95
function: handle_options
97
Sort options; put options first, until special end of options (--), or
98
until end of argv. Parse options; check that the given option matches with
99
one of the options in struct 'option', return error in case of ambiguous
100
or unknown option. Check that option was given an argument if it requires
101
one. Call function 'get_one_option()' once for each option.
104
static getopt_get_addr_func getopt_get_addr;
106
int handle_options(int *argc, char ***argv,
107
const struct option *longopts,
108
my_get_one_option get_one_option)
110
uint32_t opt_found, argvpos= 0, length;
111
bool end_of_options= 0, must_be_var, set_maximum_value=false,
113
char **pos, **pos_end, *optend, *prev_found=NULL,
114
*opt_str, key_name[FN_REFLEN];
115
const struct option *optp;
119
/* handle_options() assumes arg0 (program name) always exists */
120
assert(argc && *argc >= 1);
121
assert(argv && *argv);
122
(*argc)--; /* Skip the program name */
123
(*argv)++; /* --- || ---- */
124
init_variables(longopts, init_one_value);
126
for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++)
130
if (cur_arg[0] == '-' && cur_arg[1] && !end_of_options) /* must be opt */
134
set_maximum_value= 0;
137
cur_arg++; /* skip '-' */
138
if (*cur_arg == '-' || *cur_arg == 'O') /* check for long option, */
139
{ /* --set-variable, or -O */
144
if (!(*++cur_arg)) /* If not -Ovar=# */
146
/* the argument must be in next argv */
149
my_getopt_error_reporter(ERROR_LEVEL,
150
"%s: Option '-O' requires an argument",
151
internal::my_progname);
152
return EXIT_ARGUMENT_REQUIRED;
158
else if (!getopt_compare_strings(cur_arg, "-set-variable", 13))
161
if (cur_arg[13] == '=')
166
my_getopt_error_reporter(ERROR_LEVEL,
167
"%s: Option '--set-variable' requires an argument",
168
internal::my_progname);
169
return EXIT_ARGUMENT_REQUIRED;
172
else if (cur_arg[14]) /* garbage, or another option. break out */
176
/* the argument must be in next argv */
179
my_getopt_error_reporter(ERROR_LEVEL,
180
"%s: Option '--set-variable' requires an argument",
181
internal::my_progname);
182
return EXIT_ARGUMENT_REQUIRED;
188
else if (!must_be_var)
190
if (!*++cur_arg) /* skip the double dash */
192
/* '--' means end of options, look no further */
198
opt_str= check_struct_option(cur_arg, key_name);
199
optend= strchr(opt_str, '=');
202
length= (uint32_t) (optend - opt_str);
207
length= static_cast<uint32_t>(strlen(opt_str));
212
Find first the right option. Return error in case of an ambiguous,
216
if (!(opt_found= findopt(opt_str, length, &optp, &prev_found)))
219
Didn't find any matching option. Let's see if someone called
220
option with a special option prefix
225
must_be_var= 1; /* option is followed by an argument */
226
for (i= 0; special_opt_prefix[i]; i++)
228
if (!getopt_compare_strings(special_opt_prefix[i], opt_str,
229
special_opt_prefix_lengths[i]) &&
230
(opt_str[special_opt_prefix_lengths[i]] == '-' ||
231
opt_str[special_opt_prefix_lengths[i]] == '_'))
234
We were called with a special prefix, we can reuse opt_found
236
opt_str+= special_opt_prefix_lengths[i] + 1;
237
length-= special_opt_prefix_lengths[i] + 1;
240
if ((opt_found= findopt(opt_str, length, &optp, &prev_found)))
244
my_getopt_error_reporter(ERROR_LEVEL,
245
"%s: ambiguous option '--%s-%s' (--%s-%s)",
246
internal::my_progname,
247
special_opt_prefix[i],
248
cur_arg, special_opt_prefix[i],
250
return EXIT_AMBIGUOUS_OPTION;
254
case OPT_DISABLE: /* fall through */
256
double negation is actually enable again,
257
for example: --skip-option=0 -> option = true
259
optend= (optend && *optend == '0' && !(*(optend + 1))) ?
260
(char*) "1" : disabled_my_option;
263
optend= (optend && *optend == '0' && !(*(optend + 1))) ?
264
disabled_my_option : (char*) "1";
267
set_maximum_value= true;
271
break; /* break from the inner loop, main loop continues */
273
i= -1; /* restart the loop */
279
if (my_getopt_skip_unknown)
282
preserve all the components of this unknown option, this may
283
occurr when the user provides options like: "-O foo" or
284
"--set-variable foo" (note that theres a space in there)
285
Generally, these kind of options are to be avoided
288
(*argv)[argvpos++]= *first++;
289
} while (first <= pos);
294
my_getopt_error_reporter(option_is_loose ?
295
WARNING_LEVEL : ERROR_LEVEL,
296
"%s: unknown variable '%s'",
297
internal::my_progname, cur_arg);
298
if (!option_is_loose)
299
return EXIT_UNKNOWN_VARIABLE;
303
my_getopt_error_reporter(option_is_loose ?
304
WARNING_LEVEL : ERROR_LEVEL,
305
"%s: unknown option '--%s'",
306
internal::my_progname, cur_arg);
307
if (!option_is_loose)
308
return EXIT_UNKNOWN_OPTION;
321
my_getopt_error_reporter(ERROR_LEVEL,
322
"%s: variable prefix '%s' is not unique",
323
internal::my_progname, opt_str);
324
return EXIT_VAR_PREFIX_NOT_UNIQUE;
328
my_getopt_error_reporter(ERROR_LEVEL,
329
"%s: ambiguous option '--%s' (%s, %s)",
330
internal::my_progname, opt_str, prev_found,
332
return EXIT_AMBIGUOUS_OPTION;
335
if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
338
_("%s: %s: Option '%s' used, but is disabled\n"),
339
internal::my_progname,
340
option_is_loose ? _("WARNING") : _("ERROR"), opt_str);
346
return EXIT_OPTION_DISABLED;
348
if (must_be_var && (optp->var_type & GET_TYPE_MASK) == GET_NO_ARG)
350
my_getopt_error_reporter(ERROR_LEVEL,
351
"%s: option '%s' cannot take an argument",
352
internal::my_progname, optp->name);
353
return EXIT_NO_ARGUMENT_ALLOWED;
355
value= optp->var_type & GET_ASK_ADDR ?
356
(*getopt_get_addr)(key_name, (uint32_t) strlen(key_name), optp) : optp->value;
358
if (optp->arg_type == NO_ARG)
360
if (optend && (optp->var_type & GET_TYPE_MASK) != GET_BOOL)
362
my_getopt_error_reporter(ERROR_LEVEL,
363
"%s: option '--%s' cannot take an argument",
364
internal::my_progname, optp->name);
365
return EXIT_NO_ARGUMENT_ALLOWED;
367
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL)
370
Set bool to 1 if no argument or if the user has used
371
--enable-'option-name'.
372
*optend was set to '0' if one used --disable-option
375
if (!optend || *optend == '1' ||
376
!my_strcasecmp(&my_charset_utf8_general_ci, optend, "true"))
377
*((bool*) value)= (bool) 1;
378
else if (*optend == '0' ||
379
!my_strcasecmp(&my_charset_utf8_general_ci, optend, "false"))
380
*((bool*) value)= (bool) 0;
383
my_getopt_error_reporter(WARNING_LEVEL,
384
"%s: ignoring option '--%s' due to "
385
"invalid value '%s'",
386
internal::my_progname,
390
error= get_one_option(optp->id, optp, *((bool*) value) ?
391
(char*) "1" : disabled_my_option);
399
else if (optp->arg_type == OPT_ARG &&
400
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
402
if (optend == disabled_my_option)
403
*((bool*) value)= (bool) 0;
406
if (!optend) /* No argument -> enable option */
407
*((bool*) value)= (bool) 1;
412
else if (optp->arg_type == REQUIRED_ARG && !optend)
414
/* Check if there are more arguments after this one */
417
my_getopt_error_reporter(ERROR_LEVEL,
418
"%s: option '--%s' requires an argument",
419
internal::my_progname, optp->name);
420
return EXIT_ARGUMENT_REQUIRED;
428
else /* must be short option */
430
for (optend= cur_arg; *optend; optend++)
433
for (optp= longopts; optp->id; optp++)
435
if (optp->id == (int) (unsigned char) *optend)
437
/* Option recognized. Find next what to do with it */
439
if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
442
_("%s: ERROR: Option '-%c' used, but is disabled\n"),
443
internal::my_progname, optp->id);
444
return EXIT_OPTION_DISABLED;
446
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL &&
447
optp->arg_type == NO_ARG)
449
*((bool*) optp->value)= (bool) 1;
450
error= get_one_option(optp->id, optp, argument);
457
else if (optp->arg_type == REQUIRED_ARG ||
458
optp->arg_type == OPT_ARG)
462
/* The rest of the option is option argument */
463
argument= optend + 1;
464
/* This is in effect a jump out of the outer loop */
469
if (optp->arg_type == OPT_ARG)
471
if (optp->var_type == GET_BOOL)
472
*((bool*) optp->value)= (bool) 1;
473
error= get_one_option(optp->id, optp, argument);
479
/* Check if there are more arguments after this one */
482
my_getopt_error_reporter(ERROR_LEVEL,
483
"%s: option '-%c' requires "
485
internal::my_progname, optp->id);
486
return EXIT_ARGUMENT_REQUIRED;
490
/* the other loop will break, because *optend + 1 == 0 */
493
if ((error= setval(optp, optp->value, argument,
496
my_getopt_error_reporter(ERROR_LEVEL,
497
"%s: Error while setting value '%s' "
499
internal::my_progname,
500
argument, optp->name);
503
error= get_one_option(optp->id, optp, argument);
512
my_getopt_error_reporter(ERROR_LEVEL,
513
"%s: unknown option '-%c'",
514
internal::my_progname, *optend);
515
return EXIT_UNKNOWN_OPTION;
518
(*argc)--; /* option handled (short), decrease argument count */
521
if ((error= setval(optp, value, argument, set_maximum_value)))
523
my_getopt_error_reporter(ERROR_LEVEL,
524
"%s: Error while setting value '%s' to '%s'",
525
internal::my_progname, argument, optp->name);
528
error= get_one_option(optp->id, optp, argument);
532
(*argc)--; /* option handled (short or long), decrease argument count */
534
else /* non-option found */
535
(*argv)[argvpos++]= cur_arg;
538
Destroy the first, already handled option, so that programs that look
539
for arguments in 'argv', without checking 'argc', know when to stop.
540
Items in argv, before the destroyed one, are all non-option -arguments
541
to the program, yet to be (possibly) handled.
549
function: check_struct_option
551
Arguments: Current argument under processing from argv and a variable
552
where to store the possible key name.
554
Return value: In case option is a struct option, returns a pointer to
555
the current argument at the position where the struct option (key_name)
556
ends, the next character after the dot. In case argument is not a struct
557
option, returns a pointer to the argument.
559
key_name will hold the name of the key, or 0 if not found.
562
static char *check_struct_option(char *cur_arg, char *key_name)
566
ptr= NULL; //Options with '.' are now supported.
567
end= strrchr(cur_arg, '=');
570
If the first dot is after an equal sign, then it is part
571
of a variable value and the option is not a struct option.
572
Also, if the last character in the string before the ending
573
NULL, or the character right before equal sign is the first
574
dot found, the option is not a struct option.
576
if ((ptr != NULL) && (end != NULL) && (end - ptr > 1))
578
uint32_t len= (uint32_t) (ptr - cur_arg);
579
set_if_smaller(len, (uint32_t)FN_REFLEN-1);
580
strncpy(key_name, cur_arg, len);
590
Arguments: opts, argument
591
Will set the option value to given value
594
static int setval(const struct option *opts, char **value, char *argument,
595
bool set_maximum_value)
599
if (value && argument)
601
char* *result_pos= ((set_maximum_value) ?
602
opts->u_max_value : value);
605
return EXIT_NO_PTR_TO_VARIABLE;
607
switch ((opts->var_type & GET_TYPE_MASK)) {
608
case GET_BOOL: /* If argument differs from 0, enable option, else disable */
609
*((bool*) result_pos)= (bool) atoi(argument) != 0;
612
*((int32_t*) result_pos)= (int) getopt_ll(argument, opts, &err);
616
*((uint32_t*) result_pos)= (uint32_t) getopt_ull(argument, opts, &err);
618
case GET_ULONG_IS_FAIL:
619
*((ulong*) result_pos)= (ulong) getopt_ull(argument, opts, &err);
622
*((long*) result_pos)= (long) getopt_ll(argument, opts, &err);
625
*((int64_t*) result_pos)= getopt_ll(argument, opts, &err);
629
*((uint64_t*) result_pos)= getopt_ull(argument, opts, &err);
632
*((size_t*) result_pos)= getopt_size(argument, opts, &err);
635
*((double*) result_pos)= getopt_double(argument, opts, &err);
638
*((char**) result_pos)= argument;
641
if ((*((char**) result_pos)))
642
free((*(char**) result_pos));
643
if (!(*((char**) result_pos)= strdup(argument)))
644
return EXIT_OUT_OF_MEMORY;
647
if (((*(int*)result_pos)= opts->typelib->find_type(argument, 2) - 1) < 0)
648
return EXIT_ARGUMENT_INVALID;
651
*((uint64_t*)result_pos)= opts->typelib->find_typeset(argument, &err);
653
return EXIT_ARGUMENT_INVALID;
655
default: /* dummy default to avoid compiler warnings */
659
return EXIT_UNKNOWN_SUFFIX;
670
optpat Prefix of option to find (with - or _)
671
length Length of optpat
673
ffname Place for pointer to first found name
676
Go through all options in the option struct. Return number
677
of options found that match the pattern and in the argument
678
list the option found, if any. In case of ambiguous option, store
679
the name in ffname argument
682
0 No matching options
683
# Number of matching options
684
ffname points to first matching option
687
static int findopt(char *optpat, uint32_t length,
688
const struct option **opt_res,
692
struct option *opt= (struct option *) *opt_res;
694
for (count= 0; opt->name; opt++)
696
if (!getopt_compare_strings(opt->name, optpat, length)) /* match found */
699
if (!opt->name[length]) /* Exact match */
704
*ffname= (char *) opt->name; /* We only need to know one prev */
706
else if (strcmp(*ffname, opt->name))
709
The above test is to not count same option twice
710
(see mysql.cc, option "help")
721
53
function: compare_strings
723
55
Works like strncmp, other than 1.) considers '-' and '_' the same.
724
56
2.) Returns -1 if strings differ, 0 if they are equal
727
bool getopt_compare_strings(register const char *s, register const char *t,
59
bool getopt_compare_strings(const char *s, const char *t,
730
62
char const *end= s + length;
862
static uint64_t getopt_ull(char *arg, const struct option *optp, int *err)
864
uint64_t num= eval_num_suffix(arg, err, (char*) optp->name);
865
return getopt_ull_limit_value(num, optp, NULL);
869
static size_t getopt_size(char *arg, const struct option *optp, int *err)
871
return (size_t)getopt_ull(arg, optp, err);
876
uint64_t getopt_ull_limit_value(uint64_t num, const struct option *optp,
137
uint64_t getopt_ull_limit_value(uint64_t num, const option& optp, bool *fix)
879
139
bool adjusted= false;
880
140
uint64_t old= num;
881
141
char buf1[255], buf2[255];
883
if ((uint64_t) num > (uint64_t) optp->max_value &&
884
optp->max_value) /* if max value is not set -> no upper limit */
143
if ((uint64_t) num > (uint64_t) optp.max_value &&
144
optp.max_value) /* if max value is not set -> no upper limit */
886
num= (uint64_t) optp->max_value;
146
num= (uint64_t) optp.max_value;
890
switch ((optp->var_type & GET_TYPE_MASK)) {
150
switch (optp.var_type & GET_TYPE_MASK)
892
if (num > (uint64_t) UINT_MAX)
894
num= ((uint64_t) UINT_MAX);
899
160
case GET_ULONG_IS_FAIL:
900
if (num > (uint64_t) UINT32_MAX)
161
if (num > UINT32_MAX)
902
num= ((uint64_t) UINT32_MAX);
907
if (num > (uint64_t) SIZE_MAX)
909
num= ((uint64_t) SIZE_MAX);
914
assert(((optp->var_type & GET_TYPE_MASK) == GET_ULL)
915
|| ((optp->var_type & GET_TYPE_MASK) == GET_UINT64));
919
if (optp->block_size > 1)
921
num/= (uint64_t) optp->block_size;
922
num*= (uint64_t) optp->block_size;
925
if (num < (uint64_t) optp->min_value)
927
num= (uint64_t) optp->min_value;
175
assert((optp.var_type & GET_TYPE_MASK) == GET_ULL || (optp.var_type & GET_TYPE_MASK) == GET_UINT64);
178
if (optp.block_size > 1)
180
num/= optp.block_size;
181
num*= optp.block_size;
184
if (num < (uint64_t) optp.min_value)
186
num= (uint64_t) optp.min_value;
933
192
else if (adjusted)
934
my_getopt_error_reporter(WARNING_LEVEL,
935
"option '%s': unsigned value %s adjusted to %s",
936
optp->name, internal::ullstr(old, buf1), internal::ullstr(num, buf2));
193
default_reporter(WARNING_LEVEL, "option '%s': unsigned value %s adjusted to %s",
194
optp.name, internal::ullstr(old, buf1), internal::ullstr(num, buf2));
943
Get double value withing ranges
945
Evaluates and returns the value that user gave as an argument to a variable.
950
In case of an error, prints an error message and sets *err to
951
EXIT_ARGUMENT_INVALID. Otherwise err is not touched
954
static double getopt_double(char *arg, const struct option *optp, int *err)
958
char *end= arg + 1000; /* Big enough as *arg is \0 terminated */
959
num= internal::my_strtod(arg, &end, &error);
960
if (end[0] != 0 || error)
963
_("%s: ERROR: Invalid decimal value for option '%s'\n"),
964
internal::my_progname, optp->name);
965
*err= EXIT_ARGUMENT_INVALID;
968
if (optp->max_value && num > (double) optp->max_value)
969
num= (double) optp->max_value;
970
return max(num, (double) optp->min_value);
974
Init one value to it's default values
978
option Option to initialize
979
value Pointer to variable
982
static void init_one_value(const struct option *option, char** variable,
985
switch ((option->var_type & GET_TYPE_MASK)) {
987
*((bool*) variable)= (bool) value;
990
*((int*) variable)= (int) value;
994
*((uint*) variable)= (uint32_t) value;
997
*((long*) variable)= (long) value;
1000
*((uint32_t*) variable)= (uint32_t) value;
1002
case GET_ULONG_IS_FAIL:
1003
*((ulong*) variable)= (ulong) value;
1006
*((int64_t*) variable)= (int64_t) value;
1009
*((size_t*) variable)= (size_t) value;
1014
*((uint64_t*) variable)= (uint64_t) value;
1017
*((double*) variable)= (double) value;
1021
Do not clear variable value if it has no default value.
1022
The default value may already be set.
1023
NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
1024
so that the value has the same size as a pointer.
1026
if ((char*) (intptr_t) value)
1027
*((char**) variable)= (char*) (intptr_t) value;
1031
Do not clear variable value if it has no default value.
1032
The default value may already be set.
1033
NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
1034
so that the value has the same size as a pointer.
1036
if ((char*) (intptr_t) value)
1038
free((*(char**) variable));
1039
char *tmpptr= strdup((char *) (intptr_t) value);
1041
*((char**) variable)= tmpptr;
1044
default: /* dummy default to avoid compiler warnings */
1052
Init one value to it's default values
1056
option Option to initialize
1057
value Pointer to variable
1060
static void fini_one_value(const struct option *option, char **variable,
1063
switch ((option->var_type & GET_TYPE_MASK)) {
1065
free((*(char**) variable));
1066
*((char**) variable)= NULL;
1068
default: /* dummy default to avoid compiler warnings */
1075
void my_cleanup_options(const struct option *options)
1077
init_variables(options, fini_one_value);
1082
initialize all variables to their default values
1086
options Array of options
1089
We will initialize the value that is pointed to by options->value.
1090
If the value is of type GET_ASK_ADDR, we will also ask for the address
1091
for a value and initialize.
1094
static void init_variables(const struct option *options,
1095
init_func_p init_one_value)
1097
for (; options->name; options++)
1101
We must set u_max_value first as for some variables
1102
options->u_max_value == options->value and in this case we want to
1103
set the value to default value.
1105
if (options->u_max_value)
1106
init_one_value(options, options->u_max_value, options->max_value);
1108
init_one_value(options, options->value, options->def_value);
1109
if (options->var_type & GET_ASK_ADDR &&
1110
(variable= (*getopt_get_addr)("", 0, options)))
1111
init_one_value(options, variable, options->def_value);
1118
201
function: my_print_options
1120
203
Print help for all options and variables.
1123
void my_print_help(const struct option *options)
206
void my_print_help(const option* options)
1125
208
uint32_t col, name_space= 22, comment_space= 57;
1126
209
const char *line_end;