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 <my_global.h>
20
#include <mysys_err.h>
21
#include <my_getopt.h>
24
typedef void (*init_func_p)(const struct my_option *option, char **variable,
27
static void default_reporter(enum loglevel level, const char *format, ...);
28
my_error_reporter my_getopt_error_reporter= &default_reporter;
30
static int findopt(char *optpat, uint length,
31
const struct my_option **opt_res,
33
static int64_t getopt_ll(char *arg, const struct my_option *optp, int *err);
34
static uint64_t getopt_ull(char *arg, const struct my_option *optp,
36
static double getopt_double(char *arg, const struct my_option *optp, int *err);
37
static void init_variables(const struct my_option *options,
38
init_func_p init_one_value);
39
static void init_one_value(const struct my_option *option, char **variable,
41
static void fini_one_value(const struct my_option *option, char **variable,
43
static int setval(const struct my_option *opts, char* *value, char *argument,
44
bool set_maximum_value);
45
static char *check_struct_option(char *cur_arg, char *key_name);
48
The following three variables belong to same group and the number and
49
order of their arguments must correspond to each other.
51
static const char *special_opt_prefix[]=
52
{"skip", "disable", "enable", "maximum", "loose", 0};
53
static const uint special_opt_prefix_lengths[]=
56
{ OPT_SKIP, OPT_DISABLE, OPT_ENABLE, OPT_MAXIMUM, OPT_LOOSE};
58
char *disabled_my_option= (char*) "0";
61
This is a flag that can be set in client programs. 0 means that
62
my_getopt will not print error messages, but the client should do
66
bool my_getopt_print_errors= 1;
69
This is a flag that can be set in client programs. 1 means that
70
my_getopt will skip over options it does not know how to handle.
73
bool my_getopt_skip_unknown= 0;
75
static void default_reporter(enum loglevel level,
76
const char *format, ...)
79
va_start(args, format);
80
if (level == WARNING_LEVEL)
81
fprintf(stderr, "%s", "Warning: ");
82
else if (level == INFORMATION_LEVEL)
83
fprintf(stderr, "%s", "Info: ");
84
vfprintf(stderr, format, args);
91
function: handle_options
93
Sort options; put options first, until special end of options (--), or
94
until end of argv. Parse options; check that the given option matches with
95
one of the options in struct 'my_option', return error in case of ambiguous
96
or unknown option. Check that option was given an argument if it requires
97
one. Call function 'get_one_option()' once for each option.
100
static char** (*getopt_get_addr)(const char *, uint, const struct my_option *);
102
void my_getopt_register_get_addr(char** (*func_addr)(const char *, uint,
103
const struct my_option *))
105
getopt_get_addr= func_addr;
108
int handle_options(int *argc, char ***argv,
109
const struct my_option *longopts,
110
my_get_one_option get_one_option)
112
uint opt_found, argvpos= 0, length;
113
bool end_of_options= 0, must_be_var, set_maximum_value=false,
115
char **pos, **pos_end, *optend, *prev_found=NULL,
116
*opt_str, key_name[FN_REFLEN];
117
const struct my_option *optp;
121
/* handle_options() assumes arg0 (program name) always exists */
122
assert(argc && *argc >= 1);
123
assert(argv && *argv);
124
(*argc)--; /* Skip the program name */
125
(*argv)++; /* --- || ---- */
126
init_variables(longopts, init_one_value);
128
for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++)
132
if (cur_arg[0] == '-' && cur_arg[1] && !end_of_options) /* must be opt */
136
set_maximum_value= 0;
139
cur_arg++; /* skip '-' */
140
if (*cur_arg == '-' || *cur_arg == 'O') /* check for long option, */
141
{ /* --set-variable, or -O */
146
if (!(*++cur_arg)) /* If not -Ovar=# */
148
/* the argument must be in next argv */
151
if (my_getopt_print_errors)
152
my_getopt_error_reporter(ERROR_LEVEL,
153
"%s: Option '-O' requires an argument",
155
return EXIT_ARGUMENT_REQUIRED;
161
else if (!getopt_compare_strings(cur_arg, "-set-variable", 13))
164
if (cur_arg[13] == '=')
169
if (my_getopt_print_errors)
170
my_getopt_error_reporter(ERROR_LEVEL,
171
"%s: Option '--set-variable' requires an argument",
173
return EXIT_ARGUMENT_REQUIRED;
176
else if (cur_arg[14]) /* garbage, or another option. break out */
180
/* the argument must be in next argv */
183
if (my_getopt_print_errors)
184
my_getopt_error_reporter(ERROR_LEVEL,
185
"%s: Option '--set-variable' requires an argument",
187
return EXIT_ARGUMENT_REQUIRED;
193
else if (!must_be_var)
195
if (!*++cur_arg) /* skip the double dash */
197
/* '--' means end of options, look no further */
203
opt_str= check_struct_option(cur_arg, key_name);
204
optend= strcend(opt_str, '=');
205
length= (uint) (optend - opt_str);
212
Find first the right option. Return error in case of an ambiguous,
216
if (!(opt_found= findopt(opt_str, length, &optp, &prev_found)))
219
Didn't find any matching option. Let's see if someone called
220
option with a special option prefix
225
must_be_var= 1; /* option is followed by an argument */
226
for (i= 0; special_opt_prefix[i]; i++)
228
if (!getopt_compare_strings(special_opt_prefix[i], opt_str,
229
special_opt_prefix_lengths[i]) &&
230
(opt_str[special_opt_prefix_lengths[i]] == '-' ||
231
opt_str[special_opt_prefix_lengths[i]] == '_'))
234
We were called with a special prefix, we can reuse opt_found
236
opt_str+= special_opt_prefix_lengths[i] + 1;
237
length-= special_opt_prefix_lengths[i] + 1;
240
if ((opt_found= findopt(opt_str, length, &optp, &prev_found)))
244
if (my_getopt_print_errors)
245
my_getopt_error_reporter(ERROR_LEVEL,
246
"%s: ambiguous option '--%s-%s' (--%s-%s)",
247
my_progname, special_opt_prefix[i],
248
cur_arg, special_opt_prefix[i],
250
return EXIT_AMBIGUOUS_OPTION;
254
case OPT_DISABLE: /* fall through */
256
double negation is actually enable again,
257
for example: --skip-option=0 -> option = true
259
optend= (optend && *optend == '0' && !(*(optend + 1))) ?
260
(char*) "1" : disabled_my_option;
263
optend= (optend && *optend == '0' && !(*(optend + 1))) ?
264
disabled_my_option : (char*) "1";
267
set_maximum_value= true;
271
break; /* break from the inner loop, main loop continues */
273
i= -1; /* restart the loop */
279
if (my_getopt_skip_unknown)
282
preserve all the components of this unknown option, this may
283
occurr when the user provides options like: "-O foo" or
284
"--set-variable foo" (note that theres a space in there)
285
Generally, these kind of options are to be avoided
288
(*argv)[argvpos++]= *first++;
289
} while (first <= pos);
294
if (my_getopt_print_errors)
295
my_getopt_error_reporter(option_is_loose ?
296
WARNING_LEVEL : ERROR_LEVEL,
297
"%s: unknown variable '%s'",
298
my_progname, cur_arg);
299
if (!option_is_loose)
300
return EXIT_UNKNOWN_VARIABLE;
304
if (my_getopt_print_errors)
305
my_getopt_error_reporter(option_is_loose ?
306
WARNING_LEVEL : ERROR_LEVEL,
307
"%s: unknown option '--%s'",
308
my_progname, cur_arg);
309
if (!option_is_loose)
310
return EXIT_UNKNOWN_OPTION;
323
if (my_getopt_print_errors)
324
my_getopt_error_reporter(ERROR_LEVEL,
325
"%s: variable prefix '%s' is not unique",
326
my_progname, opt_str);
327
return EXIT_VAR_PREFIX_NOT_UNIQUE;
331
if (my_getopt_print_errors)
332
my_getopt_error_reporter(ERROR_LEVEL,
333
"%s: ambiguous option '--%s' (%s, %s)",
334
my_progname, opt_str, prev_found,
336
return EXIT_AMBIGUOUS_OPTION;
339
if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
341
if (my_getopt_print_errors)
343
"%s: %s: Option '%s' used, but is disabled\n", my_progname,
344
option_is_loose ? "WARNING" : "ERROR", opt_str);
350
return EXIT_OPTION_DISABLED;
352
if (must_be_var && (optp->var_type & GET_TYPE_MASK) == GET_NO_ARG)
354
if (my_getopt_print_errors)
355
my_getopt_error_reporter(ERROR_LEVEL,
356
"%s: option '%s' cannot take an argument",
357
my_progname, optp->name);
358
return EXIT_NO_ARGUMENT_ALLOWED;
360
value= optp->var_type & GET_ASK_ADDR ?
361
(*getopt_get_addr)(key_name, (uint) strlen(key_name), optp) : optp->value;
363
if (optp->arg_type == NO_ARG)
365
if (optend && (optp->var_type & GET_TYPE_MASK) != GET_BOOL)
367
if (my_getopt_print_errors)
368
my_getopt_error_reporter(ERROR_LEVEL,
369
"%s: option '--%s' cannot take an argument",
370
my_progname, optp->name);
371
return EXIT_NO_ARGUMENT_ALLOWED;
373
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL)
376
Set bool to 1 if no argument or if the user has used
377
--enable-'option-name'.
378
*optend was set to '0' if one used --disable-option
381
if (!optend || *optend == '1' ||
382
!my_strcasecmp(&my_charset_latin1, optend, "true"))
383
*((bool*) value)= (bool) 1;
384
else if (*optend == '0' ||
385
!my_strcasecmp(&my_charset_latin1, optend, "false"))
386
*((bool*) value)= (bool) 0;
389
my_getopt_error_reporter(WARNING_LEVEL,
390
"%s: ignoring option '--%s' due to \
392
my_progname, optp->name, optend);
395
get_one_option(optp->id, optp,
397
(char*) "1" : disabled_my_option);
402
else if (optp->arg_type == OPT_ARG &&
403
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
405
if (optend == disabled_my_option)
406
*((bool*) value)= (bool) 0;
409
if (!optend) /* No argument -> enable option */
410
*((bool*) value)= (bool) 1;
415
else if (optp->arg_type == REQUIRED_ARG && !optend)
417
/* Check if there are more arguments after this one */
420
if (my_getopt_print_errors)
421
my_getopt_error_reporter(ERROR_LEVEL,
422
"%s: option '--%s' requires an argument",
423
my_progname, optp->name);
424
return EXIT_ARGUMENT_REQUIRED;
432
else /* must be short option */
434
for (optend= cur_arg; *optend; optend++)
437
for (optp= longopts; optp->id; optp++)
439
if (optp->id == (int) (uchar) *optend)
441
/* Option recognized. Find next what to do with it */
443
if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
445
if (my_getopt_print_errors)
447
"%s: ERROR: Option '-%c' used, but is disabled\n",
448
my_progname, optp->id);
449
return EXIT_OPTION_DISABLED;
451
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL &&
452
optp->arg_type == NO_ARG)
454
*((bool*) optp->value)= (bool) 1;
455
get_one_option(optp->id, optp, argument);
458
else if (optp->arg_type == REQUIRED_ARG ||
459
optp->arg_type == OPT_ARG)
463
/* The rest of the option is option argument */
464
argument= optend + 1;
465
/* This is in effect a jump out of the outer loop */
470
if (optp->arg_type == OPT_ARG)
472
if (optp->var_type == GET_BOOL)
473
*((bool*) optp->value)= (bool) 1;
474
get_one_option(optp->id, optp, argument);
477
/* Check if there are more arguments after this one */
480
if (my_getopt_print_errors)
481
my_getopt_error_reporter(ERROR_LEVEL,
482
"%s: option '-%c' requires an argument",
483
my_progname, optp->id);
484
return EXIT_ARGUMENT_REQUIRED;
488
/* the other loop will break, because *optend + 1 == 0 */
491
if ((error= setval(optp, optp->value, argument,
494
my_getopt_error_reporter(ERROR_LEVEL,
495
"%s: Error while setting value '%s' to '%s'",
496
my_progname, argument, optp->name);
499
get_one_option(optp->id, optp, argument);
505
if (my_getopt_print_errors)
506
my_getopt_error_reporter(ERROR_LEVEL,
507
"%s: unknown option '-%c'",
508
my_progname, *optend);
509
return EXIT_UNKNOWN_OPTION;
512
(*argc)--; /* option handled (short), decrease argument count */
515
if ((error= setval(optp, value, argument, set_maximum_value)))
517
my_getopt_error_reporter(ERROR_LEVEL,
518
"%s: Error while setting value '%s' to '%s'",
519
my_progname, argument, optp->name);
522
get_one_option(optp->id, optp, argument);
524
(*argc)--; /* option handled (short or long), decrease argument count */
526
else /* non-option found */
527
(*argv)[argvpos++]= cur_arg;
530
Destroy the first, already handled option, so that programs that look
531
for arguments in 'argv', without checking 'argc', know when to stop.
532
Items in argv, before the destroyed one, are all non-option -arguments
533
to the program, yet to be (possibly) handled.
541
function: check_struct_option
543
Arguments: Current argument under processing from argv and a variable
544
where to store the possible key name.
546
Return value: In case option is a struct option, returns a pointer to
547
the current argument at the position where the struct option (key_name)
548
ends, the next character after the dot. In case argument is not a struct
549
option, returns a pointer to the argument.
551
key_name will hold the name of the key, or 0 if not found.
554
static char *check_struct_option(char *cur_arg, char *key_name)
558
ptr= strcend(cur_arg + 1, '.'); /* Skip the first character */
559
end= strcend(cur_arg, '=');
562
If the first dot is after an equal sign, then it is part
563
of a variable value and the option is not a struct option.
564
Also, if the last character in the string before the ending
565
NULL, or the character right before equal sign is the first
566
dot found, the option is not a struct option.
570
uint len= (uint) (ptr - cur_arg);
571
set_if_smaller(len, FN_REFLEN-1);
572
strmake(key_name, cur_arg, len);
585
Arguments: opts, argument
586
Will set the option value to given value
589
static int setval(const struct my_option *opts, char **value, char *argument,
590
bool set_maximum_value)
594
if (value && argument)
596
char* *result_pos= ((set_maximum_value) ?
597
opts->u_max_value : value);
600
return EXIT_NO_PTR_TO_VARIABLE;
602
switch ((opts->var_type & GET_TYPE_MASK)) {
603
case GET_BOOL: /* If argument differs from 0, enable option, else disable */
604
*((bool*) result_pos)= (bool) atoi(argument) != 0;
607
*((int*) result_pos)= (int) getopt_ll(argument, opts, &err);
610
*((uint*) result_pos)= (uint) getopt_ull(argument, opts, &err);
613
*((long*) result_pos)= (long) getopt_ll(argument, opts, &err);
616
*((long*) result_pos)= (long) getopt_ull(argument, opts, &err);
619
*((int64_t*) result_pos)= getopt_ll(argument, opts, &err);
622
*((uint64_t*) result_pos)= getopt_ull(argument, opts, &err);
625
*((double*) result_pos)= getopt_double(argument, opts, &err);
628
*((char**) result_pos)= argument;
631
if ((*((char**) result_pos)))
632
my_free((*(char**) result_pos), MYF(MY_WME | MY_FAE));
633
if (!(*((char**) result_pos)= my_strdup(argument, MYF(MY_WME))))
634
return EXIT_OUT_OF_MEMORY;
637
if (((*(int*)result_pos)= find_type(argument, opts->typelib, 2) - 1) < 0)
638
return EXIT_ARGUMENT_INVALID;
641
*((uint64_t*)result_pos)= find_typeset(argument, opts->typelib, &err);
643
return EXIT_ARGUMENT_INVALID;
645
default: /* dummy default to avoid compiler warnings */
649
return EXIT_UNKNOWN_SUFFIX;
660
optpat Prefix of option to find (with - or _)
661
length Length of optpat
663
ffname Place for pointer to first found name
666
Go through all options in the my_option struct. Return number
667
of options found that match the pattern and in the argument
668
list the option found, if any. In case of ambiguous option, store
669
the name in ffname argument
672
0 No matching options
673
# Number of matching options
674
ffname points to first matching option
677
static int findopt(char *optpat, uint length,
678
const struct my_option **opt_res,
682
struct my_option *opt= (struct my_option *) *opt_res;
684
for (count= 0; opt->name; opt++)
686
if (!getopt_compare_strings(opt->name, optpat, length)) /* match found */
689
if (!opt->name[length]) /* Exact match */
694
*ffname= (char *) opt->name; /* We only need to know one prev */
696
else if (strcmp(*ffname, opt->name))
699
The above test is to not count same option twice
700
(see mysql.cc, option "help")
711
function: compare_strings
713
Works like strncmp, other than 1.) considers '-' and '_' the same.
714
2.) Returns -1 if strings differ, 0 if they are equal
717
bool getopt_compare_strings(register const char *s, register const char *t,
720
char const *end= s + length;
721
for (;s != end ; s++, t++)
723
if ((*s != '-' ? *s : '_') != (*t != '-' ? *t : '_'))
730
function: eval_num_suffix
732
Transforms a number with a suffix to real number. Suffix can
733
be k|K for kilo, m|M for mega or g|G for giga.
736
static int64_t eval_num_suffix(char *argument, int *error, char *option_name)
743
num= strtoll(argument, &endchar, 10);
746
my_getopt_error_reporter(ERROR_LEVEL,
747
"Incorrect integer value: '%s'", argument);
751
if (*endchar == 'k' || *endchar == 'K')
753
else if (*endchar == 'm' || *endchar == 'M')
755
else if (*endchar == 'g' || *endchar == 'G')
756
num*= 1024L * 1024L * 1024L;
760
"Unknown suffix '%c' used for variable '%s' (value '%s')\n",
761
*endchar, option_name, argument);
771
Evaluates and returns the value that user gave as an argument
772
to a variable. Recognizes (case insensitive) K as KILO, M as MEGA
773
and G as GIGA bytes. Some values must be in certain blocks, as
774
defined in the given my_option struct, this function will check
775
that those values are honored.
776
In case of an error, set error value in *err.
779
static int64_t getopt_ll(char *arg, const struct my_option *optp, int *err)
781
int64_t num=eval_num_suffix(arg, err, (char*) optp->name);
782
return getopt_ll_limit_value(num, optp, NULL);
786
function: getopt_ll_limit_value
788
Applies min/max/block_size to a numeric value of an option.
789
Returns "fixed" value.
792
int64_t getopt_ll_limit_value(int64_t num, const struct my_option *optp,
796
bool adjusted= false;
797
char buf1[255], buf2[255];
798
uint64_t block_size= (optp->block_size ? (uint64_t) optp->block_size : 1L);
800
if (num > 0 && ((uint64_t) num > (uint64_t) optp->max_value) &&
801
optp->max_value) /* if max value is not set -> no upper limit */
803
num= (uint64_t) optp->max_value;
807
switch ((optp->var_type & GET_TYPE_MASK)) {
809
if (num > (int64_t) INT_MAX)
811
num= ((int64_t) INT_MAX);
816
#if SIZEOF_LONG < SIZEOF_LONG_LONG
817
if (num > (int64_t) LONG_MAX)
819
num= ((int64_t) LONG_MAX);
825
assert((optp->var_type & GET_TYPE_MASK) == GET_LL);
829
num= ((num - optp->sub_size) / block_size);
830
num= (int64_t) (num * block_size);
832
if (num < optp->min_value)
834
num= optp->min_value;
841
my_getopt_error_reporter(WARNING_LEVEL,
842
"option '%s': signed value %s adjusted to %s",
843
optp->name, llstr(old, buf1), llstr(num, buf2));
850
This is the same as getopt_ll, but is meant for unsigned long long
854
static uint64_t getopt_ull(char *arg, const struct my_option *optp, int *err)
856
uint64_t num= eval_num_suffix(arg, err, (char*) optp->name);
857
return getopt_ull_limit_value(num, optp, NULL);
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
#if SIZEOF_LONG < SIZEOF_LONG_LONG
885
if (num > (uint64_t) ULONG_MAX)
887
num= ((uint64_t) ULONG_MAX);
893
assert((optp->var_type & GET_TYPE_MASK) == GET_ULL);
897
if (optp->block_size > 1)
899
num/= (uint64_t) optp->block_size;
900
num*= (uint64_t) optp->block_size;
903
if (num < (uint64_t) optp->min_value)
905
num= (uint64_t) optp->min_value;
912
my_getopt_error_reporter(WARNING_LEVEL,
913
"option '%s': unsigned value %s adjusted to %s",
914
optp->name, ullstr(old, buf1), ullstr(num, buf2));
921
Get double value withing ranges
923
Evaluates and returns the value that user gave as an argument to a variable.
928
In case of an error, prints an error message and sets *err to
929
EXIT_ARGUMENT_INVALID. Otherwise err is not touched
932
static double getopt_double(char *arg, const struct my_option *optp, int *err)
936
char *end= arg + 1000; /* Big enough as *arg is \0 terminated */
937
num= my_strtod(arg, &end, &error);
938
if (end[0] != 0 || error)
941
"%s: ERROR: Invalid decimal value for option '%s'\n",
942
my_progname, optp->name);
943
*err= EXIT_ARGUMENT_INVALID;
946
if (optp->max_value && num > (double) optp->max_value)
947
num= (double) optp->max_value;
948
return max(num, (double) optp->min_value);
952
Init one value to it's default values
956
option Option to initialize
957
value Pointer to variable
960
static void init_one_value(const struct my_option *option, char** variable,
963
switch ((option->var_type & GET_TYPE_MASK)) {
965
*((bool*) variable)= (bool) value;
968
*((int*) variable)= (int) value;
972
*((uint*) variable)= (uint) value;
975
*((long*) variable)= (long) value;
978
*((ulong*) variable)= (ulong) value;
981
*((int64_t*) variable)= (int64_t) value;
985
*((uint64_t*) variable)= (uint64_t) value;
988
*((double*) variable)= (double) value;
992
Do not clear variable value if it has no default value.
993
The default value may already be set.
994
NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
995
so that the value has the same size as a pointer.
997
if ((char*) (intptr_t) value)
998
*((char**) variable)= (char*) (intptr_t) value;
1002
Do not clear variable value if it has no default value.
1003
The default value may already be set.
1004
NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
1005
so that the value has the same size as a pointer.
1007
if ((char*) (intptr_t) value)
1009
my_free((*(char**) variable), MYF(MY_ALLOW_ZERO_PTR));
1010
*((char**) variable)= my_strdup((char*) (intptr_t) value, MYF(MY_WME));
1013
default: /* dummy default to avoid compiler warnings */
1021
Init one value to it's default values
1025
option Option to initialize
1026
value Pointer to variable
1029
static void fini_one_value(const struct my_option *option, char **variable,
1030
int64_t value __attribute__ ((unused)))
1032
switch ((option->var_type & GET_TYPE_MASK)) {
1034
my_free((*(char**) variable), MYF(MY_ALLOW_ZERO_PTR));
1035
*((char**) variable)= NULL;
1037
default: /* dummy default to avoid compiler warnings */
1044
void my_cleanup_options(const struct my_option *options)
1046
init_variables(options, fini_one_value);
1051
initialize all variables to their default values
1055
options Array of options
1058
We will initialize the value that is pointed to by options->value.
1059
If the value is of type GET_ASK_ADDR, we will also ask for the address
1060
for a value and initialize.
1063
static void init_variables(const struct my_option *options,
1064
init_func_p init_one_value)
1066
for (; options->name; options++)
1070
We must set u_max_value first as for some variables
1071
options->u_max_value == options->value and in this case we want to
1072
set the value to default value.
1074
if (options->u_max_value)
1075
init_one_value(options, options->u_max_value, options->max_value);
1077
init_one_value(options, options->value, options->def_value);
1078
if (options->var_type & GET_ASK_ADDR &&
1079
(variable= (*getopt_get_addr)("", 0, options)))
1080
init_one_value(options, variable, options->def_value);
1087
function: my_print_options
1089
Print help for all options and variables.
1092
#include <help_start.h>
1094
void my_print_help(const struct my_option *options)
1096
uint col, name_space= 22, comment_space= 57;
1097
const char *line_end;
1098
const struct my_option *optp;
1100
for (optp= options; optp->id; optp++)
1104
printf(" -%c%s", optp->id, strlen(optp->name) ? ", " : " ");
1112
if (strlen(optp->name))
1114
printf("--%s", optp->name);
1115
col+= 2 + (uint) strlen(optp->name);
1116
if ((optp->var_type & GET_TYPE_MASK) == GET_STR ||
1117
(optp->var_type & GET_TYPE_MASK) == GET_STR_ALLOC)
1119
printf("%s=name%s ", optp->arg_type == OPT_ARG ? "[" : "",
1120
optp->arg_type == OPT_ARG ? "]" : "");
1121
col+= (optp->arg_type == OPT_ARG) ? 8 : 6;
1123
else if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG ||
1124
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
1131
printf("%s=#%s ", optp->arg_type == OPT_ARG ? "[" : "",
1132
optp->arg_type == OPT_ARG ? "]" : "");
1133
col+= (optp->arg_type == OPT_ARG) ? 5 : 3;
1135
if (col > name_space && optp->comment && *optp->comment)
1141
for (; col < name_space; col++)
1143
if (optp->comment && *optp->comment)
1145
const char *comment= optp->comment, *end= strend(comment);
1147
while ((uint) (end - comment) > comment_space)
1149
for (line_end= comment + comment_space; *line_end != ' '; line_end--);
1150
for (; comment != line_end; comment++)
1152
comment++; /* skip the space, as a newline will take it's place now */
1154
for (col= 0; col < name_space; col++)
1157
printf("%s", comment);
1160
if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG ||
1161
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
1163
if (optp->def_value != 0)
1165
printf("%*s(Defaults to on; use --skip-%s to disable.)\n", name_space, "", optp->name);
1173
function: my_print_options
1178
void my_print_variables(const struct my_option *options)
1180
uint name_space= 34, length, nr;
1181
uint64_t bit, llvalue;
1183
const struct my_option *optp;
1185
printf("\nVariables (--variable-name=value)\n");
1186
printf("and boolean options {false|true} Value (after reading options)\n");
1187
printf("--------------------------------- -----------------------------\n");
1188
for (optp= options; optp->id; optp++)
1190
char* *value= (optp->var_type & GET_ASK_ADDR ?
1191
(*getopt_get_addr)("", 0, optp) : optp->value);
1194
printf("%s ", optp->name);
1195
length= (uint) strlen(optp->name)+1;
1196
for (; length < name_space; length++)
1198
switch ((optp->var_type & GET_TYPE_MASK)) {
1200
if (!(llvalue= *(uint64_t*) value))
1201
printf("%s\n", "(No default value)");
1203
for (nr= 0, bit= 1; llvalue && nr < optp->typelib->count; nr++, bit<<=1)
1205
if (!(bit & llvalue))
1208
printf( llvalue ? "%s," : "%s\n", get_type(optp->typelib, nr));
1212
printf("%s\n", get_type(optp->typelib, *(uint*) value));
1215
case GET_STR_ALLOC: /* fall through */
1216
printf("%s\n", *((char**) value) ? *((char**) value) :
1217
"(No default value)");
1220
printf("%s\n", *((bool*) value) ? "true" : "false");
1223
printf("%d\n", *((int*) value));
1226
printf("%d\n", *((uint*) value));
1229
printf("%ld\n", *((long*) value));
1232
printf("%lu\n", *((ulong*) value));
1235
printf("%s\n", llstr(*((int64_t*) value), buff));
1238
int64_t2str(*((uint64_t*) value), buff, 10);
1239
printf("%s\n", buff);
1242
printf("%g\n", *(double*) value);
1245
printf("(Disabled)\n");
1252
#include <help_end.h>