1
/* Copyright (C) 2002-2006 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
#include "mysys_priv.h"
17
#include <libdrizzle/gettext.h>
19
#include <mystrings/m_string.h>
22
#include <mysys_err.h>
23
#include <my_getopt.h>
26
typedef void (*init_func_p)(const struct my_option *option, char **variable,
29
static void default_reporter(enum loglevel level, const char *format, ...);
30
my_error_reporter my_getopt_error_reporter= &default_reporter;
32
static int findopt(char *optpat, uint length,
33
const struct my_option **opt_res,
35
static int64_t getopt_ll(char *arg, const struct my_option *optp, int *err);
36
static uint64_t getopt_ull(char *arg, const struct my_option *optp,
38
static double getopt_double(char *arg, const struct my_option *optp, int *err);
39
static void init_variables(const struct my_option *options,
40
init_func_p init_one_value);
41
static void init_one_value(const struct my_option *option, char **variable,
43
static void fini_one_value(const struct my_option *option, char **variable,
45
static int setval(const struct my_option *opts, char* *value, char *argument,
46
bool set_maximum_value);
47
static char *check_struct_option(char *cur_arg, char *key_name);
50
The following three variables belong to same group and the number and
51
order of their arguments must correspond to each other.
53
static const char *special_opt_prefix[]=
54
{"skip", "disable", "enable", "maximum", "loose", 0};
55
static const uint special_opt_prefix_lengths[]=
58
{ OPT_SKIP, OPT_DISABLE, OPT_ENABLE, OPT_MAXIMUM, OPT_LOOSE};
60
char *disabled_my_option= (char*) "0";
63
This is a flag that can be set in client programs. 0 means that
64
my_getopt will not print error messages, but the client should do
68
bool my_getopt_print_errors= 1;
71
This is a flag that can be set in client programs. 1 means that
72
my_getopt will skip over options it does not know how to handle.
75
bool my_getopt_skip_unknown= 0;
77
static void default_reporter(enum loglevel level,
78
const char *format, ...)
81
va_start(args, format);
82
if (level == WARNING_LEVEL)
83
fprintf(stderr, "%s", _("Warning: "));
84
else if (level == INFORMATION_LEVEL)
85
fprintf(stderr, "%s", _("Info: "));
86
vfprintf(stderr, format, args);
93
function: handle_options
95
Sort options; put options first, until special end of options (--), or
96
until end of argv. Parse options; check that the given option matches with
97
one of the options in struct 'my_option', return error in case of ambiguous
98
or unknown option. Check that option was given an argument if it requires
99
one. Call function 'get_one_option()' once for each option.
102
static char** (*getopt_get_addr)(const char *, uint, const struct my_option *);
104
void my_getopt_register_get_addr(char** (*func_addr)(const char *, uint,
105
const struct my_option *))
107
getopt_get_addr= func_addr;
110
int handle_options(int *argc, char ***argv,
111
const struct my_option *longopts,
112
my_get_one_option get_one_option)
114
uint opt_found, argvpos= 0, length;
115
bool end_of_options= 0, must_be_var, set_maximum_value=false,
117
char **pos, **pos_end, *optend, *prev_found=NULL,
118
*opt_str, key_name[FN_REFLEN];
119
const struct my_option *optp;
123
/* handle_options() assumes arg0 (program name) always exists */
124
assert(argc && *argc >= 1);
125
assert(argv && *argv);
126
(*argc)--; /* Skip the program name */
127
(*argv)++; /* --- || ---- */
128
init_variables(longopts, init_one_value);
130
for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++)
134
if (cur_arg[0] == '-' && cur_arg[1] && !end_of_options) /* must be opt */
138
set_maximum_value= 0;
141
cur_arg++; /* skip '-' */
142
if (*cur_arg == '-' || *cur_arg == 'O') /* check for long option, */
143
{ /* --set-variable, or -O */
148
if (!(*++cur_arg)) /* If not -Ovar=# */
150
/* the argument must be in next argv */
153
if (my_getopt_print_errors)
154
my_getopt_error_reporter(ERROR_LEVEL,
155
"%s: Option '-O' requires an argument",
157
return EXIT_ARGUMENT_REQUIRED;
163
else if (!getopt_compare_strings(cur_arg, "-set-variable", 13))
166
if (cur_arg[13] == '=')
171
if (my_getopt_print_errors)
172
my_getopt_error_reporter(ERROR_LEVEL,
173
"%s: Option '--set-variable' requires an argument",
175
return EXIT_ARGUMENT_REQUIRED;
178
else if (cur_arg[14]) /* garbage, or another option. break out */
182
/* the argument must be in next argv */
185
if (my_getopt_print_errors)
186
my_getopt_error_reporter(ERROR_LEVEL,
187
"%s: Option '--set-variable' requires an argument",
189
return EXIT_ARGUMENT_REQUIRED;
195
else if (!must_be_var)
197
if (!*++cur_arg) /* skip the double dash */
199
/* '--' means end of options, look no further */
205
opt_str= check_struct_option(cur_arg, key_name);
206
optend= strrchr(opt_str, '=');
209
length= (uint) (optend - opt_str);
214
length= strlen(opt_str);
219
Find first the right option. Return error in case of an ambiguous,
223
if (!(opt_found= findopt(opt_str, length, &optp, &prev_found)))
226
Didn't find any matching option. Let's see if someone called
227
option with a special option prefix
232
must_be_var= 1; /* option is followed by an argument */
233
for (i= 0; special_opt_prefix[i]; i++)
235
if (!getopt_compare_strings(special_opt_prefix[i], opt_str,
236
special_opt_prefix_lengths[i]) &&
237
(opt_str[special_opt_prefix_lengths[i]] == '-' ||
238
opt_str[special_opt_prefix_lengths[i]] == '_'))
241
We were called with a special prefix, we can reuse opt_found
243
opt_str+= special_opt_prefix_lengths[i] + 1;
244
length-= special_opt_prefix_lengths[i] + 1;
247
if ((opt_found= findopt(opt_str, length, &optp, &prev_found)))
251
if (my_getopt_print_errors)
252
my_getopt_error_reporter(ERROR_LEVEL,
253
"%s: ambiguous option '--%s-%s' (--%s-%s)",
254
my_progname, special_opt_prefix[i],
255
cur_arg, special_opt_prefix[i],
257
return EXIT_AMBIGUOUS_OPTION;
261
case OPT_DISABLE: /* fall through */
263
double negation is actually enable again,
264
for example: --skip-option=0 -> option = true
266
optend= (optend && *optend == '0' && !(*(optend + 1))) ?
267
(char*) "1" : disabled_my_option;
270
optend= (optend && *optend == '0' && !(*(optend + 1))) ?
271
disabled_my_option : (char*) "1";
274
set_maximum_value= true;
278
break; /* break from the inner loop, main loop continues */
280
i= -1; /* restart the loop */
286
if (my_getopt_skip_unknown)
289
preserve all the components of this unknown option, this may
290
occurr when the user provides options like: "-O foo" or
291
"--set-variable foo" (note that theres a space in there)
292
Generally, these kind of options are to be avoided
295
(*argv)[argvpos++]= *first++;
296
} while (first <= pos);
301
if (my_getopt_print_errors)
302
my_getopt_error_reporter(option_is_loose ?
303
WARNING_LEVEL : ERROR_LEVEL,
304
"%s: unknown variable '%s'",
305
my_progname, cur_arg);
306
if (!option_is_loose)
307
return EXIT_UNKNOWN_VARIABLE;
311
if (my_getopt_print_errors)
312
my_getopt_error_reporter(option_is_loose ?
313
WARNING_LEVEL : ERROR_LEVEL,
314
"%s: unknown option '--%s'",
315
my_progname, cur_arg);
316
if (!option_is_loose)
317
return EXIT_UNKNOWN_OPTION;
330
if (my_getopt_print_errors)
331
my_getopt_error_reporter(ERROR_LEVEL,
332
"%s: variable prefix '%s' is not unique",
333
my_progname, opt_str);
334
return EXIT_VAR_PREFIX_NOT_UNIQUE;
338
if (my_getopt_print_errors)
339
my_getopt_error_reporter(ERROR_LEVEL,
340
"%s: ambiguous option '--%s' (%s, %s)",
341
my_progname, opt_str, prev_found,
343
return EXIT_AMBIGUOUS_OPTION;
346
if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
348
if (my_getopt_print_errors)
350
_("%s: %s: Option '%s' used, but is disabled\n"), my_progname,
351
option_is_loose ? _("WARNING") : _("ERROR"), opt_str);
357
return EXIT_OPTION_DISABLED;
359
if (must_be_var && (optp->var_type & GET_TYPE_MASK) == GET_NO_ARG)
361
if (my_getopt_print_errors)
362
my_getopt_error_reporter(ERROR_LEVEL,
363
"%s: option '%s' cannot take an argument",
364
my_progname, optp->name);
365
return EXIT_NO_ARGUMENT_ALLOWED;
367
value= optp->var_type & GET_ASK_ADDR ?
368
(*getopt_get_addr)(key_name, (uint) strlen(key_name), optp) : optp->value;
370
if (optp->arg_type == NO_ARG)
372
if (optend && (optp->var_type & GET_TYPE_MASK) != GET_BOOL)
374
if (my_getopt_print_errors)
375
my_getopt_error_reporter(ERROR_LEVEL,
376
"%s: option '--%s' cannot take an argument",
377
my_progname, optp->name);
378
return EXIT_NO_ARGUMENT_ALLOWED;
380
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL)
383
Set bool to 1 if no argument or if the user has used
384
--enable-'option-name'.
385
*optend was set to '0' if one used --disable-option
388
if (!optend || *optend == '1' ||
389
!my_strcasecmp(&my_charset_utf8_general_ci, optend, "true"))
390
*((bool*) value)= (bool) 1;
391
else if (*optend == '0' ||
392
!my_strcasecmp(&my_charset_utf8_general_ci, optend, "false"))
393
*((bool*) value)= (bool) 0;
396
my_getopt_error_reporter(WARNING_LEVEL,
397
"%s: ignoring option '--%s' due to \
399
my_progname, optp->name, optend);
402
get_one_option(optp->id, optp,
404
(char*) "1" : disabled_my_option);
409
else if (optp->arg_type == OPT_ARG &&
410
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
412
if (optend == disabled_my_option)
413
*((bool*) value)= (bool) 0;
416
if (!optend) /* No argument -> enable option */
417
*((bool*) value)= (bool) 1;
422
else if (optp->arg_type == REQUIRED_ARG && !optend)
424
/* Check if there are more arguments after this one */
427
if (my_getopt_print_errors)
428
my_getopt_error_reporter(ERROR_LEVEL,
429
"%s: option '--%s' requires an argument",
430
my_progname, optp->name);
431
return EXIT_ARGUMENT_REQUIRED;
439
else /* must be short option */
441
for (optend= cur_arg; *optend; optend++)
444
for (optp= longopts; optp->id; optp++)
446
if (optp->id == (int) (uchar) *optend)
448
/* Option recognized. Find next what to do with it */
450
if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
452
if (my_getopt_print_errors)
454
_("%s: ERROR: Option '-%c' used, but is disabled\n"),
455
my_progname, optp->id);
456
return EXIT_OPTION_DISABLED;
458
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL &&
459
optp->arg_type == NO_ARG)
461
*((bool*) optp->value)= (bool) 1;
462
get_one_option(optp->id, optp, argument);
465
else if (optp->arg_type == REQUIRED_ARG ||
466
optp->arg_type == OPT_ARG)
470
/* The rest of the option is option argument */
471
argument= optend + 1;
472
/* This is in effect a jump out of the outer loop */
477
if (optp->arg_type == OPT_ARG)
479
if (optp->var_type == GET_BOOL)
480
*((bool*) optp->value)= (bool) 1;
481
get_one_option(optp->id, optp, argument);
484
/* Check if there are more arguments after this one */
487
if (my_getopt_print_errors)
488
my_getopt_error_reporter(ERROR_LEVEL,
489
"%s: option '-%c' requires an argument",
490
my_progname, optp->id);
491
return EXIT_ARGUMENT_REQUIRED;
495
/* the other loop will break, because *optend + 1 == 0 */
498
if ((error= setval(optp, optp->value, argument,
501
my_getopt_error_reporter(ERROR_LEVEL,
502
"%s: Error while setting value '%s' to '%s'",
503
my_progname, argument, optp->name);
506
get_one_option(optp->id, optp, argument);
512
if (my_getopt_print_errors)
513
my_getopt_error_reporter(ERROR_LEVEL,
514
"%s: unknown option '-%c'",
515
my_progname, *optend);
516
return EXIT_UNKNOWN_OPTION;
519
(*argc)--; /* option handled (short), decrease argument count */
522
if ((error= setval(optp, value, argument, set_maximum_value)))
524
my_getopt_error_reporter(ERROR_LEVEL,
525
"%s: Error while setting value '%s' to '%s'",
526
my_progname, argument, optp->name);
529
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
uint len= (uint) (ptr - cur_arg);
578
set_if_smaller(len, FN_REFLEN-1);
579
strmake(key_name, cur_arg, len);
592
Arguments: opts, argument
593
Will set the option value to given value
596
static int setval(const struct my_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
*((int*) result_pos)= (int) getopt_ll(argument, opts, &err);
617
*((uint*) result_pos)= (uint) getopt_ull(argument, opts, &err);
620
*((long*) result_pos)= (long) getopt_ll(argument, opts, &err);
623
*((long*) result_pos)= (long) getopt_ull(argument, opts, &err);
626
*((int64_t*) result_pos)= getopt_ll(argument, opts, &err);
629
*((uint64_t*) result_pos)= getopt_ull(argument, opts, &err);
632
*((double*) result_pos)= getopt_double(argument, opts, &err);
635
*((char**) result_pos)= argument;
638
if ((*((char**) result_pos)))
639
my_free((*(char**) result_pos), MYF(MY_WME | MY_FAE));
640
if (!(*((char**) result_pos)= my_strdup(argument, MYF(MY_WME))))
641
return EXIT_OUT_OF_MEMORY;
644
if (((*(int*)result_pos)= find_type(argument, opts->typelib, 2) - 1) < 0)
645
return EXIT_ARGUMENT_INVALID;
648
*((uint64_t*)result_pos)= find_typeset(argument, opts->typelib, &err);
650
return EXIT_ARGUMENT_INVALID;
652
default: /* dummy default to avoid compiler warnings */
656
return EXIT_UNKNOWN_SUFFIX;
667
optpat Prefix of option to find (with - or _)
668
length Length of optpat
670
ffname Place for pointer to first found name
673
Go through all options in the my_option struct. Return number
674
of options found that match the pattern and in the argument
675
list the option found, if any. In case of ambiguous option, store
676
the name in ffname argument
679
0 No matching options
680
# Number of matching options
681
ffname points to first matching option
684
static int findopt(char *optpat, uint length,
685
const struct my_option **opt_res,
689
struct my_option *opt= (struct my_option *) *opt_res;
691
for (count= 0; opt->name; opt++)
693
if (!getopt_compare_strings(opt->name, optpat, length)) /* match found */
696
if (!opt->name[length]) /* Exact match */
701
*ffname= (char *) opt->name; /* We only need to know one prev */
703
else if (strcmp(*ffname, opt->name))
706
The above test is to not count same option twice
707
(see mysql.cc, option "help")
718
function: compare_strings
720
Works like strncmp, other than 1.) considers '-' and '_' the same.
721
2.) Returns -1 if strings differ, 0 if they are equal
724
bool getopt_compare_strings(register const char *s, register const char *t,
727
char const *end= s + length;
728
for (;s != end ; s++, t++)
730
if ((*s != '-' ? *s : '_') != (*t != '-' ? *t : '_'))
737
function: eval_num_suffix
739
Transforms a number with a suffix to real number. Suffix can
740
be k|K for kilo, m|M for mega or g|G for giga.
743
static int64_t eval_num_suffix(char *argument, int *error, char *option_name)
750
num= strtoll(argument, &endchar, 10);
753
my_getopt_error_reporter(ERROR_LEVEL,
754
"Incorrect integer value: '%s'", argument);
758
if (*endchar == 'k' || *endchar == 'K')
760
else if (*endchar == 'm' || *endchar == 'M')
762
else if (*endchar == 'g' || *endchar == 'G')
763
num*= 1024L * 1024L * 1024L;
767
_("Unknown suffix '%c' used for variable '%s' (value '%s')\n"),
768
*endchar, option_name, argument);
778
Evaluates and returns the value that user gave as an argument
779
to a variable. Recognizes (case insensitive) K as KILO, M as MEGA
780
and G as GIGA bytes. Some values must be in certain blocks, as
781
defined in the given my_option struct, this function will check
782
that those values are honored.
783
In case of an error, set error value in *err.
786
static int64_t getopt_ll(char *arg, const struct my_option *optp, int *err)
788
int64_t num=eval_num_suffix(arg, err, (char*) optp->name);
789
return getopt_ll_limit_value(num, optp, NULL);
793
function: getopt_ll_limit_value
795
Applies min/max/block_size to a numeric value of an option.
796
Returns "fixed" value.
799
int64_t getopt_ll_limit_value(int64_t num, const struct my_option *optp,
803
bool adjusted= false;
804
char buf1[255], buf2[255];
805
uint64_t block_size= (optp->block_size ? (uint64_t) optp->block_size : 1L);
807
if (num > 0 && ((uint64_t) num > (uint64_t) optp->max_value) &&
808
optp->max_value) /* if max value is not set -> no upper limit */
810
num= (uint64_t) optp->max_value;
814
switch ((optp->var_type & GET_TYPE_MASK)) {
816
if (num > (int64_t) INT_MAX)
818
num= ((int64_t) INT_MAX);
823
#if SIZEOF_LONG < SIZEOF_LONG_LONG
824
if (num > (int64_t) LONG_MAX)
826
num= ((int64_t) LONG_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, llstr(old, buf1), llstr(num, buf2));
857
This is the same as getopt_ll, but is meant for unsigned long long
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
uint64_t getopt_ull_limit_value(uint64_t num, const struct my_option *optp,
871
bool adjusted= false;
873
char buf1[255], buf2[255];
875
if ((uint64_t) num > (uint64_t) optp->max_value &&
876
optp->max_value) /* if max value is not set -> no upper limit */
878
num= (uint64_t) optp->max_value;
882
switch ((optp->var_type & GET_TYPE_MASK)) {
884
if (num > (uint64_t) UINT_MAX)
886
num= ((uint64_t) UINT_MAX);
891
#if SIZEOF_LONG < SIZEOF_LONG_LONG
892
if (num > (uint64_t) ULONG_MAX)
894
num= ((uint64_t) ULONG_MAX);
900
assert((optp->var_type & GET_TYPE_MASK) == GET_ULL);
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, ullstr(old, buf1), 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= my_strtod(arg, &end, &error);
945
if (end[0] != 0 || error)
948
_("%s: ERROR: Invalid decimal value for option '%s'\n"),
949
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)= (uint) value;
982
*((long*) variable)= (long) value;
985
*((uint32_t*) variable)= (uint32_t) value;
988
*((int64_t*) variable)= (int64_t) value;
992
*((uint64_t*) variable)= (uint64_t) value;
995
*((double*) variable)= (double) value;
999
Do not clear variable value if it has no default value.
1000
The default value may already be set.
1001
NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
1002
so that the value has the same size as a pointer.
1004
if ((char*) (intptr_t) value)
1005
*((char**) variable)= (char*) (intptr_t) value;
1009
Do not clear variable value if it has no default value.
1010
The default value may already be set.
1011
NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
1012
so that the value has the same size as a pointer.
1014
if ((char*) (intptr_t) value)
1016
my_free((*(char**) variable), MYF(MY_ALLOW_ZERO_PTR));
1017
*((char**) variable)= my_strdup((char*) (intptr_t) value, MYF(MY_WME));
1020
default: /* dummy default to avoid compiler warnings */
1028
Init one value to it's default values
1032
option Option to initialize
1033
value Pointer to variable
1036
static void fini_one_value(const struct my_option *option, char **variable,
1037
int64_t value __attribute__ ((unused)))
1039
switch ((option->var_type & GET_TYPE_MASK)) {
1041
my_free((*(char**) variable), MYF(MY_ALLOW_ZERO_PTR));
1042
*((char**) variable)= NULL;
1044
default: /* dummy default to avoid compiler warnings */
1051
void my_cleanup_options(const struct my_option *options)
1053
init_variables(options, fini_one_value);
1058
initialize all variables to their default values
1062
options Array of options
1065
We will initialize the value that is pointed to by options->value.
1066
If the value is of type GET_ASK_ADDR, we will also ask for the address
1067
for a value and initialize.
1070
static void init_variables(const struct my_option *options,
1071
init_func_p init_one_value)
1073
for (; options->name; options++)
1077
We must set u_max_value first as for some variables
1078
options->u_max_value == options->value and in this case we want to
1079
set the value to default value.
1081
if (options->u_max_value)
1082
init_one_value(options, options->u_max_value, options->max_value);
1084
init_one_value(options, options->value, options->def_value);
1085
if (options->var_type & GET_ASK_ADDR &&
1086
(variable= (*getopt_get_addr)("", 0, options)))
1087
init_one_value(options, variable, options->def_value);
1094
function: my_print_options
1096
Print help for all options and variables.
1099
void my_print_help(const struct my_option *options)
1101
uint col, name_space= 22, comment_space= 57;
1102
const char *line_end;
1103
const struct my_option *optp;
1105
for (optp= options; optp->id; optp++)
1109
printf(" -%c%s", optp->id, strlen(optp->name) ? ", " : " ");
1117
if (strlen(optp->name))
1119
printf("--%s", optp->name);
1120
col+= 2 + (uint) strlen(optp->name);
1121
if ((optp->var_type & GET_TYPE_MASK) == GET_STR ||
1122
(optp->var_type & GET_TYPE_MASK) == GET_STR_ALLOC)
1124
printf("%s=name%s ", optp->arg_type == OPT_ARG ? "[" : "",
1125
optp->arg_type == OPT_ARG ? "]" : "");
1126
col+= (optp->arg_type == OPT_ARG) ? 8 : 6;
1128
else if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG ||
1129
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
1136
printf("%s=#%s ", optp->arg_type == OPT_ARG ? "[" : "",
1137
optp->arg_type == OPT_ARG ? "]" : "");
1138
col+= (optp->arg_type == OPT_ARG) ? 5 : 3;
1140
if (col > name_space && optp->comment && *optp->comment)
1146
for (; col < name_space; col++)
1148
if (optp->comment && *optp->comment)
1150
const char *comment= _(optp->comment), *end= strchr(comment, '\0');
1152
while ((uint) (end - comment) > comment_space)
1154
for (line_end= comment + comment_space; *line_end != ' '; line_end--);
1155
for (; comment != line_end; comment++)
1157
comment++; /* skip the space, as a newline will take it's place now */
1159
for (col= 0; col < name_space; col++)
1162
printf("%s", comment);
1165
if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG ||
1166
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
1168
if (optp->def_value != 0)
1170
printf(_("%*s(Defaults to on; use --skip-%s to disable.)\n"), name_space, "", optp->name);
1178
function: my_print_options
1183
void my_print_variables(const struct my_option *options)
1185
uint name_space= 34, length, nr;
1186
uint64_t bit, llvalue;
1188
const struct my_option *optp;
1190
printf(_("\nVariables (--variable-name=value)\n"
1191
"and boolean options {false|true} Value (after reading options)\n"
1192
"--------------------------------- -----------------------------\n"));
1193
for (optp= options; optp->id; optp++)
1195
char* *value= (optp->var_type & GET_ASK_ADDR ?
1196
(*getopt_get_addr)("", 0, optp) : optp->value);
1199
printf("%s ", optp->name);
1200
length= (uint) strlen(optp->name)+1;
1201
for (; length < name_space; length++)
1203
switch ((optp->var_type & GET_TYPE_MASK)) {
1205
if (!(llvalue= *(uint64_t*) value))
1206
printf("%s\n", _("(No default value)"));
1208
for (nr= 0, bit= 1; llvalue && nr < optp->typelib->count; nr++, bit<<=1)
1210
if (!(bit & llvalue))
1213
printf( llvalue ? "%s," : "%s\n", get_type(optp->typelib, nr));
1217
printf("%s\n", get_type(optp->typelib, *(uint*) value));
1220
case GET_STR_ALLOC: /* fall through */
1221
printf("%s\n", *((char**) value) ? *((char**) value) :
1222
_("(No default value)"));
1225
printf("%s\n", *((bool*) value) ? _("true") : _("false"));
1228
printf("%d\n", *((int*) value));
1231
printf("%d\n", *((uint*) value));
1234
printf("%ld\n", *((long*) value));
1237
printf("%u\n", *((uint32_t*) value));
1240
printf("%s\n", llstr(*((int64_t*) value), buff));
1243
int64_t2str(*((uint64_t*) value), buff, 10);
1244
printf("%s\n", buff);
1247
printf("%g\n", *(double*) value);
1250
printf(_("(Disabled)\n"));