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 <drizzled/gettext.h>
19
#include <mystrings/m_string.h>
20
#include <mysys/my_sys.h>
21
#include <mysys/mysys_err.h>
22
#include <mysys/my_getopt.h>
28
typedef void (*init_func_p)(const struct my_option *option, char **variable,
31
static void default_reporter(enum loglevel level, const char *format, ...);
32
my_error_reporter my_getopt_error_reporter= &default_reporter;
34
static int findopt(char *optpat, uint32_t length,
35
const struct my_option **opt_res,
37
static int64_t getopt_ll(char *arg, const struct my_option *optp, int *err);
38
static uint64_t getopt_ull(char *arg, const struct my_option *optp,
40
static double getopt_double(char *arg, const struct my_option *optp, int *err);
41
static void init_variables(const struct my_option *options,
42
init_func_p init_one_value);
43
static void init_one_value(const struct my_option *option, char **variable,
45
static void fini_one_value(const struct my_option *option, char **variable,
47
static int setval(const struct my_option *opts, char* *value, char *argument,
48
bool set_maximum_value);
49
static char *check_struct_option(char *cur_arg, char *key_name);
52
The following three variables belong to same group and the number and
53
order of their arguments must correspond to each other.
55
static const char *special_opt_prefix[]=
56
{"skip", "disable", "enable", "maximum", "loose", 0};
57
static const uint32_t special_opt_prefix_lengths[]=
60
{ OPT_SKIP, OPT_DISABLE, OPT_ENABLE, OPT_MAXIMUM, OPT_LOOSE};
62
char *disabled_my_option= (char*) "0";
65
This is a flag that can be set in client programs. 0 means that
66
my_getopt will not print error messages, but the client should do
70
bool my_getopt_print_errors= 1;
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
static void default_reporter(enum loglevel level,
80
const char *format, ...)
83
va_start(args, format);
84
if (level == WARNING_LEVEL)
85
fprintf(stderr, "%s", _("Warning: "));
86
else if (level == INFORMATION_LEVEL)
87
fprintf(stderr, "%s", _("Info: "));
88
vfprintf(stderr, format, args);
95
function: handle_options
97
Sort options; put options first, until special end of options (--), or
98
until end of argv. Parse options; check that the given option matches with
99
one of the options in struct 'my_option', return error in case of ambiguous
100
or unknown option. Check that option was given an argument if it requires
101
one. Call function 'get_one_option()' once for each option.
104
static getopt_get_addr_func getopt_get_addr;
106
void my_getopt_register_get_addr(getopt_get_addr_func func_addr)
108
getopt_get_addr= func_addr;
111
int handle_options(int *argc, char ***argv,
112
const struct my_option *longopts,
113
my_get_one_option get_one_option)
115
uint32_t opt_found, argvpos= 0, length;
116
bool end_of_options= 0, must_be_var, set_maximum_value=false,
118
char **pos, **pos_end, *optend, *prev_found=NULL,
119
*opt_str, key_name[FN_REFLEN];
120
const struct my_option *optp;
124
/* handle_options() assumes arg0 (program name) always exists */
125
assert(argc && *argc >= 1);
126
assert(argv && *argv);
127
(*argc)--; /* Skip the program name */
128
(*argv)++; /* --- || ---- */
129
init_variables(longopts, init_one_value);
131
for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++)
135
if (cur_arg[0] == '-' && cur_arg[1] && !end_of_options) /* must be opt */
139
set_maximum_value= 0;
142
cur_arg++; /* skip '-' */
143
if (*cur_arg == '-' || *cur_arg == 'O') /* check for long option, */
144
{ /* --set-variable, or -O */
149
if (!(*++cur_arg)) /* If not -Ovar=# */
151
/* the argument must be in next argv */
154
if (my_getopt_print_errors)
155
my_getopt_error_reporter(ERROR_LEVEL,
156
"%s: Option '-O' requires an argument",
158
return EXIT_ARGUMENT_REQUIRED;
164
else if (!getopt_compare_strings(cur_arg, "-set-variable", 13))
167
if (cur_arg[13] == '=')
172
if (my_getopt_print_errors)
173
my_getopt_error_reporter(ERROR_LEVEL,
174
"%s: Option '--set-variable' requires an argument",
176
return EXIT_ARGUMENT_REQUIRED;
179
else if (cur_arg[14]) /* garbage, or another option. break out */
183
/* the argument must be in next argv */
186
if (my_getopt_print_errors)
187
my_getopt_error_reporter(ERROR_LEVEL,
188
"%s: Option '--set-variable' requires an argument",
190
return EXIT_ARGUMENT_REQUIRED;
196
else if (!must_be_var)
198
if (!*++cur_arg) /* skip the double dash */
200
/* '--' means end of options, look no further */
206
opt_str= check_struct_option(cur_arg, key_name);
207
optend= strrchr(opt_str, '=');
210
length= (uint) (optend - opt_str);
215
length= strlen(opt_str);
220
Find first the right option. Return error in case of an ambiguous,
224
if (!(opt_found= findopt(opt_str, length, &optp, &prev_found)))
227
Didn't find any matching option. Let's see if someone called
228
option with a special option prefix
233
must_be_var= 1; /* option is followed by an argument */
234
for (i= 0; special_opt_prefix[i]; i++)
236
if (!getopt_compare_strings(special_opt_prefix[i], opt_str,
237
special_opt_prefix_lengths[i]) &&
238
(opt_str[special_opt_prefix_lengths[i]] == '-' ||
239
opt_str[special_opt_prefix_lengths[i]] == '_'))
242
We were called with a special prefix, we can reuse opt_found
244
opt_str+= special_opt_prefix_lengths[i] + 1;
245
length-= special_opt_prefix_lengths[i] + 1;
248
if ((opt_found= findopt(opt_str, length, &optp, &prev_found)))
252
if (my_getopt_print_errors)
253
my_getopt_error_reporter(ERROR_LEVEL,
254
"%s: ambiguous option '--%s-%s' (--%s-%s)",
255
my_progname, special_opt_prefix[i],
256
cur_arg, special_opt_prefix[i],
258
return EXIT_AMBIGUOUS_OPTION;
262
case OPT_DISABLE: /* fall through */
264
double negation is actually enable again,
265
for example: --skip-option=0 -> option = true
267
optend= (optend && *optend == '0' && !(*(optend + 1))) ?
268
(char*) "1" : disabled_my_option;
271
optend= (optend && *optend == '0' && !(*(optend + 1))) ?
272
disabled_my_option : (char*) "1";
275
set_maximum_value= true;
279
break; /* break from the inner loop, main loop continues */
281
i= -1; /* restart the loop */
287
if (my_getopt_skip_unknown)
290
preserve all the components of this unknown option, this may
291
occurr when the user provides options like: "-O foo" or
292
"--set-variable foo" (note that theres a space in there)
293
Generally, these kind of options are to be avoided
296
(*argv)[argvpos++]= *first++;
297
} while (first <= pos);
302
if (my_getopt_print_errors)
303
my_getopt_error_reporter(option_is_loose ?
304
WARNING_LEVEL : ERROR_LEVEL,
305
"%s: unknown variable '%s'",
306
my_progname, cur_arg);
307
if (!option_is_loose)
308
return EXIT_UNKNOWN_VARIABLE;
312
if (my_getopt_print_errors)
313
my_getopt_error_reporter(option_is_loose ?
314
WARNING_LEVEL : ERROR_LEVEL,
315
"%s: unknown option '--%s'",
316
my_progname, cur_arg);
317
if (!option_is_loose)
318
return EXIT_UNKNOWN_OPTION;
331
if (my_getopt_print_errors)
332
my_getopt_error_reporter(ERROR_LEVEL,
333
"%s: variable prefix '%s' is not unique",
334
my_progname, opt_str);
335
return EXIT_VAR_PREFIX_NOT_UNIQUE;
339
if (my_getopt_print_errors)
340
my_getopt_error_reporter(ERROR_LEVEL,
341
"%s: ambiguous option '--%s' (%s, %s)",
342
my_progname, opt_str, prev_found,
344
return EXIT_AMBIGUOUS_OPTION;
347
if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
349
if (my_getopt_print_errors)
351
_("%s: %s: Option '%s' used, but is disabled\n"), my_progname,
352
option_is_loose ? _("WARNING") : _("ERROR"), opt_str);
358
return EXIT_OPTION_DISABLED;
360
if (must_be_var && (optp->var_type & GET_TYPE_MASK) == GET_NO_ARG)
362
if (my_getopt_print_errors)
363
my_getopt_error_reporter(ERROR_LEVEL,
364
"%s: option '%s' cannot take an argument",
365
my_progname, optp->name);
366
return EXIT_NO_ARGUMENT_ALLOWED;
368
value= optp->var_type & GET_ASK_ADDR ?
369
(*getopt_get_addr)(key_name, (uint) strlen(key_name), optp) : optp->value;
371
if (optp->arg_type == NO_ARG)
373
if (optend && (optp->var_type & GET_TYPE_MASK) != GET_BOOL)
375
if (my_getopt_print_errors)
376
my_getopt_error_reporter(ERROR_LEVEL,
377
"%s: option '--%s' cannot take an argument",
378
my_progname, optp->name);
379
return EXIT_NO_ARGUMENT_ALLOWED;
381
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL)
384
Set bool to 1 if no argument or if the user has used
385
--enable-'option-name'.
386
*optend was set to '0' if one used --disable-option
389
if (!optend || *optend == '1' ||
390
!my_strcasecmp(&my_charset_utf8_general_ci, optend, "true"))
391
*((bool*) value)= (bool) 1;
392
else if (*optend == '0' ||
393
!my_strcasecmp(&my_charset_utf8_general_ci, optend, "false"))
394
*((bool*) value)= (bool) 0;
397
my_getopt_error_reporter(WARNING_LEVEL,
398
"%s: ignoring option '--%s' due to \
400
my_progname, optp->name, optend);
403
get_one_option(optp->id, optp,
405
(char*) "1" : disabled_my_option);
410
else if (optp->arg_type == OPT_ARG &&
411
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
413
if (optend == disabled_my_option)
414
*((bool*) value)= (bool) 0;
417
if (!optend) /* No argument -> enable option */
418
*((bool*) value)= (bool) 1;
423
else if (optp->arg_type == REQUIRED_ARG && !optend)
425
/* Check if there are more arguments after this one */
428
if (my_getopt_print_errors)
429
my_getopt_error_reporter(ERROR_LEVEL,
430
"%s: option '--%s' requires an argument",
431
my_progname, optp->name);
432
return EXIT_ARGUMENT_REQUIRED;
440
else /* must be short option */
442
for (optend= cur_arg; *optend; optend++)
445
for (optp= longopts; optp->id; optp++)
447
if (optp->id == (int) (unsigned char) *optend)
449
/* Option recognized. Find next what to do with it */
451
if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
453
if (my_getopt_print_errors)
455
_("%s: ERROR: Option '-%c' used, but is disabled\n"),
456
my_progname, optp->id);
457
return EXIT_OPTION_DISABLED;
459
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL &&
460
optp->arg_type == NO_ARG)
462
*((bool*) optp->value)= (bool) 1;
463
get_one_option(optp->id, optp, argument);
466
else if (optp->arg_type == REQUIRED_ARG ||
467
optp->arg_type == OPT_ARG)
471
/* The rest of the option is option argument */
472
argument= optend + 1;
473
/* This is in effect a jump out of the outer loop */
478
if (optp->arg_type == OPT_ARG)
480
if (optp->var_type == GET_BOOL)
481
*((bool*) optp->value)= (bool) 1;
482
get_one_option(optp->id, optp, argument);
485
/* Check if there are more arguments after this one */
488
if (my_getopt_print_errors)
489
my_getopt_error_reporter(ERROR_LEVEL,
490
"%s: option '-%c' requires an argument",
491
my_progname, optp->id);
492
return EXIT_ARGUMENT_REQUIRED;
496
/* the other loop will break, because *optend + 1 == 0 */
499
if ((error= setval(optp, optp->value, argument,
502
my_getopt_error_reporter(ERROR_LEVEL,
503
"%s: Error while setting value '%s' to '%s'",
504
my_progname, argument, optp->name);
507
get_one_option(optp->id, optp, argument);
513
if (my_getopt_print_errors)
514
my_getopt_error_reporter(ERROR_LEVEL,
515
"%s: unknown option '-%c'",
516
my_progname, *optend);
517
return EXIT_UNKNOWN_OPTION;
520
(*argc)--; /* option handled (short), decrease argument count */
523
if ((error= setval(optp, value, argument, set_maximum_value)))
525
my_getopt_error_reporter(ERROR_LEVEL,
526
"%s: Error while setting value '%s' to '%s'",
527
my_progname, argument, optp->name);
530
get_one_option(optp->id, optp, argument);
532
(*argc)--; /* option handled (short or long), decrease argument count */
534
else /* non-option found */
535
(*argv)[argvpos++]= cur_arg;
538
Destroy the first, already handled option, so that programs that look
539
for arguments in 'argv', without checking 'argc', know when to stop.
540
Items in argv, before the destroyed one, are all non-option -arguments
541
to the program, yet to be (possibly) handled.
549
function: check_struct_option
551
Arguments: Current argument under processing from argv and a variable
552
where to store the possible key name.
554
Return value: In case option is a struct option, returns a pointer to
555
the current argument at the position where the struct option (key_name)
556
ends, the next character after the dot. In case argument is not a struct
557
option, returns a pointer to the argument.
559
key_name will hold the name of the key, or 0 if not found.
562
static char *check_struct_option(char *cur_arg, char *key_name)
566
ptr= strrchr(cur_arg + 1, '.'); /* Skip the first character */
567
end= strrchr(cur_arg, '=');
570
If the first dot is after an equal sign, then it is part
571
of a variable value and the option is not a struct option.
572
Also, if the last character in the string before the ending
573
NULL, or the character right before equal sign is the first
574
dot found, the option is not a struct option.
576
if ((ptr != NULL) && (end != NULL) && (end - ptr > 1))
578
uint32_t len= (uint) (ptr - cur_arg);
579
set_if_smaller(len, FN_REFLEN-1);
580
strmake(key_name, cur_arg, len);
590
Arguments: opts, argument
591
Will set the option value to given value
594
static int setval(const struct my_option *opts, char **value, char *argument,
595
bool set_maximum_value)
599
if (value && argument)
601
char* *result_pos= ((set_maximum_value) ?
602
opts->u_max_value : value);
605
return EXIT_NO_PTR_TO_VARIABLE;
607
switch ((opts->var_type & GET_TYPE_MASK)) {
608
case GET_BOOL: /* If argument differs from 0, enable option, else disable */
609
*((bool*) result_pos)= (bool) atoi(argument) != 0;
612
*((int32_t*) result_pos)= (int) getopt_ll(argument, opts, &err);
615
*((uint32_t*) result_pos)= (uint) getopt_ull(argument, opts, &err);
618
*((long*) result_pos)= (long) getopt_ll(argument, opts, &err);
621
*((long*) result_pos)= (long) getopt_ull(argument, opts, &err);
624
*((int64_t*) result_pos)= getopt_ll(argument, opts, &err);
627
*((uint64_t*) result_pos)= getopt_ull(argument, opts, &err);
630
*((double*) result_pos)= getopt_double(argument, opts, &err);
633
*((char**) result_pos)= argument;
636
if ((*((char**) result_pos)))
637
free((*(char**) result_pos));
638
if (!(*((char**) result_pos)= my_strdup(argument, MYF(MY_WME))))
639
return EXIT_OUT_OF_MEMORY;
642
if (((*(int*)result_pos)= find_type(argument, opts->typelib, 2) - 1) < 0)
643
return EXIT_ARGUMENT_INVALID;
646
*((uint64_t*)result_pos)= find_typeset(argument, opts->typelib, &err);
648
return EXIT_ARGUMENT_INVALID;
650
default: /* dummy default to avoid compiler warnings */
654
return EXIT_UNKNOWN_SUFFIX;
665
optpat Prefix of option to find (with - or _)
666
length Length of optpat
668
ffname Place for pointer to first found name
671
Go through all options in the my_option struct. Return number
672
of options found that match the pattern and in the argument
673
list the option found, if any. In case of ambiguous option, store
674
the name in ffname argument
677
0 No matching options
678
# Number of matching options
679
ffname points to first matching option
682
static int findopt(char *optpat, uint32_t length,
683
const struct my_option **opt_res,
687
struct my_option *opt= (struct my_option *) *opt_res;
689
for (count= 0; opt->name; opt++)
691
if (!getopt_compare_strings(opt->name, optpat, length)) /* match found */
694
if (!opt->name[length]) /* Exact match */
699
*ffname= (char *) opt->name; /* We only need to know one prev */
701
else if (strcmp(*ffname, opt->name))
704
The above test is to not count same option twice
705
(see mysql.cc, option "help")
716
function: compare_strings
718
Works like strncmp, other than 1.) considers '-' and '_' the same.
719
2.) Returns -1 if strings differ, 0 if they are equal
722
bool getopt_compare_strings(register const char *s, register const char *t,
725
char const *end= s + length;
726
for (;s != end ; s++, t++)
728
if ((*s != '-' ? *s : '_') != (*t != '-' ? *t : '_'))
735
function: eval_num_suffix
737
Transforms a number with a suffix to real number. Suffix can
738
be k|K for kilo, m|M for mega or g|G for giga.
741
static int64_t eval_num_suffix(char *argument, int *error, char *option_name)
748
num= strtoll(argument, &endchar, 10);
751
my_getopt_error_reporter(ERROR_LEVEL,
752
"Incorrect integer value: '%s'", argument);
756
if (*endchar == 'k' || *endchar == 'K')
758
else if (*endchar == 'm' || *endchar == 'M')
760
else if (*endchar == 'g' || *endchar == 'G')
761
num*= 1024L * 1024L * 1024L;
765
_("Unknown suffix '%c' used for variable '%s' (value '%s')\n"),
766
*endchar, option_name, argument);
776
Evaluates and returns the value that user gave as an argument
777
to a variable. Recognizes (case insensitive) K as KILO, M as MEGA
778
and G as GIGA bytes. Some values must be in certain blocks, as
779
defined in the given my_option struct, this function will check
780
that those values are honored.
781
In case of an error, set error value in *err.
784
static int64_t getopt_ll(char *arg, const struct my_option *optp, int *err)
786
int64_t num=eval_num_suffix(arg, err, (char*) optp->name);
787
return getopt_ll_limit_value(num, optp, NULL);
791
function: getopt_ll_limit_value
793
Applies min/max/block_size to a numeric value of an option.
794
Returns "fixed" value.
797
int64_t getopt_ll_limit_value(int64_t num, const struct my_option *optp,
801
bool adjusted= false;
802
char buf1[255], buf2[255];
803
uint64_t block_size= (optp->block_size ? (uint64_t) optp->block_size : 1L);
805
if (num > 0 && ((uint64_t) num > (uint64_t) optp->max_value) &&
806
optp->max_value) /* if max value is not set -> no upper limit */
808
num= (uint64_t) optp->max_value;
812
switch ((optp->var_type & GET_TYPE_MASK)) {
814
if (num > (int64_t) INT_MAX)
816
num= ((int64_t) INT_MAX);
821
if (num > (int64_t) INT32_MAX)
823
num= ((int64_t) INT32_MAX);
828
assert((optp->var_type & GET_TYPE_MASK) == GET_LL);
832
num= ((num - optp->sub_size) / block_size);
833
num= (int64_t) (num * block_size);
835
if (num < optp->min_value)
837
num= optp->min_value;
844
my_getopt_error_reporter(WARNING_LEVEL,
845
"option '%s': signed value %s adjusted to %s",
846
optp->name, llstr(old, buf1), llstr(num, buf2));
853
This is the same as getopt_ll, but is meant for uint64_t
857
static uint64_t getopt_ull(char *arg, const struct my_option *optp, int *err)
859
uint64_t num= eval_num_suffix(arg, err, (char*) optp->name);
860
return getopt_ull_limit_value(num, optp, NULL);
864
uint64_t getopt_ull_limit_value(uint64_t num, const struct my_option *optp,
867
bool adjusted= false;
869
char buf1[255], buf2[255];
871
if ((uint64_t) num > (uint64_t) optp->max_value &&
872
optp->max_value) /* if max value is not set -> no upper limit */
874
num= (uint64_t) optp->max_value;
878
switch ((optp->var_type & GET_TYPE_MASK)) {
880
if (num > (uint64_t) UINT_MAX)
882
num= ((uint64_t) UINT_MAX);
887
if (num > (uint64_t) UINT32_MAX)
889
num= ((uint64_t) UINT32_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 cmax(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
*((uint32_t*) variable)= (uint32_t) 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
free((*(char**) variable));
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
free((*(char**) variable));
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
uint32_t 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= _(optp->comment), *end= strchr(comment, '\0');
1146
while ((uint) (end - comment) > comment_space)
1148
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
uint32_t name_space= 34, length, nr;
1181
uint64_t bit, llvalue;
1183
const struct my_option *optp;
1185
printf(_("\nVariables (--variable-name=value)\n"
1186
"and boolean options {false|true} Value (after reading options)\n"
1187
"--------------------------------- -----------------------------\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("%u\n", *((uint32_t*) 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"));