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, uint32_t 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 uint32_t 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
uint32_t 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) (unsigned char) *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
uint32_t 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
free((*(char**) result_pos));
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, uint32_t 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 (num > (int64_t) INT32_MAX)
825
num= ((int64_t) INT32_MAX);
830
assert((optp->var_type & GET_TYPE_MASK) == GET_LL);
834
num= ((num - optp->sub_size) / block_size);
835
num= (int64_t) (num * block_size);
837
if (num < optp->min_value)
839
num= optp->min_value;
846
my_getopt_error_reporter(WARNING_LEVEL,
847
"option '%s': signed value %s adjusted to %s",
848
optp->name, llstr(old, buf1), llstr(num, buf2));
855
This is the same as getopt_ll, but is meant for uint64_t
859
static uint64_t getopt_ull(char *arg, const struct my_option *optp, int *err)
861
uint64_t num= eval_num_suffix(arg, err, (char*) optp->name);
862
return getopt_ull_limit_value(num, optp, NULL);
866
uint64_t getopt_ull_limit_value(uint64_t num, const struct my_option *optp,
869
bool adjusted= false;
871
char buf1[255], buf2[255];
873
if ((uint64_t) num > (uint64_t) optp->max_value &&
874
optp->max_value) /* if max value is not set -> no upper limit */
876
num= (uint64_t) optp->max_value;
880
switch ((optp->var_type & GET_TYPE_MASK)) {
882
if (num > (uint64_t) UINT_MAX)
884
num= ((uint64_t) UINT_MAX);
889
if (num > (uint64_t) UINT32_MAX)
891
num= ((uint64_t) UINT32_MAX);
896
assert((optp->var_type & GET_TYPE_MASK) == GET_ULL);
900
if (optp->block_size > 1)
902
num/= (uint64_t) optp->block_size;
903
num*= (uint64_t) optp->block_size;
906
if (num < (uint64_t) optp->min_value)
908
num= (uint64_t) optp->min_value;
915
my_getopt_error_reporter(WARNING_LEVEL,
916
"option '%s': unsigned value %s adjusted to %s",
917
optp->name, ullstr(old, buf1), ullstr(num, buf2));
924
Get double value withing ranges
926
Evaluates and returns the value that user gave as an argument to a variable.
931
In case of an error, prints an error message and sets *err to
932
EXIT_ARGUMENT_INVALID. Otherwise err is not touched
935
static double getopt_double(char *arg, const struct my_option *optp, int *err)
939
char *end= arg + 1000; /* Big enough as *arg is \0 terminated */
940
num= my_strtod(arg, &end, &error);
941
if (end[0] != 0 || error)
944
_("%s: ERROR: Invalid decimal value for option '%s'\n"),
945
my_progname, optp->name);
946
*err= EXIT_ARGUMENT_INVALID;
949
if (optp->max_value && num > (double) optp->max_value)
950
num= (double) optp->max_value;
951
return cmax(num, (double) optp->min_value);
955
Init one value to it's default values
959
option Option to initialize
960
value Pointer to variable
963
static void init_one_value(const struct my_option *option, char** variable,
966
switch ((option->var_type & GET_TYPE_MASK)) {
968
*((bool*) variable)= (bool) value;
971
*((int*) variable)= (int) value;
975
*((uint*) variable)= (uint) value;
978
*((long*) variable)= (long) value;
981
*((uint32_t*) variable)= (uint32_t) value;
984
*((int64_t*) variable)= (int64_t) value;
988
*((uint64_t*) variable)= (uint64_t) value;
991
*((double*) variable)= (double) value;
995
Do not clear variable value if it has no default value.
996
The default value may already be set.
997
NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
998
so that the value has the same size as a pointer.
1000
if ((char*) (intptr_t) value)
1001
*((char**) variable)= (char*) (intptr_t) value;
1005
Do not clear variable value if it has no default value.
1006
The default value may already be set.
1007
NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
1008
so that the value has the same size as a pointer.
1010
if ((char*) (intptr_t) value)
1012
free((*(char**) variable));
1013
*((char**) variable)= my_strdup((char*) (intptr_t) value, MYF(MY_WME));
1016
default: /* dummy default to avoid compiler warnings */
1024
Init one value to it's default values
1028
option Option to initialize
1029
value Pointer to variable
1032
static void fini_one_value(const struct my_option *option, char **variable,
1033
int64_t value __attribute__ ((unused)))
1035
switch ((option->var_type & GET_TYPE_MASK)) {
1037
free((*(char**) variable));
1038
*((char**) variable)= NULL;
1040
default: /* dummy default to avoid compiler warnings */
1047
void my_cleanup_options(const struct my_option *options)
1049
init_variables(options, fini_one_value);
1054
initialize all variables to their default values
1058
options Array of options
1061
We will initialize the value that is pointed to by options->value.
1062
If the value is of type GET_ASK_ADDR, we will also ask for the address
1063
for a value and initialize.
1066
static void init_variables(const struct my_option *options,
1067
init_func_p init_one_value)
1069
for (; options->name; options++)
1073
We must set u_max_value first as for some variables
1074
options->u_max_value == options->value and in this case we want to
1075
set the value to default value.
1077
if (options->u_max_value)
1078
init_one_value(options, options->u_max_value, options->max_value);
1080
init_one_value(options, options->value, options->def_value);
1081
if (options->var_type & GET_ASK_ADDR &&
1082
(variable= (*getopt_get_addr)("", 0, options)))
1083
init_one_value(options, variable, options->def_value);
1090
function: my_print_options
1092
Print help for all options and variables.
1095
void my_print_help(const struct my_option *options)
1097
uint32_t col, name_space= 22, comment_space= 57;
1098
const char *line_end;
1099
const struct my_option *optp;
1101
for (optp= options; optp->id; optp++)
1105
printf(" -%c%s", optp->id, strlen(optp->name) ? ", " : " ");
1113
if (strlen(optp->name))
1115
printf("--%s", optp->name);
1116
col+= 2 + (uint) strlen(optp->name);
1117
if ((optp->var_type & GET_TYPE_MASK) == GET_STR ||
1118
(optp->var_type & GET_TYPE_MASK) == GET_STR_ALLOC)
1120
printf("%s=name%s ", optp->arg_type == OPT_ARG ? "[" : "",
1121
optp->arg_type == OPT_ARG ? "]" : "");
1122
col+= (optp->arg_type == OPT_ARG) ? 8 : 6;
1124
else if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG ||
1125
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
1132
printf("%s=#%s ", optp->arg_type == OPT_ARG ? "[" : "",
1133
optp->arg_type == OPT_ARG ? "]" : "");
1134
col+= (optp->arg_type == OPT_ARG) ? 5 : 3;
1136
if (col > name_space && optp->comment && *optp->comment)
1142
for (; col < name_space; col++)
1144
if (optp->comment && *optp->comment)
1146
const char *comment= _(optp->comment), *end= strchr(comment, '\0');
1148
while ((uint) (end - comment) > comment_space)
1150
for (line_end= comment + comment_space; *line_end != ' '; line_end--);
1151
for (; comment != line_end; comment++)
1153
comment++; /* skip the space, as a newline will take it's place now */
1155
for (col= 0; col < name_space; col++)
1158
printf("%s", comment);
1161
if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG ||
1162
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
1164
if (optp->def_value != 0)
1166
printf(_("%*s(Defaults to on; use --skip-%s to disable.)\n"), name_space, "", optp->name);
1174
function: my_print_options
1179
void my_print_variables(const struct my_option *options)
1181
uint32_t name_space= 34, length, nr;
1182
uint64_t bit, llvalue;
1184
const struct my_option *optp;
1186
printf(_("\nVariables (--variable-name=value)\n"
1187
"and boolean options {false|true} Value (after reading options)\n"
1188
"--------------------------------- -----------------------------\n"));
1189
for (optp= options; optp->id; optp++)
1191
char* *value= (optp->var_type & GET_ASK_ADDR ?
1192
(*getopt_get_addr)("", 0, optp) : optp->value);
1195
printf("%s ", optp->name);
1196
length= (uint) strlen(optp->name)+1;
1197
for (; length < name_space; length++)
1199
switch ((optp->var_type & GET_TYPE_MASK)) {
1201
if (!(llvalue= *(uint64_t*) value))
1202
printf("%s\n", _("(No default value)"));
1204
for (nr= 0, bit= 1; llvalue && nr < optp->typelib->count; nr++, bit<<=1)
1206
if (!(bit & llvalue))
1209
printf( llvalue ? "%s," : "%s\n", get_type(optp->typelib, nr));
1213
printf("%s\n", get_type(optp->typelib, *(uint*) value));
1216
case GET_STR_ALLOC: /* fall through */
1217
printf("%s\n", *((char**) value) ? *((char**) value) :
1218
_("(No default value)"));
1221
printf("%s\n", *((bool*) value) ? _("true") : _("false"));
1224
printf("%d\n", *((int*) value));
1227
printf("%d\n", *((uint*) value));
1230
printf("%ld\n", *((long*) value));
1233
printf("%u\n", *((uint32_t*) value));
1236
printf("%s\n", llstr(*((int64_t*) value), buff));
1239
int64_t2str(*((uint64_t*) value), buff, 10);
1240
printf("%s\n", buff);
1243
printf("%g\n", *(double*) value);
1246
printf(_("(Disabled)\n"));