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/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>
32
typedef void (*init_func_p)(const struct my_option *option, char **variable,
35
extern "C" void default_reporter(enum loglevel level, const char *format, ...);
36
my_error_reporter my_getopt_error_reporter= &default_reporter;
38
static int findopt(char *optpat, uint32_t length,
39
const struct my_option **opt_res,
41
static int64_t getopt_ll(char *arg, const struct my_option *optp, int *err);
42
static uint64_t getopt_ull(char *arg, const struct my_option *optp,
44
static size_t getopt_size(char *arg, const struct my_option *optp, int *err);
45
static double getopt_double(char *arg, const struct my_option *optp, int *err);
46
static void init_variables(const struct my_option *options,
47
init_func_p init_one_value);
48
static void init_one_value(const struct my_option *option, char **variable,
50
static void fini_one_value(const struct my_option *option, char **variable,
52
static int setval(const struct my_option *opts, char* *value, char *argument,
53
bool set_maximum_value);
54
static char *check_struct_option(char *cur_arg, char *key_name);
57
The following three variables belong to same group and the number and
58
order of their arguments must correspond to each other.
60
static const char *special_opt_prefix[]=
61
{"skip", "disable", "enable", "maximum", "loose", 0};
62
static const uint32_t special_opt_prefix_lengths[]=
65
{ OPT_SKIP, OPT_DISABLE, OPT_ENABLE, OPT_MAXIMUM, OPT_LOOSE};
67
char *disabled_my_option= (char*) "0";
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
extern "C" void default_reporter(enum loglevel level, 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 getopt_get_addr_func getopt_get_addr;
102
int handle_options(int *argc, char ***argv,
103
const struct my_option *longopts,
104
my_get_one_option get_one_option)
106
uint32_t opt_found, argvpos= 0, length;
107
bool end_of_options= 0, must_be_var, set_maximum_value=false,
109
char **pos, **pos_end, *optend, *prev_found=NULL,
110
*opt_str, key_name[FN_REFLEN];
111
const struct my_option *optp;
115
/* handle_options() assumes arg0 (program name) always exists */
116
assert(argc && *argc >= 1);
117
assert(argv && *argv);
118
(*argc)--; /* Skip the program name */
119
(*argv)++; /* --- || ---- */
120
init_variables(longopts, init_one_value);
122
for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++)
126
if (cur_arg[0] == '-' && cur_arg[1] && !end_of_options) /* must be opt */
130
set_maximum_value= 0;
133
cur_arg++; /* skip '-' */
134
if (*cur_arg == '-' || *cur_arg == 'O') /* check for long option, */
135
{ /* --set-variable, or -O */
140
if (!(*++cur_arg)) /* If not -Ovar=# */
142
/* the argument must be in next argv */
145
my_getopt_error_reporter(ERROR_LEVEL,
146
"%s: Option '-O' requires an argument",
148
return EXIT_ARGUMENT_REQUIRED;
154
else if (!getopt_compare_strings(cur_arg, "-set-variable", 13))
157
if (cur_arg[13] == '=')
162
my_getopt_error_reporter(ERROR_LEVEL,
163
"%s: Option '--set-variable' requires an argument",
165
return EXIT_ARGUMENT_REQUIRED;
168
else if (cur_arg[14]) /* garbage, or another option. break out */
172
/* the argument must be in next argv */
175
my_getopt_error_reporter(ERROR_LEVEL,
176
"%s: Option '--set-variable' requires an argument",
178
return EXIT_ARGUMENT_REQUIRED;
184
else if (!must_be_var)
186
if (!*++cur_arg) /* skip the double dash */
188
/* '--' means end of options, look no further */
194
opt_str= check_struct_option(cur_arg, key_name);
195
optend= strrchr(opt_str, '=');
198
length= (uint32_t) (optend - opt_str);
203
length= static_cast<uint32_t>(strlen(opt_str));
208
Find first the right option. Return error in case of an ambiguous,
212
if (!(opt_found= findopt(opt_str, length, &optp, &prev_found)))
215
Didn't find any matching option. Let's see if someone called
216
option with a special option prefix
221
must_be_var= 1; /* option is followed by an argument */
222
for (i= 0; special_opt_prefix[i]; i++)
224
if (!getopt_compare_strings(special_opt_prefix[i], opt_str,
225
special_opt_prefix_lengths[i]) &&
226
(opt_str[special_opt_prefix_lengths[i]] == '-' ||
227
opt_str[special_opt_prefix_lengths[i]] == '_'))
230
We were called with a special prefix, we can reuse opt_found
232
opt_str+= special_opt_prefix_lengths[i] + 1;
233
length-= special_opt_prefix_lengths[i] + 1;
236
if ((opt_found= findopt(opt_str, length, &optp, &prev_found)))
240
my_getopt_error_reporter(ERROR_LEVEL,
241
"%s: ambiguous option '--%s-%s' (--%s-%s)",
242
my_progname, special_opt_prefix[i],
243
cur_arg, special_opt_prefix[i],
245
return EXIT_AMBIGUOUS_OPTION;
249
case OPT_DISABLE: /* fall through */
251
double negation is actually enable again,
252
for example: --skip-option=0 -> option = true
254
optend= (optend && *optend == '0' && !(*(optend + 1))) ?
255
(char*) "1" : disabled_my_option;
258
optend= (optend && *optend == '0' && !(*(optend + 1))) ?
259
disabled_my_option : (char*) "1";
262
set_maximum_value= true;
266
break; /* break from the inner loop, main loop continues */
268
i= -1; /* restart the loop */
274
if (my_getopt_skip_unknown)
277
preserve all the components of this unknown option, this may
278
occurr when the user provides options like: "-O foo" or
279
"--set-variable foo" (note that theres a space in there)
280
Generally, these kind of options are to be avoided
283
(*argv)[argvpos++]= *first++;
284
} while (first <= pos);
289
my_getopt_error_reporter(option_is_loose ?
290
WARNING_LEVEL : ERROR_LEVEL,
291
"%s: unknown variable '%s'",
292
my_progname, cur_arg);
293
if (!option_is_loose)
294
return EXIT_UNKNOWN_VARIABLE;
298
my_getopt_error_reporter(option_is_loose ?
299
WARNING_LEVEL : ERROR_LEVEL,
300
"%s: unknown option '--%s'",
301
my_progname, cur_arg);
302
if (!option_is_loose)
303
return EXIT_UNKNOWN_OPTION;
316
my_getopt_error_reporter(ERROR_LEVEL,
317
"%s: variable prefix '%s' is not unique",
318
my_progname, opt_str);
319
return EXIT_VAR_PREFIX_NOT_UNIQUE;
323
my_getopt_error_reporter(ERROR_LEVEL,
324
"%s: ambiguous option '--%s' (%s, %s)",
325
my_progname, opt_str, prev_found,
327
return EXIT_AMBIGUOUS_OPTION;
330
if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
333
_("%s: %s: Option '%s' used, but is disabled\n"), my_progname,
334
option_is_loose ? _("WARNING") : _("ERROR"), opt_str);
340
return EXIT_OPTION_DISABLED;
342
if (must_be_var && (optp->var_type & GET_TYPE_MASK) == GET_NO_ARG)
344
my_getopt_error_reporter(ERROR_LEVEL,
345
"%s: option '%s' cannot take an argument",
346
my_progname, optp->name);
347
return EXIT_NO_ARGUMENT_ALLOWED;
349
value= optp->var_type & GET_ASK_ADDR ?
350
(*getopt_get_addr)(key_name, (uint32_t) strlen(key_name), optp) : optp->value;
352
if (optp->arg_type == NO_ARG)
354
if (optend && (optp->var_type & GET_TYPE_MASK) != GET_BOOL)
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
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL)
364
Set bool to 1 if no argument or if the user has used
365
--enable-'option-name'.
366
*optend was set to '0' if one used --disable-option
369
if (!optend || *optend == '1' ||
370
!my_strcasecmp(&my_charset_utf8_general_ci, optend, "true"))
371
*((bool*) value)= (bool) 1;
372
else if (*optend == '0' ||
373
!my_strcasecmp(&my_charset_utf8_general_ci, optend, "false"))
374
*((bool*) value)= (bool) 0;
377
my_getopt_error_reporter(WARNING_LEVEL,
378
"%s: ignoring option '--%s' due to \
380
my_progname, optp->name, optend);
383
get_one_option(optp->id, optp,
385
(char*) "1" : disabled_my_option);
390
else if (optp->arg_type == OPT_ARG &&
391
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
393
if (optend == disabled_my_option)
394
*((bool*) value)= (bool) 0;
397
if (!optend) /* No argument -> enable option */
398
*((bool*) value)= (bool) 1;
403
else if (optp->arg_type == REQUIRED_ARG && !optend)
405
/* Check if there are more arguments after this one */
408
my_getopt_error_reporter(ERROR_LEVEL,
409
"%s: option '--%s' requires an argument",
410
my_progname, optp->name);
411
return EXIT_ARGUMENT_REQUIRED;
419
else /* must be short option */
421
for (optend= cur_arg; *optend; optend++)
424
for (optp= longopts; optp->id; optp++)
426
if (optp->id == (int) (unsigned char) *optend)
428
/* Option recognized. Find next what to do with it */
430
if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
433
_("%s: ERROR: Option '-%c' used, but is disabled\n"),
434
my_progname, optp->id);
435
return EXIT_OPTION_DISABLED;
437
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL &&
438
optp->arg_type == NO_ARG)
440
*((bool*) optp->value)= (bool) 1;
441
get_one_option(optp->id, optp, argument);
444
else if (optp->arg_type == REQUIRED_ARG ||
445
optp->arg_type == OPT_ARG)
449
/* The rest of the option is option argument */
450
argument= optend + 1;
451
/* This is in effect a jump out of the outer loop */
456
if (optp->arg_type == OPT_ARG)
458
if (optp->var_type == GET_BOOL)
459
*((bool*) optp->value)= (bool) 1;
460
get_one_option(optp->id, optp, argument);
463
/* Check if there are more arguments after this one */
466
my_getopt_error_reporter(ERROR_LEVEL,
467
"%s: option '-%c' requires an argument",
468
my_progname, optp->id);
469
return EXIT_ARGUMENT_REQUIRED;
473
/* the other loop will break, because *optend + 1 == 0 */
476
if ((error= setval(optp, optp->value, argument,
479
my_getopt_error_reporter(ERROR_LEVEL,
480
"%s: Error while setting value '%s' to '%s'",
481
my_progname, argument, optp->name);
484
get_one_option(optp->id, optp, argument);
490
my_getopt_error_reporter(ERROR_LEVEL,
491
"%s: unknown option '-%c'",
492
my_progname, *optend);
493
return EXIT_UNKNOWN_OPTION;
496
(*argc)--; /* option handled (short), decrease argument count */
499
if ((error= setval(optp, value, argument, set_maximum_value)))
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);
508
(*argc)--; /* option handled (short or long), decrease argument count */
510
else /* non-option found */
511
(*argv)[argvpos++]= cur_arg;
514
Destroy the first, already handled option, so that programs that look
515
for arguments in 'argv', without checking 'argc', know when to stop.
516
Items in argv, before the destroyed one, are all non-option -arguments
517
to the program, yet to be (possibly) handled.
525
function: check_struct_option
527
Arguments: Current argument under processing from argv and a variable
528
where to store the possible key name.
530
Return value: In case option is a struct option, returns a pointer to
531
the current argument at the position where the struct option (key_name)
532
ends, the next character after the dot. In case argument is not a struct
533
option, returns a pointer to the argument.
535
key_name will hold the name of the key, or 0 if not found.
538
static char *check_struct_option(char *cur_arg, char *key_name)
542
ptr= strrchr(cur_arg + 1, '.'); /* Skip the first character */
543
end= strrchr(cur_arg, '=');
546
If the first dot is after an equal sign, then it is part
547
of a variable value and the option is not a struct option.
548
Also, if the last character in the string before the ending
549
NULL, or the character right before equal sign is the first
550
dot found, the option is not a struct option.
552
if ((ptr != NULL) && (end != NULL) && (end - ptr > 1))
554
uint32_t len= (uint32_t) (ptr - cur_arg);
555
set_if_smaller(len, (uint32_t)FN_REFLEN-1);
556
strncpy(key_name, cur_arg, len);
566
Arguments: opts, argument
567
Will set the option value to given value
570
static int setval(const struct my_option *opts, char **value, char *argument,
571
bool set_maximum_value)
575
if (value && argument)
577
char* *result_pos= ((set_maximum_value) ?
578
opts->u_max_value : value);
581
return EXIT_NO_PTR_TO_VARIABLE;
583
switch ((opts->var_type & GET_TYPE_MASK)) {
584
case GET_BOOL: /* If argument differs from 0, enable option, else disable */
585
*((bool*) result_pos)= (bool) atoi(argument) != 0;
588
*((int32_t*) result_pos)= (int) getopt_ll(argument, opts, &err);
592
*((uint32_t*) result_pos)= (uint32_t) getopt_ull(argument, opts, &err);
594
case GET_ULONG_IS_FAIL:
595
*((ulong*) result_pos)= (ulong) getopt_ull(argument, opts, &err);
598
*((long*) result_pos)= (long) getopt_ll(argument, opts, &err);
601
*((int64_t*) result_pos)= getopt_ll(argument, opts, &err);
605
*((uint64_t*) result_pos)= getopt_ull(argument, opts, &err);
608
*((size_t*) result_pos)= getopt_size(argument, opts, &err);
611
*((double*) result_pos)= getopt_double(argument, opts, &err);
614
*((char**) result_pos)= argument;
617
if ((*((char**) result_pos)))
618
free((*(char**) result_pos));
619
if (!(*((char**) result_pos)= strdup(argument)))
620
return EXIT_OUT_OF_MEMORY;
623
if (((*(int*)result_pos)= find_type(argument, opts->typelib, 2) - 1) < 0)
624
return EXIT_ARGUMENT_INVALID;
627
*((uint64_t*)result_pos)= find_typeset(argument, opts->typelib, &err);
629
return EXIT_ARGUMENT_INVALID;
631
default: /* dummy default to avoid compiler warnings */
635
return EXIT_UNKNOWN_SUFFIX;
646
optpat Prefix of option to find (with - or _)
647
length Length of optpat
649
ffname Place for pointer to first found name
652
Go through all options in the my_option struct. Return number
653
of options found that match the pattern and in the argument
654
list the option found, if any. In case of ambiguous option, store
655
the name in ffname argument
658
0 No matching options
659
# Number of matching options
660
ffname points to first matching option
663
static int findopt(char *optpat, uint32_t length,
664
const struct my_option **opt_res,
668
struct my_option *opt= (struct my_option *) *opt_res;
670
for (count= 0; opt->name; opt++)
672
if (!getopt_compare_strings(opt->name, optpat, length)) /* match found */
675
if (!opt->name[length]) /* Exact match */
680
*ffname= (char *) opt->name; /* We only need to know one prev */
682
else if (strcmp(*ffname, opt->name))
685
The above test is to not count same option twice
686
(see mysql.cc, option "help")
697
function: compare_strings
699
Works like strncmp, other than 1.) considers '-' and '_' the same.
700
2.) Returns -1 if strings differ, 0 if they are equal
703
bool getopt_compare_strings(register const char *s, register const char *t,
706
char const *end= s + length;
707
for (;s != end ; s++, t++)
709
if ((*s != '-' ? *s : '_') != (*t != '-' ? *t : '_'))
716
function: eval_num_suffix
718
Transforms a number with a suffix to real number. Suffix can
719
be k|K for kilo, m|M for mega or g|G for giga.
722
static int64_t eval_num_suffix(char *argument, int *error, char *option_name)
729
num= strtoll(argument, &endchar, 10);
732
my_getopt_error_reporter(ERROR_LEVEL,
733
"Incorrect integer value: '%s'", argument);
737
if (*endchar == 'k' || *endchar == 'K')
739
else if (*endchar == 'm' || *endchar == 'M')
741
else if (*endchar == 'g' || *endchar == 'G')
742
num*= 1024L * 1024L * 1024L;
746
_("Unknown suffix '%c' used for variable '%s' (value '%s')\n"),
747
*endchar, option_name, argument);
757
Evaluates and returns the value that user gave as an argument
758
to a variable. Recognizes (case insensitive) K as KILO, M as MEGA
759
and G as GIGA bytes. Some values must be in certain blocks, as
760
defined in the given my_option struct, this function will check
761
that those values are honored.
762
In case of an error, set error value in *err.
765
static int64_t getopt_ll(char *arg, const struct my_option *optp, int *err)
767
int64_t num=eval_num_suffix(arg, err, (char*) optp->name);
768
return getopt_ll_limit_value(num, optp, NULL);
772
function: getopt_ll_limit_value
774
Applies min/max/block_size to a numeric value of an option.
775
Returns "fixed" value.
778
int64_t getopt_ll_limit_value(int64_t num, const struct my_option *optp,
782
bool adjusted= false;
783
char buf1[255], buf2[255];
784
uint64_t block_size= (optp->block_size ? (uint64_t) optp->block_size : 1L);
786
if (num > 0 && ((uint64_t) num > (uint64_t) optp->max_value) &&
787
optp->max_value) /* if max value is not set -> no upper limit */
789
num= (uint64_t) optp->max_value;
793
switch ((optp->var_type & GET_TYPE_MASK)) {
795
if (num > (int64_t) INT_MAX)
797
num= ((int64_t) INT_MAX);
802
if (num > (int64_t) INT32_MAX)
804
num= ((int64_t) INT32_MAX);
809
assert((optp->var_type & GET_TYPE_MASK) == GET_LL);
813
num= ((num - optp->sub_size) / block_size);
814
num= (int64_t) (num * block_size);
816
if (num < optp->min_value)
818
num= optp->min_value;
825
my_getopt_error_reporter(WARNING_LEVEL,
826
"option '%s': signed value %s adjusted to %s",
827
optp->name, llstr(old, buf1), llstr(num, buf2));
834
This is the same as getopt_ll, but is meant for uint64_t
838
static uint64_t getopt_ull(char *arg, const struct my_option *optp, int *err)
840
uint64_t num= eval_num_suffix(arg, err, (char*) optp->name);
841
return getopt_ull_limit_value(num, optp, NULL);
845
static size_t getopt_size(char *arg, const struct my_option *optp, int *err)
847
return (size_t)getopt_ull(arg, optp, err);
852
uint64_t getopt_ull_limit_value(uint64_t num, const struct my_option *optp,
855
bool adjusted= false;
857
char buf1[255], buf2[255];
859
if ((uint64_t) num > (uint64_t) optp->max_value &&
860
optp->max_value) /* if max value is not set -> no upper limit */
862
num= (uint64_t) optp->max_value;
866
switch ((optp->var_type & GET_TYPE_MASK)) {
868
if (num > (uint64_t) UINT_MAX)
870
num= ((uint64_t) UINT_MAX);
875
case GET_ULONG_IS_FAIL:
876
if (num > (uint64_t) UINT32_MAX)
878
num= ((uint64_t) UINT32_MAX);
883
if (num > (uint64_t) SIZE_MAX)
885
num= ((uint64_t) SIZE_MAX);
890
assert(((optp->var_type & GET_TYPE_MASK) == GET_ULL)
891
|| ((optp->var_type & GET_TYPE_MASK) == GET_UINT64));
895
if (optp->block_size > 1)
897
num/= (uint64_t) optp->block_size;
898
num*= (uint64_t) optp->block_size;
901
if (num < (uint64_t) optp->min_value)
903
num= (uint64_t) optp->min_value;
910
my_getopt_error_reporter(WARNING_LEVEL,
911
"option '%s': unsigned value %s adjusted to %s",
912
optp->name, ullstr(old, buf1), ullstr(num, buf2));
919
Get double value withing ranges
921
Evaluates and returns the value that user gave as an argument to a variable.
926
In case of an error, prints an error message and sets *err to
927
EXIT_ARGUMENT_INVALID. Otherwise err is not touched
930
static double getopt_double(char *arg, const struct my_option *optp, int *err)
934
char *end= arg + 1000; /* Big enough as *arg is \0 terminated */
935
num= my_strtod(arg, &end, &error);
936
if (end[0] != 0 || error)
939
_("%s: ERROR: Invalid decimal value for option '%s'\n"),
940
my_progname, optp->name);
941
*err= EXIT_ARGUMENT_INVALID;
944
if (optp->max_value && num > (double) optp->max_value)
945
num= (double) optp->max_value;
946
return max(num, (double) optp->min_value);
950
Init one value to it's default values
954
option Option to initialize
955
value Pointer to variable
958
static void init_one_value(const struct my_option *option, char** variable,
961
switch ((option->var_type & GET_TYPE_MASK)) {
963
*((bool*) variable)= (bool) value;
966
*((int*) variable)= (int) value;
970
*((uint*) variable)= (uint32_t) value;
973
*((long*) variable)= (long) value;
976
*((uint32_t*) variable)= (uint32_t) value;
978
case GET_ULONG_IS_FAIL:
979
*((ulong*) variable)= (ulong) value;
982
*((int64_t*) variable)= (int64_t) value;
985
*((size_t*) variable)= (size_t) value;
990
*((uint64_t*) variable)= (uint64_t) value;
993
*((double*) variable)= (double) value;
997
Do not clear variable value if it has no default value.
998
The default value may already be set.
999
NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
1000
so that the value has the same size as a pointer.
1002
if ((char*) (intptr_t) value)
1003
*((char**) variable)= (char*) (intptr_t) value;
1007
Do not clear variable value if it has no default value.
1008
The default value may already be set.
1009
NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
1010
so that the value has the same size as a pointer.
1012
if ((char*) (intptr_t) value)
1014
free((*(char**) variable));
1015
char *tmpptr= strdup((char *) (intptr_t) value);
1017
*((char**) variable)= tmpptr;
1020
default: /* dummy default to avoid compiler warnings */
1028
Init one value to it's default values
1032
option Option to initialize
1033
value Pointer to variable
1036
static void fini_one_value(const struct my_option *option, char **variable,
1039
switch ((option->var_type & GET_TYPE_MASK)) {
1041
free((*(char**) variable));
1042
*((char**) variable)= NULL;
1044
default: /* dummy default to avoid compiler warnings */
1051
void my_cleanup_options(const struct my_option *options)
1053
init_variables(options, fini_one_value);
1058
initialize all variables to their default values
1062
options Array of options
1065
We will initialize the value that is pointed to by options->value.
1066
If the value is of type GET_ASK_ADDR, we will also ask for the address
1067
for a value and initialize.
1070
static void init_variables(const struct my_option *options,
1071
init_func_p init_one_value)
1073
for (; options->name; options++)
1077
We must set u_max_value first as for some variables
1078
options->u_max_value == options->value and in this case we want to
1079
set the value to default value.
1081
if (options->u_max_value)
1082
init_one_value(options, options->u_max_value, options->max_value);
1084
init_one_value(options, options->value, options->def_value);
1085
if (options->var_type & GET_ASK_ADDR &&
1086
(variable= (*getopt_get_addr)("", 0, options)))
1087
init_one_value(options, variable, options->def_value);
1094
function: my_print_options
1096
Print help for all options and variables.
1099
void my_print_help(const struct my_option *options)
1101
uint32_t col, name_space= 22, comment_space= 57;
1102
const char *line_end;
1103
const struct my_option *optp;
1105
for (optp= options; optp->id; optp++)
1109
printf(" -%c%s", optp->id, strlen(optp->name) ? ", " : " ");
1117
if (strlen(optp->name))
1119
printf("--%s", optp->name);
1120
col+= 2 + (uint32_t) strlen(optp->name);
1121
if ((optp->var_type & GET_TYPE_MASK) == GET_STR ||
1122
(optp->var_type & GET_TYPE_MASK) == GET_STR_ALLOC)
1124
printf("%s=name%s ", optp->arg_type == OPT_ARG ? "[" : "",
1125
optp->arg_type == OPT_ARG ? "]" : "");
1126
col+= (optp->arg_type == OPT_ARG) ? 8 : 6;
1128
else if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG ||
1129
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
1136
printf("%s=#%s ", optp->arg_type == OPT_ARG ? "[" : "",
1137
optp->arg_type == OPT_ARG ? "]" : "");
1138
col+= (optp->arg_type == OPT_ARG) ? 5 : 3;
1140
if (col > name_space && optp->comment && *optp->comment)
1146
for (; col < name_space; col++)
1148
if (optp->comment && *optp->comment)
1150
const char *comment= _(optp->comment), *end= strchr(comment, '\0');
1152
while ((uint32_t) (end - comment) > comment_space)
1154
for (line_end= comment + comment_space; *line_end != ' '; line_end--)
1156
for (; comment != line_end; comment++)
1158
comment++; /* skip the space, as a newline will take it's place now */
1160
for (col= 0; col < name_space; col++)
1163
printf("%s", comment);
1166
if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG ||
1167
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
1169
if (optp->def_value != 0)
1171
printf(_("%*s(Defaults to on; use --skip-%s to disable.)\n"), name_space, "", optp->name);
1179
function: my_print_options
1184
void my_print_variables(const struct my_option *options)
1186
uint32_t name_space= 34, length, nr;
1187
uint64_t bit, llvalue;
1189
const struct my_option *optp;
1191
printf(_("\nVariables (--variable-name=value)\n"
1192
"and boolean options {false|true} Value (after reading options)\n"
1193
"--------------------------------- -----------------------------\n"));
1194
for (optp= options; optp->id; optp++)
1196
char* *value= (optp->var_type & GET_ASK_ADDR ?
1197
(*getopt_get_addr)("", 0, optp) : optp->value);
1200
printf("%s ", optp->name);
1201
length= (uint32_t) strlen(optp->name)+1;
1202
for (; length < name_space; length++)
1204
switch ((optp->var_type & GET_TYPE_MASK)) {
1206
if (!(llvalue= *(uint64_t*) value))
1207
printf("%s\n", _("(No default value)"));
1209
for (nr= 0, bit= 1; llvalue && nr < optp->typelib->count; nr++, bit<<=1)
1211
if (!(bit & llvalue))
1214
printf( llvalue ? "%s," : "%s\n", get_type(optp->typelib, nr));
1218
printf("%s\n", get_type(optp->typelib, *(uint*) value));
1221
case GET_STR_ALLOC: /* fall through */
1222
printf("%s\n", *((char**) value) ? *((char**) value) :
1223
_("(No default value)"));
1226
printf("%s\n", *((bool*) value) ? _("true") : _("false"));
1229
printf("%d\n", *((int*) value));
1232
printf("%d\n", *((uint*) value));
1235
printf("%ld\n", *((long*) value));
1238
printf("%u\n", *((uint32_t*) value));
1240
case GET_ULONG_IS_FAIL:
1241
printf("%lu\n", *((ulong*) value));
1244
int64_t2str((uint64_t)(*(size_t*)value), buff, 10);
1245
printf("%s\n", buff);
1248
printf("%s\n", llstr(*((int64_t*) value), buff));
1252
int64_t2str(*((uint64_t*) value), buff, 10);
1253
printf("%s\n", buff);
1256
printf("%g\n", *(double*) value);
1259
printf(_("(Disabled)\n"));