35
typedef void (*init_func_p)(const struct my_option *option, char **variable,
38
void default_reporter(enum loglevel level, const char *format, ...);
39
my_error_reporter my_getopt_error_reporter= &default_reporter;
41
static int findopt(char *optpat, uint32_t length,
42
const struct my_option **opt_res,
44
static int64_t getopt_ll(char *arg, const struct my_option *optp, int *err);
45
static uint64_t getopt_ull(char *arg, const struct my_option *optp,
47
static size_t getopt_size(char *arg, const struct my_option *optp, int *err);
48
static double getopt_double(char *arg, const struct my_option *optp, int *err);
49
static void init_variables(const struct my_option *options,
50
init_func_p init_one_value);
51
static void init_one_value(const struct my_option *option, char **variable,
53
static void fini_one_value(const struct my_option *option, char **variable,
55
static int setval(const struct my_option *opts, char* *value, char *argument,
56
bool set_maximum_value);
57
static char *check_struct_option(char *cur_arg, char *key_name);
60
The following three variables belong to same group and the number and
61
order of their arguments must correspond to each other.
63
static const char *special_opt_prefix[]=
64
{"skip", "disable", "enable", "maximum", "loose", 0};
65
static const uint32_t special_opt_prefix_lengths[]=
68
{ OPT_SKIP, OPT_DISABLE, OPT_ENABLE, OPT_MAXIMUM, OPT_LOOSE};
70
char *disabled_my_option= (char*) "0";
73
This is a flag that can be set in client programs. 1 means that
74
my_getopt will skip over options it does not know how to handle.
77
bool my_getopt_skip_unknown= 0;
79
void default_reporter(enum loglevel level, const char *format, ...)
82
va_start(args, format);
83
if (level == WARNING_LEVEL)
84
fprintf(stderr, "%s", _("Warning: "));
85
else if (level == INFORMATION_LEVEL)
86
fprintf(stderr, "%s", _("Info: "));
87
vfprintf(stderr, format, args);
94
function: handle_options
96
Sort options; put options first, until special end of options (--), or
97
until end of argv. Parse options; check that the given option matches with
98
one of the options in struct 'my_option', return error in case of ambiguous
99
or unknown option. Check that option was given an argument if it requires
100
one. Call function 'get_one_option()' once for each option.
103
static getopt_get_addr_func getopt_get_addr;
105
int handle_options(int *argc, char ***argv,
106
const struct my_option *longopts,
107
my_get_one_option get_one_option)
109
uint32_t opt_found, argvpos= 0, length;
110
bool end_of_options= 0, must_be_var, set_maximum_value=false,
112
char **pos, **pos_end, *optend, *prev_found=NULL,
113
*opt_str, key_name[FN_REFLEN];
114
const struct my_option *optp;
118
/* handle_options() assumes arg0 (program name) always exists */
119
assert(argc && *argc >= 1);
120
assert(argv && *argv);
121
(*argc)--; /* Skip the program name */
122
(*argv)++; /* --- || ---- */
123
init_variables(longopts, init_one_value);
125
for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++)
129
if (cur_arg[0] == '-' && cur_arg[1] && !end_of_options) /* must be opt */
35
typedef void (*init_func_p)(const struct my_option *option, char **variable,
38
void default_reporter(enum loglevel level, const char *format, ...);
39
my_error_reporter my_getopt_error_reporter= &default_reporter;
41
static int findopt(char *optpat, uint32_t length,
42
const struct my_option **opt_res,
44
static int64_t getopt_ll(char *arg, const struct my_option *optp, int *err);
45
static uint64_t getopt_ull(char *arg, const struct my_option *optp,
47
static size_t getopt_size(char *arg, const struct my_option *optp, int *err);
48
static double getopt_double(char *arg, const struct my_option *optp, int *err);
49
static void init_variables(const struct my_option *options,
50
init_func_p init_one_value);
51
static void init_one_value(const struct my_option *option, char **variable,
53
static void fini_one_value(const struct my_option *option, char **variable,
55
static int setval(const struct my_option *opts, char* *value, char *argument,
56
bool set_maximum_value);
57
static char *check_struct_option(char *cur_arg, char *key_name);
60
The following three variables belong to same group and the number and
61
order of their arguments must correspond to each other.
63
static const char *special_opt_prefix[]=
64
{"skip", "disable", "enable", "maximum", "loose", 0};
65
static const uint32_t special_opt_prefix_lengths[]=
68
{ OPT_SKIP, OPT_DISABLE, OPT_ENABLE, OPT_MAXIMUM, OPT_LOOSE};
70
char *disabled_my_option= (char*) "0";
73
This is a flag that can be set in client programs. 1 means that
74
my_getopt will skip over options it does not know how to handle.
77
bool my_getopt_skip_unknown= 0;
79
void default_reporter(enum loglevel level, const char *format, ...)
82
va_start(args, format);
83
if (level == WARNING_LEVEL)
84
fprintf(stderr, "%s", _("Warning: "));
85
else if (level == INFORMATION_LEVEL)
86
fprintf(stderr, "%s", _("Info: "));
87
vfprintf(stderr, format, args);
94
function: handle_options
96
Sort options; put options first, until special end of options (--), or
97
until end of argv. Parse options; check that the given option matches with
98
one of the options in struct 'my_option', return error in case of ambiguous
99
or unknown option. Check that option was given an argument if it requires
100
one. Call function 'get_one_option()' once for each option.
103
static getopt_get_addr_func getopt_get_addr;
105
int handle_options(int *argc, char ***argv,
106
const struct my_option *longopts,
107
my_get_one_option get_one_option)
109
uint32_t opt_found, argvpos= 0, length;
110
bool end_of_options= 0, must_be_var, set_maximum_value=false,
112
char **pos, **pos_end, *optend, *prev_found=NULL,
113
*opt_str, key_name[FN_REFLEN];
114
const struct my_option *optp;
118
/* handle_options() assumes arg0 (program name) always exists */
119
assert(argc && *argc >= 1);
120
assert(argv && *argv);
121
(*argc)--; /* Skip the program name */
122
(*argv)++; /* --- || ---- */
123
init_variables(longopts, init_one_value);
125
for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++)
133
set_maximum_value= 0;
136
cur_arg++; /* skip '-' */
137
if (*cur_arg == '-' || *cur_arg == 'O') /* check for long option, */
138
{ /* --set-variable, or -O */
143
if (!(*++cur_arg)) /* If not -Ovar=# */
145
/* the argument must be in next argv */
148
my_getopt_error_reporter(ERROR_LEVEL,
149
"%s: Option '-O' requires an argument",
150
internal::my_progname);
151
return EXIT_ARGUMENT_REQUIRED;
157
else if (!getopt_compare_strings(cur_arg, "-set-variable", 13))
160
if (cur_arg[13] == '=')
165
my_getopt_error_reporter(ERROR_LEVEL,
166
"%s: Option '--set-variable' requires an argument",
167
internal::my_progname);
168
return EXIT_ARGUMENT_REQUIRED;
171
else if (cur_arg[14]) /* garbage, or another option. break out */
175
/* the argument must be in next argv */
178
my_getopt_error_reporter(ERROR_LEVEL,
179
"%s: Option '--set-variable' requires an argument",
180
internal::my_progname);
181
return EXIT_ARGUMENT_REQUIRED;
187
else if (!must_be_var)
189
if (!*++cur_arg) /* skip the double dash */
191
/* '--' means end of options, look no further */
197
opt_str= check_struct_option(cur_arg, key_name);
198
optend= strrchr(opt_str, '=');
201
length= (uint32_t) (optend - opt_str);
206
length= static_cast<uint32_t>(strlen(opt_str));
211
Find first the right option. Return error in case of an ambiguous,
215
if (!(opt_found= findopt(opt_str, length, &optp, &prev_found)))
218
Didn't find any matching option. Let's see if someone called
219
option with a special option prefix
224
must_be_var= 1; /* option is followed by an argument */
225
for (i= 0; special_opt_prefix[i]; i++)
227
if (!getopt_compare_strings(special_opt_prefix[i], opt_str,
228
special_opt_prefix_lengths[i]) &&
229
(opt_str[special_opt_prefix_lengths[i]] == '-' ||
230
opt_str[special_opt_prefix_lengths[i]] == '_'))
233
We were called with a special prefix, we can reuse opt_found
235
opt_str+= special_opt_prefix_lengths[i] + 1;
236
length-= special_opt_prefix_lengths[i] + 1;
239
if ((opt_found= findopt(opt_str, length, &optp, &prev_found)))
243
my_getopt_error_reporter(ERROR_LEVEL,
244
"%s: ambiguous option '--%s-%s' (--%s-%s)",
245
internal::my_progname,
246
special_opt_prefix[i],
247
cur_arg, special_opt_prefix[i],
249
return EXIT_AMBIGUOUS_OPTION;
253
case OPT_DISABLE: /* fall through */
255
double negation is actually enable again,
256
for example: --skip-option=0 -> option = true
258
optend= (optend && *optend == '0' && !(*(optend + 1))) ?
259
(char*) "1" : disabled_my_option;
262
optend= (optend && *optend == '0' && !(*(optend + 1))) ?
263
disabled_my_option : (char*) "1";
266
set_maximum_value= true;
270
break; /* break from the inner loop, main loop continues */
272
i= -1; /* restart the loop */
278
if (my_getopt_skip_unknown)
129
if (cur_arg[0] == '-' && cur_arg[1] && !end_of_options) /* must be opt */
133
set_maximum_value= 0;
136
cur_arg++; /* skip '-' */
137
if (*cur_arg == '-' || *cur_arg == 'O') /* check for long option, */
138
{ /* --set-variable, or -O */
143
if (!(*++cur_arg)) /* If not -Ovar=# */
145
/* the argument must be in next argv */
148
my_getopt_error_reporter(ERROR_LEVEL,
149
"%s: Option '-O' requires an argument",
150
internal::my_progname);
151
return EXIT_ARGUMENT_REQUIRED;
157
else if (!getopt_compare_strings(cur_arg, "-set-variable", 13))
160
if (cur_arg[13] == '=')
165
my_getopt_error_reporter(ERROR_LEVEL,
166
"%s: Option '--set-variable' requires an argument",
167
internal::my_progname);
168
return EXIT_ARGUMENT_REQUIRED;
171
else if (cur_arg[14]) /* garbage, or another option. break out */
175
/* the argument must be in next argv */
178
my_getopt_error_reporter(ERROR_LEVEL,
179
"%s: Option '--set-variable' requires an argument",
180
internal::my_progname);
181
return EXIT_ARGUMENT_REQUIRED;
187
else if (!must_be_var)
189
if (!*++cur_arg) /* skip the double dash */
191
/* '--' means end of options, look no further */
197
opt_str= check_struct_option(cur_arg, key_name);
198
optend= strrchr(opt_str, '=');
201
length= (uint32_t) (optend - opt_str);
206
length= static_cast<uint32_t>(strlen(opt_str));
211
Find first the right option. Return error in case of an ambiguous,
215
if (!(opt_found= findopt(opt_str, length, &optp, &prev_found)))
218
Didn't find any matching option. Let's see if someone called
219
option with a special option prefix
224
must_be_var= 1; /* option is followed by an argument */
225
for (i= 0; special_opt_prefix[i]; i++)
227
if (!getopt_compare_strings(special_opt_prefix[i], opt_str,
228
special_opt_prefix_lengths[i]) &&
229
(opt_str[special_opt_prefix_lengths[i]] == '-' ||
230
opt_str[special_opt_prefix_lengths[i]] == '_'))
233
We were called with a special prefix, we can reuse opt_found
235
opt_str+= special_opt_prefix_lengths[i] + 1;
236
length-= special_opt_prefix_lengths[i] + 1;
239
if ((opt_found= findopt(opt_str, length, &optp, &prev_found)))
243
my_getopt_error_reporter(ERROR_LEVEL,
244
"%s: ambiguous option '--%s-%s' (--%s-%s)",
245
internal::my_progname,
246
special_opt_prefix[i],
247
cur_arg, special_opt_prefix[i],
249
return EXIT_AMBIGUOUS_OPTION;
253
case OPT_DISABLE: /* fall through */
255
double negation is actually enable again,
256
for example: --skip-option=0 -> option = true
258
optend= (optend && *optend == '0' && !(*(optend + 1))) ?
259
(char*) "1" : disabled_my_option;
262
optend= (optend && *optend == '0' && !(*(optend + 1))) ?
263
disabled_my_option : (char*) "1";
266
set_maximum_value= true;
270
break; /* break from the inner loop, main loop continues */
272
i= -1; /* restart the loop */
278
if (my_getopt_skip_unknown)
281
preserve all the components of this unknown option, this may
282
occurr when the user provides options like: "-O foo" or
283
"--set-variable foo" (note that theres a space in there)
284
Generally, these kind of options are to be avoided
287
(*argv)[argvpos++]= *first++;
288
} while (first <= pos);
293
my_getopt_error_reporter(option_is_loose ?
294
WARNING_LEVEL : ERROR_LEVEL,
295
"%s: unknown variable '%s'",
296
internal::my_progname, cur_arg);
297
if (!option_is_loose)
298
return EXIT_UNKNOWN_VARIABLE;
302
my_getopt_error_reporter(option_is_loose ?
303
WARNING_LEVEL : ERROR_LEVEL,
304
"%s: unknown option '--%s'",
305
internal::my_progname, cur_arg);
306
if (!option_is_loose)
307
return EXIT_UNKNOWN_OPTION;
320
my_getopt_error_reporter(ERROR_LEVEL,
321
"%s: variable prefix '%s' is not unique",
322
internal::my_progname, opt_str);
323
return EXIT_VAR_PREFIX_NOT_UNIQUE;
327
my_getopt_error_reporter(ERROR_LEVEL,
328
"%s: ambiguous option '--%s' (%s, %s)",
329
internal::my_progname, opt_str, prev_found,
331
return EXIT_AMBIGUOUS_OPTION;
334
if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
337
_("%s: %s: Option '%s' used, but is disabled\n"),
338
internal::my_progname,
339
option_is_loose ? _("WARNING") : _("ERROR"), opt_str);
345
return EXIT_OPTION_DISABLED;
347
if (must_be_var && (optp->var_type & GET_TYPE_MASK) == GET_NO_ARG)
349
my_getopt_error_reporter(ERROR_LEVEL,
350
"%s: option '%s' cannot take an argument",
351
internal::my_progname, optp->name);
352
return EXIT_NO_ARGUMENT_ALLOWED;
354
value= optp->var_type & GET_ASK_ADDR ?
355
(*getopt_get_addr)(key_name, (uint32_t) strlen(key_name), optp) : optp->value;
357
if (optp->arg_type == NO_ARG)
359
if (optend && (optp->var_type & GET_TYPE_MASK) != GET_BOOL)
361
my_getopt_error_reporter(ERROR_LEVEL,
362
"%s: option '--%s' cannot take an argument",
363
internal::my_progname, optp->name);
364
return EXIT_NO_ARGUMENT_ALLOWED;
366
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL)
281
preserve all the components of this unknown option, this may
282
occurr when the user provides options like: "-O foo" or
283
"--set-variable foo" (note that theres a space in there)
284
Generally, these kind of options are to be avoided
287
(*argv)[argvpos++]= *first++;
288
} while (first <= pos);
293
my_getopt_error_reporter(option_is_loose ?
294
WARNING_LEVEL : ERROR_LEVEL,
295
"%s: unknown variable '%s'",
296
internal::my_progname, cur_arg);
297
if (!option_is_loose)
298
return EXIT_UNKNOWN_VARIABLE;
302
my_getopt_error_reporter(option_is_loose ?
303
WARNING_LEVEL : ERROR_LEVEL,
304
"%s: unknown option '--%s'",
305
internal::my_progname, cur_arg);
306
if (!option_is_loose)
307
return EXIT_UNKNOWN_OPTION;
320
my_getopt_error_reporter(ERROR_LEVEL,
321
"%s: variable prefix '%s' is not unique",
322
internal::my_progname, opt_str);
323
return EXIT_VAR_PREFIX_NOT_UNIQUE;
327
my_getopt_error_reporter(ERROR_LEVEL,
328
"%s: ambiguous option '--%s' (%s, %s)",
329
internal::my_progname, opt_str, prev_found,
331
return EXIT_AMBIGUOUS_OPTION;
334
if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
337
_("%s: %s: Option '%s' used, but is disabled\n"),
338
internal::my_progname,
339
option_is_loose ? _("WARNING") : _("ERROR"), opt_str);
345
return EXIT_OPTION_DISABLED;
347
if (must_be_var && (optp->var_type & GET_TYPE_MASK) == GET_NO_ARG)
369
Set bool to 1 if no argument or if the user has used
370
--enable-'option-name'.
371
*optend was set to '0' if one used --disable-option
374
if (!optend || *optend == '1' ||
375
!my_strcasecmp(&my_charset_utf8_general_ci, optend, "true"))
376
*((bool*) value)= (bool) 1;
377
else if (*optend == '0' ||
378
!my_strcasecmp(&my_charset_utf8_general_ci, optend, "false"))
379
*((bool*) value)= (bool) 0;
382
my_getopt_error_reporter(WARNING_LEVEL,
383
"%s: ignoring option '--%s' due to "
384
"invalid value '%s'",
385
internal::my_progname,
389
error= get_one_option(optp->id, optp, *((bool*) value) ?
390
(char*) "1" : disabled_my_option);
398
else if (optp->arg_type == OPT_ARG &&
399
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
401
if (optend == disabled_my_option)
402
*((bool*) value)= (bool) 0;
405
if (!optend) /* No argument -> enable option */
406
*((bool*) value)= (bool) 1;
411
else if (optp->arg_type == REQUIRED_ARG && !optend)
413
/* Check if there are more arguments after this one */
416
my_getopt_error_reporter(ERROR_LEVEL,
417
"%s: option '--%s' requires an argument",
418
internal::my_progname, optp->name);
419
return EXIT_ARGUMENT_REQUIRED;
427
else /* must be short option */
429
for (optend= cur_arg; *optend; optend++)
432
for (optp= longopts; optp->id; optp++)
434
if (optp->id == (int) (unsigned char) *optend)
436
/* Option recognized. Find next what to do with it */
438
if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
441
_("%s: ERROR: Option '-%c' used, but is disabled\n"),
442
internal::my_progname, optp->id);
443
return EXIT_OPTION_DISABLED;
445
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL &&
446
optp->arg_type == NO_ARG)
448
*((bool*) optp->value)= (bool) 1;
449
error= get_one_option(optp->id, optp, argument);
456
else if (optp->arg_type == REQUIRED_ARG ||
457
optp->arg_type == OPT_ARG)
461
/* The rest of the option is option argument */
462
argument= optend + 1;
463
/* This is in effect a jump out of the outer loop */
468
if (optp->arg_type == OPT_ARG)
470
if (optp->var_type == GET_BOOL)
471
*((bool*) optp->value)= (bool) 1;
472
error= get_one_option(optp->id, optp, argument);
478
/* Check if there are more arguments after this one */
481
my_getopt_error_reporter(ERROR_LEVEL,
482
"%s: option '-%c' requires "
484
internal::my_progname, optp->id);
485
return EXIT_ARGUMENT_REQUIRED;
489
/* the other loop will break, because *optend + 1 == 0 */
492
if ((error= setval(optp, optp->value, argument,
495
my_getopt_error_reporter(ERROR_LEVEL,
496
"%s: Error while setting value '%s' "
498
internal::my_progname,
499
argument, optp->name);
502
error= get_one_option(optp->id, optp, argument);
511
my_getopt_error_reporter(ERROR_LEVEL,
512
"%s: unknown option '-%c'",
513
internal::my_progname, *optend);
514
return EXIT_UNKNOWN_OPTION;
517
(*argc)--; /* option handled (short), decrease argument count */
520
if ((error= setval(optp, value, argument, set_maximum_value)))
349
522
my_getopt_error_reporter(ERROR_LEVEL,
350
"%s: option '%s' cannot take an argument",
351
internal::my_progname, optp->name);
352
return EXIT_NO_ARGUMENT_ALLOWED;
354
value= optp->var_type & GET_ASK_ADDR ?
355
(*getopt_get_addr)(key_name, (uint32_t) strlen(key_name), optp) : optp->value;
357
if (optp->arg_type == NO_ARG)
359
if (optend && (optp->var_type & GET_TYPE_MASK) != GET_BOOL)
361
my_getopt_error_reporter(ERROR_LEVEL,
362
"%s: option '--%s' cannot take an argument",
363
internal::my_progname, optp->name);
364
return EXIT_NO_ARGUMENT_ALLOWED;
366
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL)
369
Set bool to 1 if no argument or if the user has used
370
--enable-'option-name'.
371
*optend was set to '0' if one used --disable-option
374
if (!optend || *optend == '1' ||
375
!my_strcasecmp(&my_charset_utf8_general_ci, optend, "true"))
376
*((bool*) value)= (bool) 1;
377
else if (*optend == '0' ||
378
!my_strcasecmp(&my_charset_utf8_general_ci, optend, "false"))
379
*((bool*) value)= (bool) 0;
382
my_getopt_error_reporter(WARNING_LEVEL,
383
"%s: ignoring option '--%s' due to "
384
"invalid value '%s'",
385
internal::my_progname,
389
get_one_option(optp->id, optp,
391
(char*) "1" : disabled_my_option);
396
else if (optp->arg_type == OPT_ARG &&
397
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
399
if (optend == disabled_my_option)
400
*((bool*) value)= (bool) 0;
403
if (!optend) /* No argument -> enable option */
404
*((bool*) value)= (bool) 1;
409
else if (optp->arg_type == REQUIRED_ARG && !optend)
411
/* Check if there are more arguments after this one */
414
my_getopt_error_reporter(ERROR_LEVEL,
415
"%s: option '--%s' requires an argument",
416
internal::my_progname, optp->name);
417
return EXIT_ARGUMENT_REQUIRED;
425
else /* must be short option */
427
for (optend= cur_arg; *optend; optend++)
430
for (optp= longopts; optp->id; optp++)
432
if (optp->id == (int) (unsigned char) *optend)
434
/* Option recognized. Find next what to do with it */
436
if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
439
_("%s: ERROR: Option '-%c' used, but is disabled\n"),
440
internal::my_progname, optp->id);
441
return EXIT_OPTION_DISABLED;
443
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL &&
444
optp->arg_type == NO_ARG)
446
*((bool*) optp->value)= (bool) 1;
447
get_one_option(optp->id, optp, argument);
450
else if (optp->arg_type == REQUIRED_ARG ||
451
optp->arg_type == OPT_ARG)
455
/* The rest of the option is option argument */
456
argument= optend + 1;
457
/* This is in effect a jump out of the outer loop */
462
if (optp->arg_type == OPT_ARG)
464
if (optp->var_type == GET_BOOL)
465
*((bool*) optp->value)= (bool) 1;
466
get_one_option(optp->id, optp, argument);
469
/* Check if there are more arguments after this one */
472
my_getopt_error_reporter(ERROR_LEVEL,
473
"%s: option '-%c' requires "
475
internal::my_progname, optp->id);
476
return EXIT_ARGUMENT_REQUIRED;
480
/* the other loop will break, because *optend + 1 == 0 */
483
if ((error= setval(optp, optp->value, argument,
486
my_getopt_error_reporter(ERROR_LEVEL,
487
"%s: Error while setting value '%s' "
489
internal::my_progname,
490
argument, optp->name);
493
get_one_option(optp->id, optp, argument);
499
my_getopt_error_reporter(ERROR_LEVEL,
500
"%s: unknown option '-%c'",
501
internal::my_progname, *optend);
502
return EXIT_UNKNOWN_OPTION;
523
"%s: Error while setting value '%s' to '%s'",
524
internal::my_progname, argument, optp->name);
505
(*argc)--; /* option handled (short), decrease argument count */
508
if ((error= setval(optp, value, argument, set_maximum_value)))
510
my_getopt_error_reporter(ERROR_LEVEL,
511
"%s: Error while setting value '%s' to '%s'",
512
internal::my_progname, argument, optp->name);
515
get_one_option(optp->id, optp, argument);
517
(*argc)--; /* option handled (short or long), decrease argument count */
519
else /* non-option found */
520
(*argv)[argvpos++]= cur_arg;
523
Destroy the first, already handled option, so that programs that look
524
for arguments in 'argv', without checking 'argc', know when to stop.
525
Items in argv, before the destroyed one, are all non-option -arguments
526
to the program, yet to be (possibly) handled.
534
function: check_struct_option
536
Arguments: Current argument under processing from argv and a variable
537
where to store the possible key name.
539
Return value: In case option is a struct option, returns a pointer to
540
the current argument at the position where the struct option (key_name)
541
ends, the next character after the dot. In case argument is not a struct
542
option, returns a pointer to the argument.
544
key_name will hold the name of the key, or 0 if not found.
547
static char *check_struct_option(char *cur_arg, char *key_name)
551
ptr= strrchr(cur_arg + 1, '.'); /* Skip the first character */
552
end= strrchr(cur_arg, '=');
555
If the first dot is after an equal sign, then it is part
556
of a variable value and the option is not a struct option.
557
Also, if the last character in the string before the ending
558
NULL, or the character right before equal sign is the first
559
dot found, the option is not a struct option.
561
if ((ptr != NULL) && (end != NULL) && (end - ptr > 1))
563
uint32_t len= (uint32_t) (ptr - cur_arg);
564
set_if_smaller(len, (uint32_t)FN_REFLEN-1);
565
strncpy(key_name, cur_arg, len);
575
Arguments: opts, argument
576
Will set the option value to given value
579
static int setval(const struct my_option *opts, char **value, char *argument,
580
bool set_maximum_value)
584
if (value && argument)
586
char* *result_pos= ((set_maximum_value) ?
587
opts->u_max_value : value);
590
return EXIT_NO_PTR_TO_VARIABLE;
592
switch ((opts->var_type & GET_TYPE_MASK)) {
593
case GET_BOOL: /* If argument differs from 0, enable option, else disable */
594
*((bool*) result_pos)= (bool) atoi(argument) != 0;
597
*((int32_t*) result_pos)= (int) getopt_ll(argument, opts, &err);
601
*((uint32_t*) result_pos)= (uint32_t) getopt_ull(argument, opts, &err);
603
case GET_ULONG_IS_FAIL:
604
*((ulong*) result_pos)= (ulong) getopt_ull(argument, opts, &err);
607
*((long*) result_pos)= (long) getopt_ll(argument, opts, &err);
610
*((int64_t*) result_pos)= getopt_ll(argument, opts, &err);
614
*((uint64_t*) result_pos)= getopt_ull(argument, opts, &err);
617
*((size_t*) result_pos)= getopt_size(argument, opts, &err);
620
*((double*) result_pos)= getopt_double(argument, opts, &err);
623
*((char**) result_pos)= argument;
626
if ((*((char**) result_pos)))
627
free((*(char**) result_pos));
628
if (!(*((char**) result_pos)= strdup(argument)))
629
return EXIT_OUT_OF_MEMORY;
632
if (((*(int*)result_pos)= find_type(argument, opts->typelib, 2) - 1) < 0)
633
return EXIT_ARGUMENT_INVALID;
636
*((uint64_t*)result_pos)= find_typeset(argument, opts->typelib, &err);
527
error= get_one_option(optp->id, optp, argument);
531
(*argc)--; /* option handled (short or long), decrease argument count */
533
else /* non-option found */
534
(*argv)[argvpos++]= cur_arg;
537
Destroy the first, already handled option, so that programs that look
538
for arguments in 'argv', without checking 'argc', know when to stop.
539
Items in argv, before the destroyed one, are all non-option -arguments
540
to the program, yet to be (possibly) handled.
548
function: check_struct_option
550
Arguments: Current argument under processing from argv and a variable
551
where to store the possible key name.
553
Return value: In case option is a struct option, returns a pointer to
554
the current argument at the position where the struct option (key_name)
555
ends, the next character after the dot. In case argument is not a struct
556
option, returns a pointer to the argument.
558
key_name will hold the name of the key, or 0 if not found.
561
static char *check_struct_option(char *cur_arg, char *key_name)
565
ptr= strrchr(cur_arg + 1, '.'); /* Skip the first character */
566
end= strrchr(cur_arg, '=');
569
If the first dot is after an equal sign, then it is part
570
of a variable value and the option is not a struct option.
571
Also, if the last character in the string before the ending
572
NULL, or the character right before equal sign is the first
573
dot found, the option is not a struct option.
575
if ((ptr != NULL) && (end != NULL) && (end - ptr > 1))
577
uint32_t len= (uint32_t) (ptr - cur_arg);
578
set_if_smaller(len, (uint32_t)FN_REFLEN-1);
579
strncpy(key_name, cur_arg, len);
589
Arguments: opts, argument
590
Will set the option value to given value
593
static int setval(const struct my_option *opts, char **value, char *argument,
594
bool set_maximum_value)
598
if (value && argument)
600
char* *result_pos= ((set_maximum_value) ?
601
opts->u_max_value : value);
604
return EXIT_NO_PTR_TO_VARIABLE;
606
switch ((opts->var_type & GET_TYPE_MASK)) {
607
case GET_BOOL: /* If argument differs from 0, enable option, else disable */
608
*((bool*) result_pos)= (bool) atoi(argument) != 0;
611
*((int32_t*) result_pos)= (int) getopt_ll(argument, opts, &err);
615
*((uint32_t*) result_pos)= (uint32_t) getopt_ull(argument, opts, &err);
617
case GET_ULONG_IS_FAIL:
618
*((ulong*) result_pos)= (ulong) getopt_ull(argument, opts, &err);
621
*((long*) result_pos)= (long) getopt_ll(argument, opts, &err);
624
*((int64_t*) result_pos)= getopt_ll(argument, opts, &err);
628
*((uint64_t*) result_pos)= getopt_ull(argument, opts, &err);
631
*((size_t*) result_pos)= getopt_size(argument, opts, &err);
634
*((double*) result_pos)= getopt_double(argument, opts, &err);
637
*((char**) result_pos)= argument;
640
if ((*((char**) result_pos)))
641
free((*(char**) result_pos));
642
if (!(*((char**) result_pos)= strdup(argument)))
643
return EXIT_OUT_OF_MEMORY;
646
if (((*(int*)result_pos)= find_type(argument, opts->typelib, 2) - 1) < 0)
647
return EXIT_ARGUMENT_INVALID;
650
*((uint64_t*)result_pos)= find_typeset(argument, opts->typelib, &err);
652
return EXIT_ARGUMENT_INVALID;
654
default: /* dummy default to avoid compiler warnings */
638
return EXIT_ARGUMENT_INVALID;
640
default: /* dummy default to avoid compiler warnings */
644
return EXIT_UNKNOWN_SUFFIX;
655
optpat Prefix of option to find (with - or _)
656
length Length of optpat
658
ffname Place for pointer to first found name
661
Go through all options in the my_option struct. Return number
662
of options found that match the pattern and in the argument
663
list the option found, if any. In case of ambiguous option, store
664
the name in ffname argument
667
0 No matching options
668
# Number of matching options
669
ffname points to first matching option
672
static int findopt(char *optpat, uint32_t length,
673
const struct my_option **opt_res,
677
struct my_option *opt= (struct my_option *) *opt_res;
679
for (count= 0; opt->name; opt++)
681
if (!getopt_compare_strings(opt->name, optpat, length)) /* match found */
684
if (!opt->name[length]) /* Exact match */
689
*ffname= (char *) opt->name; /* We only need to know one prev */
691
else if (strcmp(*ffname, opt->name))
694
The above test is to not count same option twice
695
(see mysql.cc, option "help")
706
function: compare_strings
708
Works like strncmp, other than 1.) considers '-' and '_' the same.
709
2.) Returns -1 if strings differ, 0 if they are equal
712
bool getopt_compare_strings(register const char *s, register const char *t,
715
char const *end= s + length;
716
for (;s != end ; s++, t++)
718
if ((*s != '-' ? *s : '_') != (*t != '-' ? *t : '_'))
725
function: eval_num_suffix
727
Transforms a number with a suffix to real number. Suffix can
728
be k|K for kilo, m|M for mega or g|G for giga.
731
static int64_t eval_num_suffix(char *argument, int *error, char *option_name)
738
num= strtoll(argument, &endchar, 10);
741
my_getopt_error_reporter(ERROR_LEVEL,
742
"Incorrect integer value: '%s'", argument);
746
if (*endchar == 'k' || *endchar == 'K')
748
else if (*endchar == 'm' || *endchar == 'M')
750
else if (*endchar == 'g' || *endchar == 'G')
751
num*= 1024L * 1024L * 1024L;
755
_("Unknown suffix '%c' used for variable '%s' (value '%s')\n"),
756
*endchar, option_name, argument);
766
Evaluates and returns the value that user gave as an argument
767
to a variable. Recognizes (case insensitive) K as KILO, M as MEGA
768
and G as GIGA bytes. Some values must be in certain blocks, as
769
defined in the given my_option struct, this function will check
770
that those values are honored.
771
In case of an error, set error value in *err.
774
static int64_t getopt_ll(char *arg, const struct my_option *optp, int *err)
776
int64_t num=eval_num_suffix(arg, err, (char*) optp->name);
777
return getopt_ll_limit_value(num, optp, NULL);
781
function: getopt_ll_limit_value
783
Applies min/max/block_size to a numeric value of an option.
784
Returns "fixed" value.
787
int64_t getopt_ll_limit_value(int64_t num, const struct my_option *optp,
791
bool adjusted= false;
792
char buf1[255], buf2[255];
793
uint64_t block_size= (optp->block_size ? (uint64_t) optp->block_size : 1L);
795
if (num > 0 && ((uint64_t) num > (uint64_t) optp->max_value) &&
796
optp->max_value) /* if max value is not set -> no upper limit */
798
num= (uint64_t) optp->max_value;
802
switch ((optp->var_type & GET_TYPE_MASK)) {
804
if (num > (int64_t) INT_MAX)
806
num= ((int64_t) INT_MAX);
811
if (num > (int64_t) INT32_MAX)
813
num= ((int64_t) INT32_MAX);
818
assert((optp->var_type & GET_TYPE_MASK) == GET_LL);
822
num= ((num - optp->sub_size) / block_size);
823
num= (int64_t) (num * block_size);
825
if (num < optp->min_value)
827
num= optp->min_value;
834
my_getopt_error_reporter(WARNING_LEVEL,
835
"option '%s': signed value %s adjusted to %s",
836
optp->name, internal::llstr(old, buf1), internal::llstr(num, buf2));
843
This is the same as getopt_ll, but is meant for uint64_t
847
static uint64_t getopt_ull(char *arg, const struct my_option *optp, int *err)
849
uint64_t num= eval_num_suffix(arg, err, (char*) optp->name);
850
return getopt_ull_limit_value(num, optp, NULL);
854
static size_t getopt_size(char *arg, const struct my_option *optp, int *err)
856
return (size_t)getopt_ull(arg, optp, err);
861
uint64_t getopt_ull_limit_value(uint64_t num, const struct my_option *optp,
864
bool adjusted= false;
866
char buf1[255], buf2[255];
868
if ((uint64_t) num > (uint64_t) optp->max_value &&
869
optp->max_value) /* if max value is not set -> no upper limit */
871
num= (uint64_t) optp->max_value;
875
switch ((optp->var_type & GET_TYPE_MASK)) {
877
if (num > (uint64_t) UINT_MAX)
879
num= ((uint64_t) UINT_MAX);
884
case GET_ULONG_IS_FAIL:
885
if (num > (uint64_t) UINT32_MAX)
887
num= ((uint64_t) UINT32_MAX);
892
if (num > (uint64_t) SIZE_MAX)
894
num= ((uint64_t) SIZE_MAX);
899
assert(((optp->var_type & GET_TYPE_MASK) == GET_ULL)
900
|| ((optp->var_type & GET_TYPE_MASK) == GET_UINT64));
904
if (optp->block_size > 1)
906
num/= (uint64_t) optp->block_size;
907
num*= (uint64_t) optp->block_size;
910
if (num < (uint64_t) optp->min_value)
912
num= (uint64_t) optp->min_value;
919
my_getopt_error_reporter(WARNING_LEVEL,
920
"option '%s': unsigned value %s adjusted to %s",
921
optp->name, internal::ullstr(old, buf1), internal::ullstr(num, buf2));
928
Get double value withing ranges
930
Evaluates and returns the value that user gave as an argument to a variable.
935
In case of an error, prints an error message and sets *err to
936
EXIT_ARGUMENT_INVALID. Otherwise err is not touched
939
static double getopt_double(char *arg, const struct my_option *optp, int *err)
943
char *end= arg + 1000; /* Big enough as *arg is \0 terminated */
944
num= internal::my_strtod(arg, &end, &error);
945
if (end[0] != 0 || error)
948
_("%s: ERROR: Invalid decimal value for option '%s'\n"),
949
internal::my_progname, optp->name);
950
*err= EXIT_ARGUMENT_INVALID;
953
if (optp->max_value && num > (double) optp->max_value)
954
num= (double) optp->max_value;
955
return max(num, (double) optp->min_value);
959
Init one value to it's default values
963
option Option to initialize
964
value Pointer to variable
967
static void init_one_value(const struct my_option *option, char** variable,
970
switch ((option->var_type & GET_TYPE_MASK)) {
972
*((bool*) variable)= (bool) value;
975
*((int*) variable)= (int) value;
979
*((uint*) variable)= (uint32_t) value;
982
*((long*) variable)= (long) value;
985
*((uint32_t*) variable)= (uint32_t) value;
987
case GET_ULONG_IS_FAIL:
988
*((ulong*) variable)= (ulong) value;
991
*((int64_t*) variable)= (int64_t) value;
994
*((size_t*) variable)= (size_t) value;
999
*((uint64_t*) variable)= (uint64_t) value;
1002
*((double*) variable)= (double) value;
1006
Do not clear variable value if it has no default value.
1007
The default value may already be set.
1008
NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
1009
so that the value has the same size as a pointer.
1011
if ((char*) (intptr_t) value)
1012
*((char**) variable)= (char*) (intptr_t) value;
1016
Do not clear variable value if it has no default value.
1017
The default value may already be set.
1018
NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
1019
so that the value has the same size as a pointer.
1021
if ((char*) (intptr_t) value)
1023
free((*(char**) variable));
1024
char *tmpptr= strdup((char *) (intptr_t) value);
1026
*((char**) variable)= tmpptr;
1029
default: /* dummy default to avoid compiler warnings */
1037
Init one value to it's default values
1041
option Option to initialize
1042
value Pointer to variable
1045
static void fini_one_value(const struct my_option *option, char **variable,
1048
switch ((option->var_type & GET_TYPE_MASK)) {
1050
free((*(char**) variable));
1051
*((char**) variable)= NULL;
1053
default: /* dummy default to avoid compiler warnings */
1060
void my_cleanup_options(const struct my_option *options)
1062
init_variables(options, fini_one_value);
1067
initialize all variables to their default values
1071
options Array of options
1074
We will initialize the value that is pointed to by options->value.
1075
If the value is of type GET_ASK_ADDR, we will also ask for the address
1076
for a value and initialize.
1079
static void init_variables(const struct my_option *options,
1080
init_func_p init_one_value)
1082
for (; options->name; options++)
1086
We must set u_max_value first as for some variables
1087
options->u_max_value == options->value and in this case we want to
1088
set the value to default value.
1090
if (options->u_max_value)
1091
init_one_value(options, options->u_max_value, options->max_value);
1093
init_one_value(options, options->value, options->def_value);
1094
if (options->var_type & GET_ASK_ADDR &&
1095
(variable= (*getopt_get_addr)("", 0, options)))
1096
init_one_value(options, variable, options->def_value);
1103
function: my_print_options
1105
Print help for all options and variables.
1108
void my_print_help(const struct my_option *options)
1110
uint32_t col, name_space= 22, comment_space= 57;
1111
const char *line_end;
1112
const struct my_option *optp;
1114
for (optp= options; optp->id; optp++)
1118
printf(" -%c%s", optp->id, strlen(optp->name) ? ", " : " ");
1126
if (strlen(optp->name))
1128
printf("--%s", optp->name);
1129
col+= 2 + (uint32_t) strlen(optp->name);
1130
if ((optp->var_type & GET_TYPE_MASK) == GET_STR ||
1131
(optp->var_type & GET_TYPE_MASK) == GET_STR_ALLOC)
1133
printf("%s=name%s ", optp->arg_type == OPT_ARG ? "[" : "",
1134
optp->arg_type == OPT_ARG ? "]" : "");
1135
col+= (optp->arg_type == OPT_ARG) ? 8 : 6;
1137
else if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG ||
1138
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
1145
printf("%s=#%s ", optp->arg_type == OPT_ARG ? "[" : "",
1146
optp->arg_type == OPT_ARG ? "]" : "");
1147
col+= (optp->arg_type == OPT_ARG) ? 5 : 3;
1149
if (col > name_space && optp->comment && *optp->comment)
1155
for (; col < name_space; col++)
1157
if (optp->comment && *optp->comment)
1159
const char *comment= _(optp->comment), *end= strchr(comment, '\0');
1161
while ((uint32_t) (end - comment) > comment_space)
1163
for (line_end= comment + comment_space; *line_end != ' '; line_end--)
1165
for (; comment != line_end; comment++)
1167
comment++; /* skip the space, as a newline will take it's place now */
1169
for (col= 0; col < name_space; col++)
1172
printf("%s", comment);
1175
if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG ||
1176
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
1178
if (optp->def_value != 0)
1180
printf(_("%*s(Defaults to on; use --skip-%s to disable.)\n"), name_space, "", optp->name);
1188
function: my_print_options
1193
void my_print_variables(const struct my_option *options)
1195
uint32_t name_space= 34, length, nr;
1196
uint64_t bit, llvalue;
1198
const struct my_option *optp;
1200
printf(_("\nVariables (--variable-name=value)\n"
1201
"and boolean options {false|true} Value (after reading options)\n"
1202
"--------------------------------- -----------------------------\n"));
1203
for (optp= options; optp->id; optp++)
1205
char* *value= (optp->var_type & GET_ASK_ADDR ?
1206
(*getopt_get_addr)("", 0, optp) : optp->value);
1209
printf("%s ", optp->name);
1210
length= (uint32_t) strlen(optp->name)+1;
1211
for (; length < name_space; length++)
1213
switch ((optp->var_type & GET_TYPE_MASK)) {
1215
if (!(llvalue= *(uint64_t*) value))
1216
printf("%s\n", _("(No default value)"));
1218
for (nr= 0, bit= 1; llvalue && nr < optp->typelib->count; nr++, bit<<=1)
1220
if (!(bit & llvalue))
1223
printf( llvalue ? "%s," : "%s\n", get_type(optp->typelib, nr));
658
return EXIT_UNKNOWN_SUFFIX;
669
optpat Prefix of option to find (with - or _)
670
length Length of optpat
672
ffname Place for pointer to first found name
675
Go through all options in the my_option struct. Return number
676
of options found that match the pattern and in the argument
677
list the option found, if any. In case of ambiguous option, store
678
the name in ffname argument
681
0 No matching options
682
# Number of matching options
683
ffname points to first matching option
686
static int findopt(char *optpat, uint32_t length,
687
const struct my_option **opt_res,
691
struct my_option *opt= (struct my_option *) *opt_res;
693
for (count= 0; opt->name; opt++)
695
if (!getopt_compare_strings(opt->name, optpat, length)) /* match found */
698
if (!opt->name[length]) /* Exact match */
703
*ffname= (char *) opt->name; /* We only need to know one prev */
705
else if (strcmp(*ffname, opt->name))
708
The above test is to not count same option twice
709
(see mysql.cc, option "help")
720
function: compare_strings
722
Works like strncmp, other than 1.) considers '-' and '_' the same.
723
2.) Returns -1 if strings differ, 0 if they are equal
726
bool getopt_compare_strings(register const char *s, register const char *t,
729
char const *end= s + length;
730
for (;s != end ; s++, t++)
732
if ((*s != '-' ? *s : '_') != (*t != '-' ? *t : '_'))
739
function: eval_num_suffix
741
Transforms a number with a suffix to real number. Suffix can
742
be k|K for kilo, m|M for mega or g|G for giga.
745
static int64_t eval_num_suffix(char *argument, int *error, char *option_name)
752
num= strtoll(argument, &endchar, 10);
755
my_getopt_error_reporter(ERROR_LEVEL,
756
"Incorrect integer value: '%s'", argument);
760
if (*endchar == 'k' || *endchar == 'K')
762
else if (*endchar == 'm' || *endchar == 'M')
764
else if (*endchar == 'g' || *endchar == 'G')
765
num*= 1024L * 1024L * 1024L;
769
_("Unknown suffix '%c' used for variable '%s' (value '%s')\n"),
770
*endchar, option_name, argument);
780
Evaluates and returns the value that user gave as an argument
781
to a variable. Recognizes (case insensitive) K as KILO, M as MEGA
782
and G as GIGA bytes. Some values must be in certain blocks, as
783
defined in the given my_option struct, this function will check
784
that those values are honored.
785
In case of an error, set error value in *err.
788
static int64_t getopt_ll(char *arg, const struct my_option *optp, int *err)
790
int64_t num=eval_num_suffix(arg, err, (char*) optp->name);
791
return getopt_ll_limit_value(num, optp, NULL);
795
function: getopt_ll_limit_value
797
Applies min/max/block_size to a numeric value of an option.
798
Returns "fixed" value.
801
int64_t getopt_ll_limit_value(int64_t num, const struct my_option *optp,
805
bool adjusted= false;
806
char buf1[255], buf2[255];
807
uint64_t block_size= (optp->block_size ? (uint64_t) optp->block_size : 1L);
809
if (num > 0 && ((uint64_t) num > (uint64_t) optp->max_value) &&
810
optp->max_value) /* if max value is not set -> no upper limit */
812
num= (uint64_t) optp->max_value;
816
switch ((optp->var_type & GET_TYPE_MASK)) {
818
if (num > (int64_t) INT_MAX)
820
num= ((int64_t) INT_MAX);
825
if (num > (int64_t) INT32_MAX)
827
num= ((int64_t) INT32_MAX);
832
assert((optp->var_type & GET_TYPE_MASK) == GET_LL);
836
num= ((num - optp->sub_size) / block_size);
837
num= (int64_t) (num * block_size);
839
if (num < optp->min_value)
841
num= optp->min_value;
848
my_getopt_error_reporter(WARNING_LEVEL,
849
"option '%s': signed value %s adjusted to %s",
850
optp->name, internal::llstr(old, buf1), internal::llstr(num, buf2));
857
This is the same as getopt_ll, but is meant for uint64_t
861
static uint64_t getopt_ull(char *arg, const struct my_option *optp, int *err)
863
uint64_t num= eval_num_suffix(arg, err, (char*) optp->name);
864
return getopt_ull_limit_value(num, optp, NULL);
868
static size_t getopt_size(char *arg, const struct my_option *optp, int *err)
870
return (size_t)getopt_ull(arg, optp, err);
875
uint64_t getopt_ull_limit_value(uint64_t num, const struct my_option *optp,
878
bool adjusted= false;
880
char buf1[255], buf2[255];
882
if ((uint64_t) num > (uint64_t) optp->max_value &&
883
optp->max_value) /* if max value is not set -> no upper limit */
885
num= (uint64_t) optp->max_value;
889
switch ((optp->var_type & GET_TYPE_MASK)) {
891
if (num > (uint64_t) UINT_MAX)
893
num= ((uint64_t) UINT_MAX);
898
case GET_ULONG_IS_FAIL:
899
if (num > (uint64_t) UINT32_MAX)
901
num= ((uint64_t) UINT32_MAX);
906
if (num > (uint64_t) SIZE_MAX)
908
num= ((uint64_t) SIZE_MAX);
913
assert(((optp->var_type & GET_TYPE_MASK) == GET_ULL)
914
|| ((optp->var_type & GET_TYPE_MASK) == GET_UINT64));
918
if (optp->block_size > 1)
920
num/= (uint64_t) optp->block_size;
921
num*= (uint64_t) optp->block_size;
924
if (num < (uint64_t) optp->min_value)
926
num= (uint64_t) optp->min_value;
933
my_getopt_error_reporter(WARNING_LEVEL,
934
"option '%s': unsigned value %s adjusted to %s",
935
optp->name, internal::ullstr(old, buf1), internal::ullstr(num, buf2));
942
Get double value withing ranges
944
Evaluates and returns the value that user gave as an argument to a variable.
949
In case of an error, prints an error message and sets *err to
950
EXIT_ARGUMENT_INVALID. Otherwise err is not touched
953
static double getopt_double(char *arg, const struct my_option *optp, int *err)
957
char *end= arg + 1000; /* Big enough as *arg is \0 terminated */
958
num= internal::my_strtod(arg, &end, &error);
959
if (end[0] != 0 || error)
962
_("%s: ERROR: Invalid decimal value for option '%s'\n"),
963
internal::my_progname, optp->name);
964
*err= EXIT_ARGUMENT_INVALID;
967
if (optp->max_value && num > (double) optp->max_value)
968
num= (double) optp->max_value;
969
return max(num, (double) optp->min_value);
973
Init one value to it's default values
977
option Option to initialize
978
value Pointer to variable
981
static void init_one_value(const struct my_option *option, char** variable,
984
switch ((option->var_type & GET_TYPE_MASK)) {
986
*((bool*) variable)= (bool) value;
989
*((int*) variable)= (int) value;
1227
printf("%s\n", get_type(optp->typelib, *(uint*) value));
1230
case GET_STR_ALLOC: /* fall through */
1231
printf("%s\n", *((char**) value) ? *((char**) value) :
1232
_("(No default value)"));
1235
printf("%s\n", *((bool*) value) ? _("true") : _("false"));
1238
printf("%d\n", *((int*) value));
1241
printf("%d\n", *((uint*) value));
993
*((uint*) variable)= (uint32_t) value;
1244
printf("%ld\n", *((long*) value));
996
*((long*) variable)= (long) value;
1246
998
case GET_UINT32:
1247
printf("%u\n", *((uint32_t*) value));
999
*((uint32_t*) variable)= (uint32_t) value;
1249
1001
case GET_ULONG_IS_FAIL:
1250
printf("%lu\n", *((ulong*) value));
1253
internal::int64_t2str((uint64_t)(*(size_t*)value), buff, 10);
1254
printf("%s\n", buff);
1002
*((ulong*) variable)= (ulong) value;
1257
printf("%s\n", internal::llstr(*((int64_t*) value), buff));
1005
*((int64_t*) variable)= (int64_t) value;
1008
*((size_t*) variable)= (size_t) value;
1260
1012
case GET_UINT64:
1261
internal::int64_t2str(*((uint64_t*) value), buff, 10);
1262
printf("%s\n", buff);
1013
*((uint64_t*) variable)= (uint64_t) value;
1264
1015
case GET_DOUBLE:
1265
printf("%g\n", *(double*) value);
1268
printf(_("(Disabled)\n"));
1016
*((double*) variable)= (double) value;
1020
Do not clear variable value if it has no default value.
1021
The default value may already be set.
1022
NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
1023
so that the value has the same size as a pointer.
1025
if ((char*) (intptr_t) value)
1026
*((char**) variable)= (char*) (intptr_t) value;
1030
Do not clear variable value if it has no default value.
1031
The default value may already be set.
1032
NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
1033
so that the value has the same size as a pointer.
1035
if ((char*) (intptr_t) value)
1037
free((*(char**) variable));
1038
char *tmpptr= strdup((char *) (intptr_t) value);
1040
*((char**) variable)= tmpptr;
1043
default: /* dummy default to avoid compiler warnings */
1051
Init one value to it's default values
1055
option Option to initialize
1056
value Pointer to variable
1059
static void fini_one_value(const struct my_option *option, char **variable,
1062
switch ((option->var_type & GET_TYPE_MASK)) {
1064
free((*(char**) variable));
1065
*((char**) variable)= NULL;
1067
default: /* dummy default to avoid compiler warnings */
1074
void my_cleanup_options(const struct my_option *options)
1076
init_variables(options, fini_one_value);
1081
initialize all variables to their default values
1085
options Array of options
1088
We will initialize the value that is pointed to by options->value.
1089
If the value is of type GET_ASK_ADDR, we will also ask for the address
1090
for a value and initialize.
1093
static void init_variables(const struct my_option *options,
1094
init_func_p init_one_value)
1096
for (; options->name; options++)
1100
We must set u_max_value first as for some variables
1101
options->u_max_value == options->value and in this case we want to
1102
set the value to default value.
1104
if (options->u_max_value)
1105
init_one_value(options, options->u_max_value, options->max_value);
1107
init_one_value(options, options->value, options->def_value);
1108
if (options->var_type & GET_ASK_ADDR &&
1109
(variable= (*getopt_get_addr)("", 0, options)))
1110
init_one_value(options, variable, options->def_value);
1117
function: my_print_options
1119
Print help for all options and variables.
1122
void my_print_help(const struct my_option *options)
1124
uint32_t col, name_space= 22, comment_space= 57;
1125
const char *line_end;
1126
const struct my_option *optp;
1128
for (optp= options; optp->id; optp++)
1132
printf(" -%c%s", optp->id, strlen(optp->name) ? ", " : " ");
1140
if (strlen(optp->name))
1142
printf("--%s", optp->name);
1143
col+= 2 + (uint32_t) strlen(optp->name);
1144
if ((optp->var_type & GET_TYPE_MASK) == GET_STR ||
1145
(optp->var_type & GET_TYPE_MASK) == GET_STR_ALLOC)
1147
printf("%s=name%s ", optp->arg_type == OPT_ARG ? "[" : "",
1148
optp->arg_type == OPT_ARG ? "]" : "");
1149
col+= (optp->arg_type == OPT_ARG) ? 8 : 6;
1151
else if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG ||
1152
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
1159
printf("%s=#%s ", optp->arg_type == OPT_ARG ? "[" : "",
1160
optp->arg_type == OPT_ARG ? "]" : "");
1161
col+= (optp->arg_type == OPT_ARG) ? 5 : 3;
1163
if (col > name_space && optp->comment && *optp->comment)
1169
for (; col < name_space; col++)
1171
if (optp->comment && *optp->comment)
1173
const char *comment= _(optp->comment), *end= strchr(comment, '\0');
1175
while ((uint32_t) (end - comment) > comment_space)
1177
for (line_end= comment + comment_space; *line_end != ' '; line_end--)
1179
for (; comment != line_end; comment++)
1181
comment++; /* skip the space, as a newline will take it's place now */
1183
for (col= 0; col < name_space; col++)
1186
printf("%s", comment);
1189
if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG ||
1190
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
1192
if (optp->def_value != 0)
1194
printf(_("%*s(Defaults to on; use --skip-%s to disable.)\n"), name_space, "", optp->name);
1202
function: my_print_options
1207
void my_print_variables(const struct my_option *options)
1209
uint32_t name_space= 34, length, nr;
1210
uint64_t bit, llvalue;
1212
const struct my_option *optp;
1214
printf(_("\nVariables (--variable-name=value)\n"
1215
"and boolean options {false|true} Value (after reading options)\n"
1216
"--------------------------------- -----------------------------\n"));
1217
for (optp= options; optp->id; optp++)
1219
char* *value= (optp->var_type & GET_ASK_ADDR ?
1220
(*getopt_get_addr)("", 0, optp) : optp->value);
1223
printf("%s ", optp->name);
1224
length= (uint32_t) strlen(optp->name)+1;
1225
for (; length < name_space; length++)
1227
switch ((optp->var_type & GET_TYPE_MASK)) {
1229
if (!(llvalue= *(uint64_t*) value))
1230
printf("%s\n", _("(No default value)"));
1232
for (nr= 0, bit= 1; llvalue && nr < optp->typelib->count; nr++, bit<<=1)
1234
if (!(bit & llvalue))
1237
printf( llvalue ? "%s," : "%s\n", get_type(optp->typelib, nr));
1241
printf("%s\n", get_type(optp->typelib, *(uint*) value));
1244
case GET_STR_ALLOC: /* fall through */
1245
printf("%s\n", *((char**) value) ? *((char**) value) :
1246
_("(No default value)"));
1249
printf("%s\n", *((bool*) value) ? _("true") : _("false"));
1252
printf("%d\n", *((int*) value));
1255
printf("%d\n", *((uint*) value));
1258
printf("%ld\n", *((long*) value));
1261
printf("%u\n", *((uint32_t*) value));
1263
case GET_ULONG_IS_FAIL:
1264
printf("%lu\n", *((ulong*) value));
1267
internal::int64_t2str((uint64_t)(*(size_t*)value), buff, 10);
1268
printf("%s\n", buff);
1271
printf("%s\n", internal::llstr(*((int64_t*) value), buff));
1275
internal::int64_t2str(*((uint64_t*) value), buff, 10);
1276
printf("%s\n", buff);
1279
printf("%g\n", *(double*) value);
1282
printf(_("(Disabled)\n"));
1275
1289
} /* namespace drizzled */