diff options
Diffstat (limited to 'mysys/my_getopt.c')
-rw-r--r-- | mysys/my_getopt.c | 66 |
1 files changed, 57 insertions, 9 deletions
diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index aa470282aa4..4573d27555a 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -58,6 +58,13 @@ char *disabled_my_option= (char*) "0"; my_bool my_getopt_print_errors= 1; +/* + This is a flag that can be set in client programs. 1 means that + my_getopt will skip over options it does not know how to handle. +*/ + +my_bool my_getopt_skip_unknown= 0; + static void default_reporter(enum loglevel level, const char *format, ...) { @@ -90,18 +97,18 @@ void my_getopt_register_get_addr(gptr* (*func_addr)(const char *, uint, getopt_get_addr= func_addr; } -int handle_options(int *argc, char ***argv, +int handle_options(int *argc, char ***argv, const struct my_option *longopts, my_get_one_option get_one_option) { - uint opt_found, argvpos= 0, length, i; + uint opt_found, argvpos= 0, length; my_bool end_of_options= 0, must_be_var, set_maximum_value, option_is_loose; char **pos, **pos_end, *optend, *prev_found, *opt_str, key_name[FN_REFLEN]; const struct my_option *optp; gptr *value; - int error; + int error, i; LINT_INIT(opt_found); (*argc)--; /* Skip the program name */ @@ -110,6 +117,7 @@ int handle_options(int *argc, char ***argv, for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++) { + char **first= pos; char *cur_arg= *pos; if (cur_arg[0] == '-' && cur_arg[1] && !end_of_options) /* must be opt */ { @@ -216,12 +224,11 @@ int handle_options(int *argc, char ***argv, /* We were called with a special prefix, we can reuse opt_found */ - opt_str+= (special_opt_prefix_lengths[i] + 1); + opt_str+= special_opt_prefix_lengths[i] + 1; + length-= special_opt_prefix_lengths[i] + 1; if (i == OPT_LOOSE) option_is_loose= 1; - if ((opt_found= findopt(opt_str, length - - (special_opt_prefix_lengths[i] + 1), - &optp, &prev_found))) + if ((opt_found= findopt(opt_str, length, &optp, &prev_found))) { if (opt_found > 1) { @@ -245,7 +252,7 @@ int handle_options(int *argc, char ***argv, break; case OPT_ENABLE: optend= (optend && *optend == '0' && !(*(optend + 1))) ? - disabled_my_option : (char*) "1"; + disabled_my_option : (char*) "1"; break; case OPT_MAXIMUM: set_maximum_value= 1; @@ -254,11 +261,25 @@ int handle_options(int *argc, char ***argv, } break; /* break from the inner loop, main loop continues */ } + i= -1; /* restart the loop */ } } } if (!opt_found) { + if (my_getopt_skip_unknown) + { + /* + preserve all the components of this unknown option, this may + occurr when the user provides options like: "-O foo" or + "--set-variable foo" (note that theres a space in there) + Generally, these kind of options are to be avoided + */ + do { + (*argv)[argvpos++]= *first++; + } while (first <= pos); + continue; + } if (must_be_var) { if (my_getopt_print_errors) @@ -596,6 +617,15 @@ static int setval(const struct my_option *opts, gptr *value, char *argument, if (!(*((char**) result_pos)= my_strdup(argument, MYF(MY_WME)))) return EXIT_OUT_OF_MEMORY; break; + case GET_ENUM: + if (((*(int*)result_pos)= find_type(argument, opts->typelib, 2) - 1) < 0) + return EXIT_ARGUMENT_INVALID; + break; + case GET_SET: + *((ulonglong*)result_pos)= find_typeset(argument, opts->typelib, &err); + if (err) + return EXIT_ARGUMENT_INVALID; + break; default: /* dummy default to avoid compiler warnings */ break; } @@ -788,6 +818,7 @@ static void init_one_value(const struct my_option *option, gptr *variable, *((int*) variable)= (int) value; break; case GET_UINT: + case GET_ENUM: *((uint*) variable)= (uint) value; break; case GET_LONG: @@ -800,6 +831,7 @@ static void init_one_value(const struct my_option *option, gptr *variable, *((longlong*) variable)= (longlong) value; break; case GET_ULL: + case GET_SET: *((ulonglong*) variable)= (ulonglong) value; break; default: /* dummy default to avoid compiler warnings */ @@ -928,7 +960,8 @@ void my_print_help(const struct my_option *options) void my_print_variables(const struct my_option *options) { - uint name_space= 34, length; + uint name_space= 34, length, nr; + ulonglong bit, llvalue; char buff[255]; const struct my_option *optp; @@ -946,6 +979,21 @@ void my_print_variables(const struct my_option *options) for (; length < name_space; length++) putchar(' '); switch ((optp->var_type & GET_TYPE_MASK)) { + case GET_SET: + if (!(llvalue= *(ulonglong*) value)) + printf("%s\n", "(No default value)"); + else + for (nr= 0, bit= 1; llvalue && nr < optp->typelib->count; nr++, bit<<=1) + { + if (!(bit & llvalue)) + continue; + llvalue&= ~bit; + printf( llvalue ? "%s," : "%s\n", get_type(optp->typelib, nr)); + } + break; + case GET_ENUM: + printf("%s\n", get_type(optp->typelib, *(uint*) value)); + break; case GET_STR: case GET_STR_ALLOC: /* fall through */ printf("%s\n", *((char**) value) ? *((char**) value) : |