97
function: handle_options
99
Sort options; put options first, until special end of options (--), or
100
until end of argv. Parse options; check that the given option matches with
101
one of the options in struct 'option', return error in case of ambiguous
102
or unknown option. Check that option was given an argument if it requires
103
one. Call function 'get_one_option()' once for each option.
106
static getopt_get_addr_func getopt_get_addr;
108
int handle_options(int *argc, char ***argv,
109
const struct option *longopts,
110
my_get_one_option get_one_option)
112
uint32_t opt_found, argvpos= 0, length;
113
bool end_of_options= 0, must_be_var, set_maximum_value=false,
115
char **pos, **pos_end, *optend, *prev_found=NULL,
116
*opt_str, key_name[FN_REFLEN];
117
const struct option *optp;
121
/* handle_options() assumes arg0 (program name) always exists */
122
assert(argc && *argc >= 1);
123
assert(argv && *argv);
124
(*argc)--; /* Skip the program name */
125
(*argv)++; /* --- || ---- */
126
init_variables(longopts, init_one_value);
128
for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++)
132
if (cur_arg[0] == '-' && cur_arg[1] && !end_of_options) /* must be opt */
136
set_maximum_value= 0;
139
cur_arg++; /* skip '-' */
140
if (*cur_arg == '-' || *cur_arg == 'O') /* check for long option, */
141
{ /* --set-variable, or -O */
146
if (!(*++cur_arg)) /* If not -Ovar=# */
148
/* the argument must be in next argv */
151
my_getopt_error_reporter(ERROR_LEVEL,
152
"%s: Option '-O' requires an argument",
153
internal::my_progname);
154
return EXIT_ARGUMENT_REQUIRED;
160
else if (!getopt_compare_strings(cur_arg, "-set-variable", 13))
163
if (cur_arg[13] == '=')
168
my_getopt_error_reporter(ERROR_LEVEL,
169
"%s: Option '--set-variable' requires an argument",
170
internal::my_progname);
171
return EXIT_ARGUMENT_REQUIRED;
174
else if (cur_arg[14]) /* garbage, or another option. break out */
178
/* the argument must be in next argv */
181
my_getopt_error_reporter(ERROR_LEVEL,
182
"%s: Option '--set-variable' requires an argument",
183
internal::my_progname);
184
return EXIT_ARGUMENT_REQUIRED;
190
else if (!must_be_var)
192
if (!*++cur_arg) /* skip the double dash */
194
/* '--' means end of options, look no further */
200
opt_str= check_struct_option(cur_arg, key_name);
201
optend= strchr(opt_str, '=');
204
length= (uint32_t) (optend - opt_str);
209
length= static_cast<uint32_t>(strlen(opt_str));
214
Find first the right option. Return error in case of an ambiguous,
218
if (!(opt_found= findopt(opt_str, length, &optp, &prev_found)))
221
Didn't find any matching option. Let's see if someone called
222
option with a special option prefix
227
must_be_var= 1; /* option is followed by an argument */
228
for (i= 0; special_opt_prefix[i]; i++)
230
if (!getopt_compare_strings(special_opt_prefix[i], opt_str,
231
special_opt_prefix_lengths[i]) &&
232
(opt_str[special_opt_prefix_lengths[i]] == '-' ||
233
opt_str[special_opt_prefix_lengths[i]] == '_'))
236
We were called with a special prefix, we can reuse opt_found
238
opt_str+= special_opt_prefix_lengths[i] + 1;
239
length-= special_opt_prefix_lengths[i] + 1;
242
if ((opt_found= findopt(opt_str, length, &optp, &prev_found)))
246
my_getopt_error_reporter(ERROR_LEVEL,
247
"%s: ambiguous option '--%s-%s' (--%s-%s)",
248
internal::my_progname,
249
special_opt_prefix[i],
250
cur_arg, special_opt_prefix[i],
252
return EXIT_AMBIGUOUS_OPTION;
256
case OPT_DISABLE: /* fall through */
258
double negation is actually enable again,
259
for example: --skip-option=0 -> option = true
261
optend= (optend && *optend == '0' && !(*(optend + 1))) ?
262
(char*) "1" : disabled_my_option;
265
optend= (optend && *optend == '0' && !(*(optend + 1))) ?
266
disabled_my_option : (char*) "1";
269
set_maximum_value= true;
273
break; /* break from the inner loop, main loop continues */
275
i= -1; /* restart the loop */
281
if (my_getopt_skip_unknown)
284
preserve all the components of this unknown option, this may
285
occurr when the user provides options like: "-O foo" or
286
"--set-variable foo" (note that theres a space in there)
287
Generally, these kind of options are to be avoided
290
(*argv)[argvpos++]= *first++;
291
} while (first <= pos);
296
my_getopt_error_reporter(option_is_loose ?
297
WARNING_LEVEL : ERROR_LEVEL,
298
"%s: unknown variable '%s'",
299
internal::my_progname, cur_arg);
300
if (!option_is_loose)
301
return EXIT_UNKNOWN_VARIABLE;
305
my_getopt_error_reporter(option_is_loose ?
306
WARNING_LEVEL : ERROR_LEVEL,
307
"%s: unknown option '--%s'",
308
internal::my_progname, cur_arg);
309
if (!option_is_loose)
310
return EXIT_UNKNOWN_OPTION;
323
my_getopt_error_reporter(ERROR_LEVEL,
324
"%s: variable prefix '%s' is not unique",
325
internal::my_progname, opt_str);
326
return EXIT_VAR_PREFIX_NOT_UNIQUE;
330
my_getopt_error_reporter(ERROR_LEVEL,
331
"%s: ambiguous option '--%s' (%s, %s)",
332
internal::my_progname, opt_str, prev_found,
334
return EXIT_AMBIGUOUS_OPTION;
337
if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
340
_("%s: %s: Option '%s' used, but is disabled\n"),
341
internal::my_progname,
342
option_is_loose ? _("WARNING") : _("ERROR"), opt_str);
348
return EXIT_OPTION_DISABLED;
350
if (must_be_var && (optp->var_type & GET_TYPE_MASK) == GET_NO_ARG)
352
my_getopt_error_reporter(ERROR_LEVEL,
353
"%s: option '%s' cannot take an argument",
354
internal::my_progname, optp->name);
355
return EXIT_NO_ARGUMENT_ALLOWED;
357
value= optp->var_type & GET_ASK_ADDR ?
358
(*getopt_get_addr)(key_name, (uint32_t) strlen(key_name), optp) : optp->value;
360
if (optp->arg_type == NO_ARG)
362
if (optend && (optp->var_type & GET_TYPE_MASK) != GET_BOOL)
364
my_getopt_error_reporter(ERROR_LEVEL,
365
"%s: option '--%s' cannot take an argument",
366
internal::my_progname, optp->name);
367
return EXIT_NO_ARGUMENT_ALLOWED;
369
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL)
372
Set bool to 1 if no argument or if the user has used
373
--enable-'option-name'.
374
*optend was set to '0' if one used --disable-option
377
if (!optend || *optend == '1' ||
378
!my_strcasecmp(&my_charset_utf8_general_ci, optend, "true"))
379
*((bool*) value)= (bool) 1;
380
else if (*optend == '0' ||
381
!my_strcasecmp(&my_charset_utf8_general_ci, optend, "false"))
382
*((bool*) value)= (bool) 0;
385
my_getopt_error_reporter(WARNING_LEVEL,
386
"%s: ignoring option '--%s' due to "
387
"invalid value '%s'",
388
internal::my_progname,
392
error= get_one_option(optp->id, optp, *((bool*) value) ?
393
(char*) "1" : disabled_my_option);
401
else if (optp->arg_type == OPT_ARG &&
402
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
404
if (optend == disabled_my_option)
405
*((bool*) value)= (bool) 0;
408
if (!optend) /* No argument -> enable option */
409
*((bool*) value)= (bool) 1;
414
else if (optp->arg_type == REQUIRED_ARG && !optend)
416
/* Check if there are more arguments after this one */
419
my_getopt_error_reporter(ERROR_LEVEL,
420
"%s: option '--%s' requires an argument",
421
internal::my_progname, optp->name);
422
return EXIT_ARGUMENT_REQUIRED;
430
else /* must be short option */
432
for (optend= cur_arg; *optend; optend++)
435
for (optp= longopts; optp->id; optp++)
437
if (optp->id == (int) (unsigned char) *optend)
439
/* Option recognized. Find next what to do with it */
441
if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
444
_("%s: ERROR: Option '-%c' used, but is disabled\n"),
445
internal::my_progname, optp->id);
446
return EXIT_OPTION_DISABLED;
448
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL &&
449
optp->arg_type == NO_ARG)
451
*((bool*) optp->value)= (bool) 1;
452
error= get_one_option(optp->id, optp, argument);
459
else if (optp->arg_type == REQUIRED_ARG ||
460
optp->arg_type == OPT_ARG)
464
/* The rest of the option is option argument */
465
argument= optend + 1;
466
/* This is in effect a jump out of the outer loop */
471
if (optp->arg_type == OPT_ARG)
473
if (optp->var_type == GET_BOOL)
474
*((bool*) optp->value)= (bool) 1;
475
error= get_one_option(optp->id, optp, argument);
481
/* Check if there are more arguments after this one */
484
my_getopt_error_reporter(ERROR_LEVEL,
485
"%s: option '-%c' requires "
487
internal::my_progname, optp->id);
488
return EXIT_ARGUMENT_REQUIRED;
492
/* the other loop will break, because *optend + 1 == 0 */
495
if ((error= setval(optp, optp->value, argument,
498
my_getopt_error_reporter(ERROR_LEVEL,
499
"%s: Error while setting value '%s' "
501
internal::my_progname,
502
argument, optp->name);
505
error= get_one_option(optp->id, optp, argument);
514
my_getopt_error_reporter(ERROR_LEVEL,
515
"%s: unknown option '-%c'",
516
internal::my_progname, *optend);
517
return EXIT_UNKNOWN_OPTION;
520
(*argc)--; /* option handled (short), decrease argument count */
523
if ((error= setval(optp, value, argument, set_maximum_value)))
525
my_getopt_error_reporter(ERROR_LEVEL,
526
"%s: Error while setting value '%s' to '%s'",
527
internal::my_progname, argument, optp->name);
530
error= get_one_option(optp->id, optp, argument);
534
(*argc)--; /* option handled (short or long), decrease argument count */
536
else /* non-option found */
537
(*argv)[argvpos++]= cur_arg;
540
Destroy the first, already handled option, so that programs that look
541
for arguments in 'argv', without checking 'argc', know when to stop.
542
Items in argv, before the destroyed one, are all non-option -arguments
543
to the program, yet to be (possibly) handled.
551
function: check_struct_option
553
Arguments: Current argument under processing from argv and a variable
554
where to store the possible key name.
556
Return value: In case option is a struct option, returns a pointer to
557
the current argument at the position where the struct option (key_name)
558
ends, the next character after the dot. In case argument is not a struct
559
option, returns a pointer to the argument.
561
key_name will hold the name of the key, or 0 if not found.
564
static char *check_struct_option(char *cur_arg, char *key_name)
568
ptr= NULL; //Options with '.' are now supported.
569
end= strrchr(cur_arg, '=');
572
If the first dot is after an equal sign, then it is part
573
of a variable value and the option is not a struct option.
574
Also, if the last character in the string before the ending
575
NULL, or the character right before equal sign is the first
576
dot found, the option is not a struct option.
578
if ((ptr != NULL) && (end != NULL) && (end - ptr > 1))
580
uint32_t len= (uint32_t) (ptr - cur_arg);
581
set_if_smaller(len, (uint32_t)FN_REFLEN-1);
582
strncpy(key_name, cur_arg, len);
592
Arguments: opts, argument
593
Will set the option value to given value
596
static int setval(const struct option *opts, char **value, char *argument,
597
bool set_maximum_value)
601
if (value && argument)
603
char* *result_pos= ((set_maximum_value) ?
604
opts->u_max_value : value);
607
return EXIT_NO_PTR_TO_VARIABLE;
609
switch ((opts->var_type & GET_TYPE_MASK)) {
610
case GET_BOOL: /* If argument differs from 0, enable option, else disable */
611
*((bool*) result_pos)= (bool) atoi(argument) != 0;
614
*((int32_t*) result_pos)= (int) getopt_ll(argument, opts, &err);
618
*((uint32_t*) result_pos)= (uint32_t) getopt_ull(argument, opts, &err);
620
case GET_ULONG_IS_FAIL:
621
*((ulong*) result_pos)= (ulong) getopt_ull(argument, opts, &err);
624
*((long*) result_pos)= (long) getopt_ll(argument, opts, &err);
627
*((int64_t*) result_pos)= getopt_ll(argument, opts, &err);
631
*((uint64_t*) result_pos)= getopt_ull(argument, opts, &err);
634
*((size_t*) result_pos)= getopt_size(argument, opts, &err);
637
*((double*) result_pos)= getopt_double(argument, opts, &err);
640
*((char**) result_pos)= argument;
643
if ((*((char**) result_pos)))
644
free((*(char**) result_pos));
645
if (!(*((char**) result_pos)= strdup(argument)))
646
return EXIT_OUT_OF_MEMORY;
649
if (((*(int*)result_pos)= opts->typelib->find_type(argument, 2) - 1) < 0)
650
return EXIT_ARGUMENT_INVALID;
653
*((uint64_t*)result_pos)= opts->typelib->find_typeset(argument, &err);
655
return EXIT_ARGUMENT_INVALID;
657
default: /* dummy default to avoid compiler warnings */
661
return EXIT_UNKNOWN_SUFFIX;
672
optpat Prefix of option to find (with - or _)
673
length Length of optpat
675
ffname Place for pointer to first found name
678
Go through all options in the option struct. Return number
679
of options found that match the pattern and in the argument
680
list the option found, if any. In case of ambiguous option, store
681
the name in ffname argument
684
0 No matching options
685
# Number of matching options
686
ffname points to first matching option
689
static int findopt(char *optpat, uint32_t length,
690
const struct option **opt_res,
694
struct option *opt= (struct option *) *opt_res;
696
for (count= 0; opt->name; opt++)
698
if (!getopt_compare_strings(opt->name, optpat, length)) /* match found */
701
if (!opt->name[length]) /* Exact match */
706
*ffname= (char *) opt->name; /* We only need to know one prev */
708
else if (strcmp(*ffname, opt->name))
711
The above test is to not count same option twice
712
(see mysql.cc, option "help")
723
77
function: compare_strings
725
79
Works like strncmp, other than 1.) considers '-' and '_' the same.
945
Get double value withing ranges
947
Evaluates and returns the value that user gave as an argument to a variable.
952
In case of an error, prints an error message and sets *err to
953
EXIT_ARGUMENT_INVALID. Otherwise err is not touched
956
static double getopt_double(char *arg, const struct option *optp, int *err)
960
char *end= arg + 1000; /* Big enough as *arg is \0 terminated */
961
num= internal::my_strtod(arg, &end, &error);
962
if (end[0] != 0 || error)
965
_("%s: ERROR: Invalid decimal value for option '%s'\n"),
966
internal::my_progname, optp->name);
967
*err= EXIT_ARGUMENT_INVALID;
970
if (optp->max_value && num > (double) optp->max_value)
971
num= (double) optp->max_value;
972
return max(num, (double) optp->min_value);
976
Init one value to it's default values
980
option Option to initialize
981
value Pointer to variable
984
static void init_one_value(const struct option *option, char** variable,
987
switch ((option->var_type & GET_TYPE_MASK)) {
989
*((bool*) variable)= (bool) value;
992
*((int*) variable)= (int) value;
996
*((uint*) variable)= (uint32_t) value;
999
*((long*) variable)= (long) value;
1002
*((uint32_t*) variable)= (uint32_t) value;
1004
case GET_ULONG_IS_FAIL:
1005
*((ulong*) variable)= (ulong) value;
1008
*((int64_t*) variable)= (int64_t) value;
1011
*((size_t*) variable)= (size_t) value;
1016
*((uint64_t*) variable)= (uint64_t) value;
1019
*((double*) variable)= (double) value;
1023
Do not clear variable value if it has no default value.
1024
The default value may already be set.
1025
NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
1026
so that the value has the same size as a pointer.
1028
if ((char*) (intptr_t) value)
1029
*((char**) variable)= (char*) (intptr_t) value;
1033
Do not clear variable value if it has no default value.
1034
The default value may already be set.
1035
NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
1036
so that the value has the same size as a pointer.
1038
if ((char*) (intptr_t) value)
1040
free((*(char**) variable));
1041
char *tmpptr= strdup((char *) (intptr_t) value);
1043
*((char**) variable)= tmpptr;
1046
default: /* dummy default to avoid compiler warnings */
1054
Init one value to it's default values
1058
option Option to initialize
1059
value Pointer to variable
1062
static void fini_one_value(const struct option *option, char **variable,
1065
switch ((option->var_type & GET_TYPE_MASK)) {
1067
free((*(char**) variable));
1068
*((char**) variable)= NULL;
1070
default: /* dummy default to avoid compiler warnings */
1077
void my_cleanup_options(const struct option *options)
1079
init_variables(options, fini_one_value);
1084
initialize all variables to their default values
1088
options Array of options
1091
We will initialize the value that is pointed to by options->value.
1092
If the value is of type GET_ASK_ADDR, we will also ask for the address
1093
for a value and initialize.
1096
static void init_variables(const struct option *options,
1097
init_func_p init_one_value)
1099
for (; options->name; options++)
1103
We must set u_max_value first as for some variables
1104
options->u_max_value == options->value and in this case we want to
1105
set the value to default value.
1107
if (options->u_max_value)
1108
init_one_value(options, options->u_max_value, options->max_value);
1110
init_one_value(options, options->value, options->def_value);
1111
if (options->var_type & GET_ASK_ADDR &&
1112
(variable= (*getopt_get_addr)("", 0, options)))
1113
init_one_value(options, variable, options->def_value);
1120
229
function: my_print_options