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"
18
#include <mystrings/m_string.h>
21
#include <mysys_err.h>
22
#include <my_getopt.h>
25
typedef void (*init_func_p)(const struct my_option *option, char **variable,
28
static void default_reporter(enum loglevel level, const char *format, ...);
29
my_error_reporter my_getopt_error_reporter= &default_reporter;
31
static int findopt(char *optpat, uint length,
32
const struct my_option **opt_res,
34
static int64_t getopt_ll(char *arg, const struct my_option *optp, int *err);
35
static uint64_t getopt_ull(char *arg, const struct my_option *optp,
37
static double getopt_double(char *arg, const struct my_option *optp, int *err);
38
static void init_variables(const struct my_option *options,
39
init_func_p init_one_value);
40
static void init_one_value(const struct my_option *option, char **variable,
42
static void fini_one_value(const struct my_option *option, char **variable,
44
static int setval(const struct my_option *opts, char* *value, char *argument,
45
bool set_maximum_value);
46
static char *check_struct_option(char *cur_arg, char *key_name);
49
The following three variables belong to same group and the number and
50
order of their arguments must correspond to each other.
52
static const char *special_opt_prefix[]=
53
{"skip", "disable", "enable", "maximum", "loose", 0};
54
static const uint special_opt_prefix_lengths[]=
57
{ OPT_SKIP, OPT_DISABLE, OPT_ENABLE, OPT_MAXIMUM, OPT_LOOSE};
59
char *disabled_my_option= (char*) "0";
62
This is a flag that can be set in client programs. 0 means that
63
my_getopt will not print error messages, but the client should do
67
bool my_getopt_print_errors= 1;
70
This is a flag that can be set in client programs. 1 means that
71
my_getopt will skip over options it does not know how to handle.
74
bool my_getopt_skip_unknown= 0;
76
static void default_reporter(enum loglevel level,
77
const char *format, ...)
80
va_start(args, format);
81
if (level == WARNING_LEVEL)
82
fprintf(stderr, "%s", "Warning: ");
83
else if (level == INFORMATION_LEVEL)
84
fprintf(stderr, "%s", "Info: ");
85
vfprintf(stderr, format, args);
92
function: handle_options
94
Sort options; put options first, until special end of options (--), or
95
until end of argv. Parse options; check that the given option matches with
96
one of the options in struct 'my_option', return error in case of ambiguous
97
or unknown option. Check that option was given an argument if it requires
98
one. Call function 'get_one_option()' once for each option.
101
static char** (*getopt_get_addr)(const char *, uint, const struct my_option *);
103
void my_getopt_register_get_addr(char** (*func_addr)(const char *, uint,
104
const struct my_option *))
106
getopt_get_addr= func_addr;
109
int handle_options(int *argc, char ***argv,
110
const struct my_option *longopts,
111
my_get_one_option get_one_option)
113
uint opt_found, argvpos= 0, length;
114
bool end_of_options= 0, must_be_var, set_maximum_value=false,
116
char **pos, **pos_end, *optend, *prev_found=NULL,
117
*opt_str, key_name[FN_REFLEN];
118
const struct my_option *optp;
122
/* handle_options() assumes arg0 (program name) always exists */
123
assert(argc && *argc >= 1);
124
assert(argv && *argv);
125
(*argc)--; /* Skip the program name */
126
(*argv)++; /* --- || ---- */
127
init_variables(longopts, init_one_value);
129
for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++)
133
if (cur_arg[0] == '-' && cur_arg[1] && !end_of_options) /* must be opt */
137
set_maximum_value= 0;
140
cur_arg++; /* skip '-' */
141
if (*cur_arg == '-' || *cur_arg == 'O') /* check for long option, */
142
{ /* --set-variable, or -O */
147
if (!(*++cur_arg)) /* If not -Ovar=# */
149
/* the argument must be in next argv */
152
if (my_getopt_print_errors)
153
my_getopt_error_reporter(ERROR_LEVEL,
154
"%s: Option '-O' requires an argument",
156
return EXIT_ARGUMENT_REQUIRED;
162
else if (!getopt_compare_strings(cur_arg, "-set-variable", 13))
165
if (cur_arg[13] == '=')
170
if (my_getopt_print_errors)
171
my_getopt_error_reporter(ERROR_LEVEL,
172
"%s: Option '--set-variable' requires an argument",
174
return EXIT_ARGUMENT_REQUIRED;
177
else if (cur_arg[14]) /* garbage, or another option. break out */
181
/* the argument must be in next argv */
184
if (my_getopt_print_errors)
185
my_getopt_error_reporter(ERROR_LEVEL,
186
"%s: Option '--set-variable' requires an argument",
188
return EXIT_ARGUMENT_REQUIRED;
194
else if (!must_be_var)
196
if (!*++cur_arg) /* skip the double dash */
198
/* '--' means end of options, look no further */
204
opt_str= check_struct_option(cur_arg, key_name);
205
optend= strcend(opt_str, '=');
206
length= (uint) (optend - opt_str);
213
Find first the right option. Return error in case of an ambiguous,
217
if (!(opt_found= findopt(opt_str, length, &optp, &prev_found)))
220
Didn't find any matching option. Let's see if someone called
221
option with a special option prefix
226
must_be_var= 1; /* option is followed by an argument */
227
for (i= 0; special_opt_prefix[i]; i++)
229
if (!getopt_compare_strings(special_opt_prefix[i], opt_str,
230
special_opt_prefix_lengths[i]) &&
231
(opt_str[special_opt_prefix_lengths[i]] == '-' ||
232
opt_str[special_opt_prefix_lengths[i]] == '_'))
235
We were called with a special prefix, we can reuse opt_found
237
opt_str+= special_opt_prefix_lengths[i] + 1;
238
length-= special_opt_prefix_lengths[i] + 1;
241
if ((opt_found= findopt(opt_str, length, &optp, &prev_found)))
245
if (my_getopt_print_errors)
246
my_getopt_error_reporter(ERROR_LEVEL,
247
"%s: ambiguous option '--%s-%s' (--%s-%s)",
248
my_progname, special_opt_prefix[i],
249
cur_arg, special_opt_prefix[i],
251
return EXIT_AMBIGUOUS_OPTION;
255
case OPT_DISABLE: /* fall through */
257
double negation is actually enable again,
258
for example: --skip-option=0 -> option = true
260
optend= (optend && *optend == '0' && !(*(optend + 1))) ?
261
(char*) "1" : disabled_my_option;
264
optend= (optend && *optend == '0' && !(*(optend + 1))) ?
265
disabled_my_option : (char*) "1";
268
set_maximum_value= true;
272
break; /* break from the inner loop, main loop continues */
274
i= -1; /* restart the loop */
280
if (my_getopt_skip_unknown)
283
preserve all the components of this unknown option, this may
284
occurr when the user provides options like: "-O foo" or
285
"--set-variable foo" (note that theres a space in there)
286
Generally, these kind of options are to be avoided
289
(*argv)[argvpos++]= *first++;
290
} while (first <= pos);
295
if (my_getopt_print_errors)
296
my_getopt_error_reporter(option_is_loose ?
297
WARNING_LEVEL : ERROR_LEVEL,
298
"%s: unknown variable '%s'",
299
my_progname, cur_arg);
300
if (!option_is_loose)
301
return EXIT_UNKNOWN_VARIABLE;
305
if (my_getopt_print_errors)
306
my_getopt_error_reporter(option_is_loose ?
307
WARNING_LEVEL : ERROR_LEVEL,
308
"%s: unknown option '--%s'",
309
my_progname, cur_arg);
310
if (!option_is_loose)
311
return EXIT_UNKNOWN_OPTION;
324
if (my_getopt_print_errors)
325
my_getopt_error_reporter(ERROR_LEVEL,
326
"%s: variable prefix '%s' is not unique",
327
my_progname, opt_str);
328
return EXIT_VAR_PREFIX_NOT_UNIQUE;
332
if (my_getopt_print_errors)
333
my_getopt_error_reporter(ERROR_LEVEL,
334
"%s: ambiguous option '--%s' (%s, %s)",
335
my_progname, opt_str, prev_found,
337
return EXIT_AMBIGUOUS_OPTION;
340
if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
342
if (my_getopt_print_errors)
344
"%s: %s: Option '%s' used, but is disabled\n", my_progname,
345
option_is_loose ? "WARNING" : "ERROR", opt_str);
351
return EXIT_OPTION_DISABLED;
353
if (must_be_var && (optp->var_type & GET_TYPE_MASK) == GET_NO_ARG)
355
if (my_getopt_print_errors)
356
my_getopt_error_reporter(ERROR_LEVEL,
357
"%s: option '%s' cannot take an argument",
358
my_progname, optp->name);
359
return EXIT_NO_ARGUMENT_ALLOWED;
361
value= optp->var_type & GET_ASK_ADDR ?
362
(*getopt_get_addr)(key_name, (uint) strlen(key_name), optp) : optp->value;
364
if (optp->arg_type == NO_ARG)
366
if (optend && (optp->var_type & GET_TYPE_MASK) != GET_BOOL)
368
if (my_getopt_print_errors)
369
my_getopt_error_reporter(ERROR_LEVEL,
370
"%s: option '--%s' cannot take an argument",
371
my_progname, optp->name);
372
return EXIT_NO_ARGUMENT_ALLOWED;
374
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL)
377
Set bool to 1 if no argument or if the user has used
378
--enable-'option-name'.
379
*optend was set to '0' if one used --disable-option
382
if (!optend || *optend == '1' ||
383
!my_strcasecmp(&my_charset_latin1, optend, "true"))
384
*((bool*) value)= (bool) 1;
385
else if (*optend == '0' ||
386
!my_strcasecmp(&my_charset_latin1, optend, "false"))
387
*((bool*) value)= (bool) 0;
390
my_getopt_error_reporter(WARNING_LEVEL,
391
"%s: ignoring option '--%s' due to \
393
my_progname, optp->name, optend);
396
get_one_option(optp->id, optp,
398
(char*) "1" : disabled_my_option);
403
else if (optp->arg_type == OPT_ARG &&
404
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
406
if (optend == disabled_my_option)
407
*((bool*) value)= (bool) 0;
410
if (!optend) /* No argument -> enable option */
411
*((bool*) value)= (bool) 1;
416
else if (optp->arg_type == REQUIRED_ARG && !optend)
418
/* Check if there are more arguments after this one */
421
if (my_getopt_print_errors)
422
my_getopt_error_reporter(ERROR_LEVEL,
423
"%s: option '--%s' requires an argument",
424
my_progname, optp->name);
425
return EXIT_ARGUMENT_REQUIRED;
433
else /* must be short option */
435
for (optend= cur_arg; *optend; optend++)
438
for (optp= longopts; optp->id; optp++)
440
if (optp->id == (int) (uchar) *optend)
442
/* Option recognized. Find next what to do with it */
444
if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
446
if (my_getopt_print_errors)
448
"%s: ERROR: Option '-%c' used, but is disabled\n",
449
my_progname, optp->id);
450
return EXIT_OPTION_DISABLED;
452
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL &&
453
optp->arg_type == NO_ARG)
455
*((bool*) optp->value)= (bool) 1;
456
get_one_option(optp->id, optp, argument);
459
else if (optp->arg_type == REQUIRED_ARG ||
460
optp->arg_type == OPT_ARG)
464
/* The rest of the option is option argument */
465
argument= optend + 1;
466
/* This is in effect a jump out of the outer loop */
471
if (optp->arg_type == OPT_ARG)
473
if (optp->var_type == GET_BOOL)
474
*((bool*) optp->value)= (bool) 1;
475
get_one_option(optp->id, optp, argument);
478
/* Check if there are more arguments after this one */
481
if (my_getopt_print_errors)
482
my_getopt_error_reporter(ERROR_LEVEL,
483
"%s: option '-%c' requires an argument",
484
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' to '%s'",
497
my_progname, argument, optp->name);
500
get_one_option(optp->id, optp, argument);
506
if (my_getopt_print_errors)
507
my_getopt_error_reporter(ERROR_LEVEL,
508
"%s: unknown option '-%c'",
509
my_progname, *optend);
510
return EXIT_UNKNOWN_OPTION;
513
(*argc)--; /* option handled (short), decrease argument count */
516
if ((error= setval(optp, value, argument, set_maximum_value)))
518
my_getopt_error_reporter(ERROR_LEVEL,
519
"%s: Error while setting value '%s' to '%s'",
520
my_progname, argument, optp->name);
523
get_one_option(optp->id, optp, argument);
525
(*argc)--; /* option handled (short or long), decrease argument count */
527
else /* non-option found */
528
(*argv)[argvpos++]= cur_arg;
531
Destroy the first, already handled option, so that programs that look
532
for arguments in 'argv', without checking 'argc', know when to stop.
533
Items in argv, before the destroyed one, are all non-option -arguments
534
to the program, yet to be (possibly) handled.
542
function: check_struct_option
544
Arguments: Current argument under processing from argv and a variable
545
where to store the possible key name.
547
Return value: In case option is a struct option, returns a pointer to
548
the current argument at the position where the struct option (key_name)
549
ends, the next character after the dot. In case argument is not a struct
550
option, returns a pointer to the argument.
552
key_name will hold the name of the key, or 0 if not found.
555
static char *check_struct_option(char *cur_arg, char *key_name)
559
ptr= strcend(cur_arg + 1, '.'); /* Skip the first character */
560
end= strcend(cur_arg, '=');
563
If the first dot is after an equal sign, then it is part
564
of a variable value and the option is not a struct option.
565
Also, if the last character in the string before the ending
566
NULL, or the character right before equal sign is the first
567
dot found, the option is not a struct option.
571
uint len= (uint) (ptr - cur_arg);
572
set_if_smaller(len, FN_REFLEN-1);
573
strmake(key_name, cur_arg, len);
586
Arguments: opts, argument
587
Will set the option value to given value
590
static int setval(const struct my_option *opts, char **value, char *argument,
591
bool set_maximum_value)
595
if (value && argument)
597
char* *result_pos= ((set_maximum_value) ?
598
opts->u_max_value : value);
601
return EXIT_NO_PTR_TO_VARIABLE;
603
switch ((opts->var_type & GET_TYPE_MASK)) {
604
case GET_BOOL: /* If argument differs from 0, enable option, else disable */
605
*((bool*) result_pos)= (bool) atoi(argument) != 0;
608
*((int*) result_pos)= (int) getopt_ll(argument, opts, &err);
611
*((uint*) result_pos)= (uint) getopt_ull(argument, opts, &err);
614
*((long*) result_pos)= (long) getopt_ll(argument, opts, &err);
617
*((long*) result_pos)= (long) getopt_ull(argument, opts, &err);
620
*((int64_t*) result_pos)= getopt_ll(argument, opts, &err);
623
*((uint64_t*) result_pos)= getopt_ull(argument, opts, &err);
626
*((double*) result_pos)= getopt_double(argument, opts, &err);
629
*((char**) result_pos)= argument;
632
if ((*((char**) result_pos)))
633
my_free((*(char**) result_pos), MYF(MY_WME | MY_FAE));
634
if (!(*((char**) result_pos)= my_strdup(argument, MYF(MY_WME))))
635
return EXIT_OUT_OF_MEMORY;
638
if (((*(int*)result_pos)= find_type(argument, opts->typelib, 2) - 1) < 0)
639
return EXIT_ARGUMENT_INVALID;
642
*((uint64_t*)result_pos)= find_typeset(argument, opts->typelib, &err);
644
return EXIT_ARGUMENT_INVALID;
646
default: /* dummy default to avoid compiler warnings */
650
return EXIT_UNKNOWN_SUFFIX;
661
optpat Prefix of option to find (with - or _)
662
length Length of optpat
664
ffname Place for pointer to first found name
667
Go through all options in the my_option struct. Return number
668
of options found that match the pattern and in the argument
669
list the option found, if any. In case of ambiguous option, store
670
the name in ffname argument
673
0 No matching options
674
# Number of matching options
675
ffname points to first matching option
678
static int findopt(char *optpat, uint length,
679
const struct my_option **opt_res,
683
struct my_option *opt= (struct my_option *) *opt_res;
685
for (count= 0; opt->name; opt++)
687
if (!getopt_compare_strings(opt->name, optpat, length)) /* match found */
690
if (!opt->name[length]) /* Exact match */
695
*ffname= (char *) opt->name; /* We only need to know one prev */
697
else if (strcmp(*ffname, opt->name))
700
The above test is to not count same option twice
701
(see mysql.cc, option "help")
712
function: compare_strings
714
Works like strncmp, other than 1.) considers '-' and '_' the same.
715
2.) Returns -1 if strings differ, 0 if they are equal
718
bool getopt_compare_strings(register const char *s, register const char *t,
721
char const *end= s + length;
722
for (;s != end ; s++, t++)
724
if ((*s != '-' ? *s : '_') != (*t != '-' ? *t : '_'))
731
function: eval_num_suffix
733
Transforms a number with a suffix to real number. Suffix can
734
be k|K for kilo, m|M for mega or g|G for giga.
737
static int64_t eval_num_suffix(char *argument, int *error, char *option_name)
744
num= strtoll(argument, &endchar, 10);
747
my_getopt_error_reporter(ERROR_LEVEL,
748
"Incorrect integer value: '%s'", argument);
752
if (*endchar == 'k' || *endchar == 'K')
754
else if (*endchar == 'm' || *endchar == 'M')
756
else if (*endchar == 'g' || *endchar == 'G')
757
num*= 1024L * 1024L * 1024L;
761
"Unknown suffix '%c' used for variable '%s' (value '%s')\n",
762
*endchar, option_name, argument);
772
Evaluates and returns the value that user gave as an argument
773
to a variable. Recognizes (case insensitive) K as KILO, M as MEGA
774
and G as GIGA bytes. Some values must be in certain blocks, as
775
defined in the given my_option struct, this function will check
776
that those values are honored.
777
In case of an error, set error value in *err.
780
static int64_t getopt_ll(char *arg, const struct my_option *optp, int *err)
782
int64_t num=eval_num_suffix(arg, err, (char*) optp->name);
783
return getopt_ll_limit_value(num, optp, NULL);
787
function: getopt_ll_limit_value
789
Applies min/max/block_size to a numeric value of an option.
790
Returns "fixed" value.
793
int64_t getopt_ll_limit_value(int64_t num, const struct my_option *optp,
797
bool adjusted= false;
798
char buf1[255], buf2[255];
799
uint64_t block_size= (optp->block_size ? (uint64_t) optp->block_size : 1L);
801
if (num > 0 && ((uint64_t) num > (uint64_t) optp->max_value) &&
802
optp->max_value) /* if max value is not set -> no upper limit */
804
num= (uint64_t) optp->max_value;
808
switch ((optp->var_type & GET_TYPE_MASK)) {
810
if (num > (int64_t) INT_MAX)
812
num= ((int64_t) INT_MAX);
817
#if SIZEOF_LONG < SIZEOF_LONG_LONG
818
if (num > (int64_t) LONG_MAX)
820
num= ((int64_t) LONG_MAX);
826
assert((optp->var_type & GET_TYPE_MASK) == GET_LL);
830
num= ((num - optp->sub_size) / block_size);
831
num= (int64_t) (num * block_size);
833
if (num < optp->min_value)
835
num= optp->min_value;
842
my_getopt_error_reporter(WARNING_LEVEL,
843
"option '%s': signed value %s adjusted to %s",
844
optp->name, llstr(old, buf1), llstr(num, buf2));
851
This is the same as getopt_ll, but is meant for unsigned long long
855
static uint64_t getopt_ull(char *arg, const struct my_option *optp, int *err)
857
uint64_t num= eval_num_suffix(arg, err, (char*) optp->name);
858
return getopt_ull_limit_value(num, optp, NULL);
862
uint64_t getopt_ull_limit_value(uint64_t num, const struct my_option *optp,
865
bool adjusted= false;
867
char buf1[255], buf2[255];
869
if ((uint64_t) num > (uint64_t) optp->max_value &&
870
optp->max_value) /* if max value is not set -> no upper limit */
872
num= (uint64_t) optp->max_value;
876
switch ((optp->var_type & GET_TYPE_MASK)) {
878
if (num > (uint64_t) UINT_MAX)
880
num= ((uint64_t) UINT_MAX);
885
#if SIZEOF_LONG < SIZEOF_LONG_LONG
886
if (num > (uint64_t) ULONG_MAX)
888
num= ((uint64_t) ULONG_MAX);
894
assert((optp->var_type & GET_TYPE_MASK) == GET_ULL);
898
if (optp->block_size > 1)
900
num/= (uint64_t) optp->block_size;
901
num*= (uint64_t) optp->block_size;
904
if (num < (uint64_t) optp->min_value)
906
num= (uint64_t) optp->min_value;
913
my_getopt_error_reporter(WARNING_LEVEL,
914
"option '%s': unsigned value %s adjusted to %s",
915
optp->name, ullstr(old, buf1), ullstr(num, buf2));
922
Get double value withing ranges
924
Evaluates and returns the value that user gave as an argument to a variable.
929
In case of an error, prints an error message and sets *err to
930
EXIT_ARGUMENT_INVALID. Otherwise err is not touched
933
static double getopt_double(char *arg, const struct my_option *optp, int *err)
937
char *end= arg + 1000; /* Big enough as *arg is \0 terminated */
938
num= my_strtod(arg, &end, &error);
939
if (end[0] != 0 || error)
942
"%s: ERROR: Invalid decimal value for option '%s'\n",
943
my_progname, optp->name);
944
*err= EXIT_ARGUMENT_INVALID;
947
if (optp->max_value && num > (double) optp->max_value)
948
num= (double) optp->max_value;
949
return max(num, (double) optp->min_value);
953
Init one value to it's default values
957
option Option to initialize
958
value Pointer to variable
961
static void init_one_value(const struct my_option *option, char** variable,
964
switch ((option->var_type & GET_TYPE_MASK)) {
966
*((bool*) variable)= (bool) value;
969
*((int*) variable)= (int) value;
973
*((uint*) variable)= (uint) value;
976
*((long*) variable)= (long) value;
979
*((ulong*) variable)= (ulong) value;
982
*((int64_t*) variable)= (int64_t) value;
986
*((uint64_t*) variable)= (uint64_t) value;
989
*((double*) variable)= (double) value;
993
Do not clear variable value if it has no default value.
994
The default value may already be set.
995
NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
996
so that the value has the same size as a pointer.
998
if ((char*) (intptr_t) value)
999
*((char**) variable)= (char*) (intptr_t) value;
1003
Do not clear variable value if it has no default value.
1004
The default value may already be set.
1005
NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
1006
so that the value has the same size as a pointer.
1008
if ((char*) (intptr_t) value)
1010
my_free((*(char**) variable), MYF(MY_ALLOW_ZERO_PTR));
1011
*((char**) variable)= my_strdup((char*) (intptr_t) value, MYF(MY_WME));
1014
default: /* dummy default to avoid compiler warnings */
1022
Init one value to it's default values
1026
option Option to initialize
1027
value Pointer to variable
1030
static void fini_one_value(const struct my_option *option, char **variable,
1031
int64_t value __attribute__ ((unused)))
1033
switch ((option->var_type & GET_TYPE_MASK)) {
1035
my_free((*(char**) variable), MYF(MY_ALLOW_ZERO_PTR));
1036
*((char**) variable)= NULL;
1038
default: /* dummy default to avoid compiler warnings */
1045
void my_cleanup_options(const struct my_option *options)
1047
init_variables(options, fini_one_value);
1052
initialize all variables to their default values
1056
options Array of options
1059
We will initialize the value that is pointed to by options->value.
1060
If the value is of type GET_ASK_ADDR, we will also ask for the address
1061
for a value and initialize.
1064
static void init_variables(const struct my_option *options,
1065
init_func_p init_one_value)
1067
for (; options->name; options++)
1071
We must set u_max_value first as for some variables
1072
options->u_max_value == options->value and in this case we want to
1073
set the value to default value.
1075
if (options->u_max_value)
1076
init_one_value(options, options->u_max_value, options->max_value);
1078
init_one_value(options, options->value, options->def_value);
1079
if (options->var_type & GET_ASK_ADDR &&
1080
(variable= (*getopt_get_addr)("", 0, options)))
1081
init_one_value(options, variable, options->def_value);
1088
function: my_print_options
1090
Print help for all options and variables.
1093
void my_print_help(const struct my_option *options)
1095
uint col, name_space= 22, comment_space= 57;
1096
const char *line_end;
1097
const struct my_option *optp;
1099
for (optp= options; optp->id; optp++)
1103
printf(" -%c%s", optp->id, strlen(optp->name) ? ", " : " ");
1111
if (strlen(optp->name))
1113
printf("--%s", optp->name);
1114
col+= 2 + (uint) strlen(optp->name);
1115
if ((optp->var_type & GET_TYPE_MASK) == GET_STR ||
1116
(optp->var_type & GET_TYPE_MASK) == GET_STR_ALLOC)
1118
printf("%s=name%s ", optp->arg_type == OPT_ARG ? "[" : "",
1119
optp->arg_type == OPT_ARG ? "]" : "");
1120
col+= (optp->arg_type == OPT_ARG) ? 8 : 6;
1122
else if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG ||
1123
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
1130
printf("%s=#%s ", optp->arg_type == OPT_ARG ? "[" : "",
1131
optp->arg_type == OPT_ARG ? "]" : "");
1132
col+= (optp->arg_type == OPT_ARG) ? 5 : 3;
1134
if (col > name_space && optp->comment && *optp->comment)
1140
for (; col < name_space; col++)
1142
if (optp->comment && *optp->comment)
1144
const char *comment= gettext(optp->comment), *end= strend(comment);
1146
while ((uint) (end - comment) > comment_space)
1148
for (line_end= comment + comment_space; *line_end != ' '; line_end--);
1149
for (; comment != line_end; comment++)
1151
comment++; /* skip the space, as a newline will take it's place now */
1153
for (col= 0; col < name_space; col++)
1156
printf("%s", comment);
1159
if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG ||
1160
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
1162
if (optp->def_value != 0)
1164
printf(gettext("%*s(Defaults to on; use --skip-%s to disable.)\n"), name_space, "", optp->name);
1172
function: my_print_options
1177
void my_print_variables(const struct my_option *options)
1179
uint name_space= 34, length, nr;
1180
uint64_t bit, llvalue;
1182
const struct my_option *optp;
1184
printf("\nVariables (--variable-name=value)\n");
1185
printf("and boolean options {false|true} Value (after reading options)\n");
1186
printf("--------------------------------- -----------------------------\n");
1187
for (optp= options; optp->id; optp++)
1189
char* *value= (optp->var_type & GET_ASK_ADDR ?
1190
(*getopt_get_addr)("", 0, optp) : optp->value);
1193
printf("%s ", optp->name);
1194
length= (uint) strlen(optp->name)+1;
1195
for (; length < name_space; length++)
1197
switch ((optp->var_type & GET_TYPE_MASK)) {
1199
if (!(llvalue= *(uint64_t*) value))
1200
printf("%s\n", "(No default value)");
1202
for (nr= 0, bit= 1; llvalue && nr < optp->typelib->count; nr++, bit<<=1)
1204
if (!(bit & llvalue))
1207
printf( llvalue ? "%s," : "%s\n", get_type(optp->typelib, nr));
1211
printf("%s\n", get_type(optp->typelib, *(uint*) value));
1214
case GET_STR_ALLOC: /* fall through */
1215
printf("%s\n", *((char**) value) ? *((char**) value) :
1216
"(No default value)");
1219
printf("%s\n", *((bool*) value) ? "true" : "false");
1222
printf("%d\n", *((int*) value));
1225
printf("%d\n", *((uint*) value));
1228
printf("%ld\n", *((long*) value));
1231
printf("%lu\n", *((ulong*) value));
1234
printf("%s\n", llstr(*((int64_t*) value), buff));
1237
int64_t2str(*((uint64_t*) value), buff, 10);
1238
printf("%s\n", buff);
1241
printf("%g\n", *(double*) value);
1244
printf("(Disabled)\n");