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
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. 0 means that
71
my_getopt will not print error messages, but the client should do
75
bool my_getopt_print_errors= 1;
78
This is a flag that can be set in client programs. 1 means that
79
my_getopt will skip over options it does not know how to handle.
82
bool my_getopt_skip_unknown= 0;
84
void default_reporter(enum loglevel level,
85
const char *format, ...)
88
va_start(args, format);
89
if (level == WARNING_LEVEL)
90
fprintf(stderr, "%s", _("Warning: "));
91
else if (level == INFORMATION_LEVEL)
92
fprintf(stderr, "%s", _("Info: "));
93
vfprintf(stderr, format, args);
100
function: handle_options
102
Sort options; put options first, until special end of options (--), or
103
until end of argv. Parse options; check that the given option matches with
104
one of the options in struct 'my_option', return error in case of ambiguous
105
or unknown option. Check that option was given an argument if it requires
106
one. Call function 'get_one_option()' once for each option.
109
static getopt_get_addr_func getopt_get_addr;
111
void my_getopt_register_get_addr(getopt_get_addr_func func_addr)
113
getopt_get_addr= func_addr;
116
int handle_options(int *argc, char ***argv,
117
const struct my_option *longopts,
118
my_get_one_option get_one_option)
120
uint32_t opt_found, argvpos= 0, length;
121
bool end_of_options= 0, must_be_var, set_maximum_value=false,
123
char **pos, **pos_end, *optend, *prev_found=NULL,
124
*opt_str, key_name[FN_REFLEN];
125
const struct my_option *optp;
129
/* handle_options() assumes arg0 (program name) always exists */
130
assert(argc && *argc >= 1);
131
assert(argv && *argv);
132
(*argc)--; /* Skip the program name */
133
(*argv)++; /* --- || ---- */
134
init_variables(longopts, init_one_value);
136
for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++)
140
if (cur_arg[0] == '-' && cur_arg[1] && !end_of_options) /* must be opt */
144
set_maximum_value= 0;
147
cur_arg++; /* skip '-' */
148
if (*cur_arg == '-' || *cur_arg == 'O') /* check for long option, */
149
{ /* --set-variable, or -O */
154
if (!(*++cur_arg)) /* If not -Ovar=# */
156
/* the argument must be in next argv */
159
if (my_getopt_print_errors)
160
my_getopt_error_reporter(ERROR_LEVEL,
161
"%s: Option '-O' requires an argument",
163
return EXIT_ARGUMENT_REQUIRED;
169
else if (!getopt_compare_strings(cur_arg, "-set-variable", 13))
172
if (cur_arg[13] == '=')
177
if (my_getopt_print_errors)
178
my_getopt_error_reporter(ERROR_LEVEL,
179
"%s: Option '--set-variable' requires an argument",
181
return EXIT_ARGUMENT_REQUIRED;
184
else if (cur_arg[14]) /* garbage, or another option. break out */
188
/* the argument must be in next argv */
191
if (my_getopt_print_errors)
192
my_getopt_error_reporter(ERROR_LEVEL,
193
"%s: Option '--set-variable' requires an argument",
195
return EXIT_ARGUMENT_REQUIRED;
201
else if (!must_be_var)
203
if (!*++cur_arg) /* skip the double dash */
205
/* '--' means end of options, look no further */
211
opt_str= check_struct_option(cur_arg, key_name);
212
optend= strrchr(opt_str, '=');
215
length= (uint32_t) (optend - opt_str);
220
length= strlen(opt_str);
225
Find first the right option. Return error in case of an ambiguous,
229
if (!(opt_found= findopt(opt_str, length, &optp, &prev_found)))
232
Didn't find any matching option. Let's see if someone called
233
option with a special option prefix
238
must_be_var= 1; /* option is followed by an argument */
239
for (i= 0; special_opt_prefix[i]; i++)
241
if (!getopt_compare_strings(special_opt_prefix[i], opt_str,
242
special_opt_prefix_lengths[i]) &&
243
(opt_str[special_opt_prefix_lengths[i]] == '-' ||
244
opt_str[special_opt_prefix_lengths[i]] == '_'))
247
We were called with a special prefix, we can reuse opt_found
249
opt_str+= special_opt_prefix_lengths[i] + 1;
250
length-= special_opt_prefix_lengths[i] + 1;
253
if ((opt_found= findopt(opt_str, length, &optp, &prev_found)))
257
if (my_getopt_print_errors)
258
my_getopt_error_reporter(ERROR_LEVEL,
259
"%s: ambiguous option '--%s-%s' (--%s-%s)",
260
my_progname, special_opt_prefix[i],
261
cur_arg, special_opt_prefix[i],
263
return EXIT_AMBIGUOUS_OPTION;
267
case OPT_DISABLE: /* fall through */
269
double negation is actually enable again,
270
for example: --skip-option=0 -> option = true
272
optend= (optend && *optend == '0' && !(*(optend + 1))) ?
273
(char*) "1" : disabled_my_option;
276
optend= (optend && *optend == '0' && !(*(optend + 1))) ?
277
disabled_my_option : (char*) "1";
280
set_maximum_value= true;
284
break; /* break from the inner loop, main loop continues */
286
i= -1; /* restart the loop */
292
if (my_getopt_skip_unknown)
295
preserve all the components of this unknown option, this may
296
occurr when the user provides options like: "-O foo" or
297
"--set-variable foo" (note that theres a space in there)
298
Generally, these kind of options are to be avoided
301
(*argv)[argvpos++]= *first++;
302
} while (first <= pos);
307
if (my_getopt_print_errors)
308
my_getopt_error_reporter(option_is_loose ?
309
WARNING_LEVEL : ERROR_LEVEL,
310
"%s: unknown variable '%s'",
311
my_progname, cur_arg);
312
if (!option_is_loose)
313
return EXIT_UNKNOWN_VARIABLE;
317
if (my_getopt_print_errors)
318
my_getopt_error_reporter(option_is_loose ?
319
WARNING_LEVEL : ERROR_LEVEL,
320
"%s: unknown option '--%s'",
321
my_progname, cur_arg);
322
if (!option_is_loose)
323
return EXIT_UNKNOWN_OPTION;
336
if (my_getopt_print_errors)
337
my_getopt_error_reporter(ERROR_LEVEL,
338
"%s: variable prefix '%s' is not unique",
339
my_progname, opt_str);
340
return EXIT_VAR_PREFIX_NOT_UNIQUE;
344
if (my_getopt_print_errors)
345
my_getopt_error_reporter(ERROR_LEVEL,
346
"%s: ambiguous option '--%s' (%s, %s)",
347
my_progname, opt_str, prev_found,
349
return EXIT_AMBIGUOUS_OPTION;
352
if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
354
if (my_getopt_print_errors)
356
_("%s: %s: Option '%s' used, but is disabled\n"), my_progname,
357
option_is_loose ? _("WARNING") : _("ERROR"), opt_str);
363
return EXIT_OPTION_DISABLED;
365
if (must_be_var && (optp->var_type & GET_TYPE_MASK) == GET_NO_ARG)
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
value= optp->var_type & GET_ASK_ADDR ?
374
(*getopt_get_addr)(key_name, (uint32_t) strlen(key_name), optp) : optp->value;
376
if (optp->arg_type == NO_ARG)
378
if (optend && (optp->var_type & GET_TYPE_MASK) != GET_BOOL)
380
if (my_getopt_print_errors)
381
my_getopt_error_reporter(ERROR_LEVEL,
382
"%s: option '--%s' cannot take an argument",
383
my_progname, optp->name);
384
return EXIT_NO_ARGUMENT_ALLOWED;
386
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL)
389
Set bool to 1 if no argument or if the user has used
390
--enable-'option-name'.
391
*optend was set to '0' if one used --disable-option
394
if (!optend || *optend == '1' ||
395
!my_strcasecmp(&my_charset_utf8_general_ci, optend, "true"))
396
*((bool*) value)= (bool) 1;
397
else if (*optend == '0' ||
398
!my_strcasecmp(&my_charset_utf8_general_ci, optend, "false"))
399
*((bool*) value)= (bool) 0;
402
my_getopt_error_reporter(WARNING_LEVEL,
403
"%s: ignoring option '--%s' due to \
405
my_progname, optp->name, optend);
408
get_one_option(optp->id, optp,
410
(char*) "1" : disabled_my_option);
415
else if (optp->arg_type == OPT_ARG &&
416
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
418
if (optend == disabled_my_option)
419
*((bool*) value)= (bool) 0;
422
if (!optend) /* No argument -> enable option */
423
*((bool*) value)= (bool) 1;
428
else if (optp->arg_type == REQUIRED_ARG && !optend)
430
/* Check if there are more arguments after this one */
433
if (my_getopt_print_errors)
434
my_getopt_error_reporter(ERROR_LEVEL,
435
"%s: option '--%s' requires an argument",
436
my_progname, optp->name);
437
return EXIT_ARGUMENT_REQUIRED;
445
else /* must be short option */
447
for (optend= cur_arg; *optend; optend++)
450
for (optp= longopts; optp->id; optp++)
452
if (optp->id == (int) (unsigned char) *optend)
454
/* Option recognized. Find next what to do with it */
456
if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
458
if (my_getopt_print_errors)
460
_("%s: ERROR: Option '-%c' used, but is disabled\n"),
461
my_progname, optp->id);
462
return EXIT_OPTION_DISABLED;
464
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL &&
465
optp->arg_type == NO_ARG)
467
*((bool*) optp->value)= (bool) 1;
468
get_one_option(optp->id, optp, argument);
471
else if (optp->arg_type == REQUIRED_ARG ||
472
optp->arg_type == OPT_ARG)
476
/* The rest of the option is option argument */
477
argument= optend + 1;
478
/* This is in effect a jump out of the outer loop */
483
if (optp->arg_type == OPT_ARG)
485
if (optp->var_type == GET_BOOL)
486
*((bool*) optp->value)= (bool) 1;
487
get_one_option(optp->id, optp, argument);
490
/* Check if there are more arguments after this one */
493
if (my_getopt_print_errors)
494
my_getopt_error_reporter(ERROR_LEVEL,
495
"%s: option '-%c' requires an argument",
496
my_progname, optp->id);
497
return EXIT_ARGUMENT_REQUIRED;
501
/* the other loop will break, because *optend + 1 == 0 */
504
if ((error= setval(optp, optp->value, argument,
507
my_getopt_error_reporter(ERROR_LEVEL,
508
"%s: Error while setting value '%s' to '%s'",
509
my_progname, argument, optp->name);
512
get_one_option(optp->id, optp, argument);
518
if (my_getopt_print_errors)
519
my_getopt_error_reporter(ERROR_LEVEL,
520
"%s: unknown option '-%c'",
521
my_progname, *optend);
522
return EXIT_UNKNOWN_OPTION;
525
(*argc)--; /* option handled (short), decrease argument count */
528
if ((error= setval(optp, value, argument, set_maximum_value)))
530
my_getopt_error_reporter(ERROR_LEVEL,
531
"%s: Error while setting value '%s' to '%s'",
532
my_progname, argument, optp->name);
535
get_one_option(optp->id, optp, argument);
537
(*argc)--; /* option handled (short or long), decrease argument count */
539
else /* non-option found */
540
(*argv)[argvpos++]= cur_arg;
543
Destroy the first, already handled option, so that programs that look
544
for arguments in 'argv', without checking 'argc', know when to stop.
545
Items in argv, before the destroyed one, are all non-option -arguments
546
to the program, yet to be (possibly) handled.
554
function: check_struct_option
556
Arguments: Current argument under processing from argv and a variable
557
where to store the possible key name.
559
Return value: In case option is a struct option, returns a pointer to
560
the current argument at the position where the struct option (key_name)
561
ends, the next character after the dot. In case argument is not a struct
562
option, returns a pointer to the argument.
564
key_name will hold the name of the key, or 0 if not found.
567
static char *check_struct_option(char *cur_arg, char *key_name)
571
ptr= strrchr(cur_arg + 1, '.'); /* Skip the first character */
572
end= strrchr(cur_arg, '=');
575
If the first dot is after an equal sign, then it is part
576
of a variable value and the option is not a struct option.
577
Also, if the last character in the string before the ending
578
NULL, or the character right before equal sign is the first
579
dot found, the option is not a struct option.
581
if ((ptr != NULL) && (end != NULL) && (end - ptr > 1))
583
uint32_t len= (uint32_t) (ptr - cur_arg);
584
set_if_smaller(len, (uint32_t)FN_REFLEN-1);
585
strncpy(key_name, cur_arg, len);
595
Arguments: opts, argument
596
Will set the option value to given value
599
static int setval(const struct my_option *opts, char **value, char *argument,
600
bool set_maximum_value)
604
if (value && argument)
606
char* *result_pos= ((set_maximum_value) ?
607
opts->u_max_value : value);
610
return EXIT_NO_PTR_TO_VARIABLE;
612
switch ((opts->var_type & GET_TYPE_MASK)) {
613
case GET_BOOL: /* If argument differs from 0, enable option, else disable */
614
*((bool*) result_pos)= (bool) atoi(argument) != 0;
617
*((int32_t*) result_pos)= (int) getopt_ll(argument, opts, &err);
621
*((uint32_t*) result_pos)= (uint32_t) getopt_ull(argument, opts, &err);
623
case GET_ULONG_IS_FAIL:
624
*((ulong*) result_pos)= (ulong) getopt_ull(argument, opts, &err);
627
*((long*) result_pos)= (long) getopt_ll(argument, opts, &err);
630
*((int64_t*) result_pos)= getopt_ll(argument, opts, &err);
634
*((uint64_t*) result_pos)= getopt_ull(argument, opts, &err);
637
*((size_t*) result_pos)= getopt_size(argument, opts, &err);
640
*((double*) result_pos)= getopt_double(argument, opts, &err);
643
*((char**) result_pos)= argument;
646
if ((*((char**) result_pos)))
647
free((*(char**) result_pos));
648
if (!(*((char**) result_pos)= strdup(argument)))
649
return EXIT_OUT_OF_MEMORY;
652
if (((*(int*)result_pos)= find_type(argument, opts->typelib, 2) - 1) < 0)
653
return EXIT_ARGUMENT_INVALID;
656
*((uint64_t*)result_pos)= find_typeset(argument, opts->typelib, &err);
658
return EXIT_ARGUMENT_INVALID;
660
default: /* dummy default to avoid compiler warnings */
664
return EXIT_UNKNOWN_SUFFIX;
675
optpat Prefix of option to find (with - or _)
676
length Length of optpat
678
ffname Place for pointer to first found name
681
Go through all options in the my_option struct. Return number
682
of options found that match the pattern and in the argument
683
list the option found, if any. In case of ambiguous option, store
684
the name in ffname argument
687
0 No matching options
688
# Number of matching options
689
ffname points to first matching option
692
static int findopt(char *optpat, uint32_t length,
693
const struct my_option **opt_res,
697
struct my_option *opt= (struct my_option *) *opt_res;
699
for (count= 0; opt->name; opt++)
701
if (!getopt_compare_strings(opt->name, optpat, length)) /* match found */
704
if (!opt->name[length]) /* Exact match */
709
*ffname= (char *) opt->name; /* We only need to know one prev */
711
else if (strcmp(*ffname, opt->name))
714
The above test is to not count same option twice
715
(see mysql.cc, option "help")
726
function: compare_strings
728
Works like strncmp, other than 1.) considers '-' and '_' the same.
729
2.) Returns -1 if strings differ, 0 if they are equal
732
bool getopt_compare_strings(register const char *s, register const char *t,
735
char const *end= s + length;
736
for (;s != end ; s++, t++)
738
if ((*s != '-' ? *s : '_') != (*t != '-' ? *t : '_'))
745
function: eval_num_suffix
747
Transforms a number with a suffix to real number. Suffix can
748
be k|K for kilo, m|M for mega or g|G for giga.
751
static int64_t eval_num_suffix(char *argument, int *error, char *option_name)
758
num= strtoll(argument, &endchar, 10);
761
my_getopt_error_reporter(ERROR_LEVEL,
762
"Incorrect integer value: '%s'", argument);
766
if (*endchar == 'k' || *endchar == 'K')
768
else if (*endchar == 'm' || *endchar == 'M')
770
else if (*endchar == 'g' || *endchar == 'G')
771
num*= 1024L * 1024L * 1024L;
775
_("Unknown suffix '%c' used for variable '%s' (value '%s')\n"),
776
*endchar, option_name, argument);
786
Evaluates and returns the value that user gave as an argument
787
to a variable. Recognizes (case insensitive) K as KILO, M as MEGA
788
and G as GIGA bytes. Some values must be in certain blocks, as
789
defined in the given my_option struct, this function will check
790
that those values are honored.
791
In case of an error, set error value in *err.
794
static int64_t getopt_ll(char *arg, const struct my_option *optp, int *err)
796
int64_t num=eval_num_suffix(arg, err, (char*) optp->name);
797
return getopt_ll_limit_value(num, optp, NULL);
801
function: getopt_ll_limit_value
803
Applies min/max/block_size to a numeric value of an option.
804
Returns "fixed" value.
807
int64_t getopt_ll_limit_value(int64_t num, const struct my_option *optp,
811
bool adjusted= false;
812
char buf1[255], buf2[255];
813
uint64_t block_size= (optp->block_size ? (uint64_t) optp->block_size : 1L);
815
if (num > 0 && ((uint64_t) num > (uint64_t) optp->max_value) &&
816
optp->max_value) /* if max value is not set -> no upper limit */
818
num= (uint64_t) optp->max_value;
822
switch ((optp->var_type & GET_TYPE_MASK)) {
824
if (num > (int64_t) INT_MAX)
826
num= ((int64_t) INT_MAX);
831
if (num > (int64_t) INT32_MAX)
833
num= ((int64_t) INT32_MAX);
838
assert((optp->var_type & GET_TYPE_MASK) == GET_LL);
842
num= ((num - optp->sub_size) / block_size);
843
num= (int64_t) (num * block_size);
845
if (num < optp->min_value)
847
num= optp->min_value;
854
my_getopt_error_reporter(WARNING_LEVEL,
855
"option '%s': signed value %s adjusted to %s",
856
optp->name, llstr(old, buf1), llstr(num, buf2));
863
This is the same as getopt_ll, but is meant for uint64_t
867
static uint64_t getopt_ull(char *arg, const struct my_option *optp, int *err)
869
uint64_t num= eval_num_suffix(arg, err, (char*) optp->name);
870
return getopt_ull_limit_value(num, optp, NULL);
874
static size_t getopt_size(char *arg, const struct my_option *optp, int *err)
876
return (size_t)getopt_ull(arg, optp, err);
881
uint64_t getopt_ull_limit_value(uint64_t num, const struct my_option *optp,
884
bool adjusted= false;
886
char buf1[255], buf2[255];
888
if ((uint64_t) num > (uint64_t) optp->max_value &&
889
optp->max_value) /* if max value is not set -> no upper limit */
891
num= (uint64_t) optp->max_value;
895
switch ((optp->var_type & GET_TYPE_MASK)) {
897
if (num > (uint64_t) UINT_MAX)
899
num= ((uint64_t) UINT_MAX);
904
case GET_ULONG_IS_FAIL:
905
if (num > (uint64_t) UINT32_MAX)
907
num= ((uint64_t) UINT32_MAX);
912
if (num > (uint64_t) SIZE_MAX)
914
num= ((uint64_t) SIZE_MAX);
919
assert(((optp->var_type & GET_TYPE_MASK) == GET_ULL)
920
|| ((optp->var_type & GET_TYPE_MASK) == GET_UINT64));
924
if (optp->block_size > 1)
926
num/= (uint64_t) optp->block_size;
927
num*= (uint64_t) optp->block_size;
930
if (num < (uint64_t) optp->min_value)
932
num= (uint64_t) optp->min_value;
939
my_getopt_error_reporter(WARNING_LEVEL,
940
"option '%s': unsigned value %s adjusted to %s",
941
optp->name, ullstr(old, buf1), ullstr(num, buf2));
948
Get double value withing ranges
950
Evaluates and returns the value that user gave as an argument to a variable.
955
In case of an error, prints an error message and sets *err to
956
EXIT_ARGUMENT_INVALID. Otherwise err is not touched
959
static double getopt_double(char *arg, const struct my_option *optp, int *err)
963
char *end= arg + 1000; /* Big enough as *arg is \0 terminated */
964
num= my_strtod(arg, &end, &error);
965
if (end[0] != 0 || error)
968
_("%s: ERROR: Invalid decimal value for option '%s'\n"),
969
my_progname, optp->name);
970
*err= EXIT_ARGUMENT_INVALID;
973
if (optp->max_value && num > (double) optp->max_value)
974
num= (double) optp->max_value;
975
return max(num, (double) optp->min_value);
979
Init one value to it's default values
983
option Option to initialize
984
value Pointer to variable
987
static void init_one_value(const struct my_option *option, char** variable,
990
switch ((option->var_type & GET_TYPE_MASK)) {
992
*((bool*) variable)= (bool) value;
995
*((int*) variable)= (int) value;
999
*((uint*) variable)= (uint32_t) value;
1002
*((long*) variable)= (long) value;
1005
*((uint32_t*) variable)= (uint32_t) value;
1007
case GET_ULONG_IS_FAIL:
1008
*((ulong*) variable)= (ulong) value;
1011
*((int64_t*) variable)= (int64_t) value;
1014
*((size_t*) variable)= (size_t) value;
1019
*((uint64_t*) variable)= (uint64_t) value;
1022
*((double*) variable)= (double) value;
1026
Do not clear variable value if it has no default value.
1027
The default value may already be set.
1028
NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
1029
so that the value has the same size as a pointer.
1031
if ((char*) (intptr_t) value)
1032
*((char**) variable)= (char*) (intptr_t) value;
1036
Do not clear variable value if it has no default value.
1037
The default value may already be set.
1038
NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
1039
so that the value has the same size as a pointer.
1041
if ((char*) (intptr_t) value)
1043
free((*(char**) variable));
1044
char *tmpptr= strdup((char *) (intptr_t) value);
1046
*((char**) variable)= tmpptr;
1049
default: /* dummy default to avoid compiler warnings */
1057
Init one value to it's default values
1061
option Option to initialize
1062
value Pointer to variable
1065
static void fini_one_value(const struct my_option *option, char **variable,
1068
switch ((option->var_type & GET_TYPE_MASK)) {
1070
free((*(char**) variable));
1071
*((char**) variable)= NULL;
1073
default: /* dummy default to avoid compiler warnings */
1080
void my_cleanup_options(const struct my_option *options)
1082
init_variables(options, fini_one_value);
1087
initialize all variables to their default values
1091
options Array of options
1094
We will initialize the value that is pointed to by options->value.
1095
If the value is of type GET_ASK_ADDR, we will also ask for the address
1096
for a value and initialize.
1099
static void init_variables(const struct my_option *options,
1100
init_func_p init_one_value)
1102
for (; options->name; options++)
1106
We must set u_max_value first as for some variables
1107
options->u_max_value == options->value and in this case we want to
1108
set the value to default value.
1110
if (options->u_max_value)
1111
init_one_value(options, options->u_max_value, options->max_value);
1113
init_one_value(options, options->value, options->def_value);
1114
if (options->var_type & GET_ASK_ADDR &&
1115
(variable= (*getopt_get_addr)("", 0, options)))
1116
init_one_value(options, variable, options->def_value);
1123
function: my_print_options
1125
Print help for all options and variables.
1128
void my_print_help(const struct my_option *options)
1130
uint32_t col, name_space= 22, comment_space= 57;
1131
const char *line_end;
1132
const struct my_option *optp;
1134
for (optp= options; optp->id; optp++)
1138
printf(" -%c%s", optp->id, strlen(optp->name) ? ", " : " ");
1146
if (strlen(optp->name))
1148
printf("--%s", optp->name);
1149
col+= 2 + (uint32_t) strlen(optp->name);
1150
if ((optp->var_type & GET_TYPE_MASK) == GET_STR ||
1151
(optp->var_type & GET_TYPE_MASK) == GET_STR_ALLOC)
1153
printf("%s=name%s ", optp->arg_type == OPT_ARG ? "[" : "",
1154
optp->arg_type == OPT_ARG ? "]" : "");
1155
col+= (optp->arg_type == OPT_ARG) ? 8 : 6;
1157
else if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG ||
1158
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
1165
printf("%s=#%s ", optp->arg_type == OPT_ARG ? "[" : "",
1166
optp->arg_type == OPT_ARG ? "]" : "");
1167
col+= (optp->arg_type == OPT_ARG) ? 5 : 3;
1169
if (col > name_space && optp->comment && *optp->comment)
1175
for (; col < name_space; col++)
1177
if (optp->comment && *optp->comment)
1179
const char *comment= _(optp->comment), *end= strchr(comment, '\0');
1181
while ((uint32_t) (end - comment) > comment_space)
1183
for (line_end= comment + comment_space; *line_end != ' '; line_end--)
1185
for (; comment != line_end; comment++)
1187
comment++; /* skip the space, as a newline will take it's place now */
1189
for (col= 0; col < name_space; col++)
1192
printf("%s", comment);
1195
if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG ||
1196
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
1198
if (optp->def_value != 0)
1200
printf(_("%*s(Defaults to on; use --skip-%s to disable.)\n"), name_space, "", optp->name);
1208
function: my_print_options
1213
void my_print_variables(const struct my_option *options)
1215
uint32_t name_space= 34, length, nr;
1216
uint64_t bit, llvalue;
1218
const struct my_option *optp;
1220
printf(_("\nVariables (--variable-name=value)\n"
1221
"and boolean options {false|true} Value (after reading options)\n"
1222
"--------------------------------- -----------------------------\n"));
1223
for (optp= options; optp->id; optp++)
1225
char* *value= (optp->var_type & GET_ASK_ADDR ?
1226
(*getopt_get_addr)("", 0, optp) : optp->value);
1229
printf("%s ", optp->name);
1230
length= (uint32_t) strlen(optp->name)+1;
1231
for (; length < name_space; length++)
1233
switch ((optp->var_type & GET_TYPE_MASK)) {
1235
if (!(llvalue= *(uint64_t*) value))
1236
printf("%s\n", _("(No default value)"));
1238
for (nr= 0, bit= 1; llvalue && nr < optp->typelib->count; nr++, bit<<=1)
1240
if (!(bit & llvalue))
1243
printf( llvalue ? "%s," : "%s\n", get_type(optp->typelib, nr));
1247
printf("%s\n", get_type(optp->typelib, *(uint*) value));
1250
case GET_STR_ALLOC: /* fall through */
1251
printf("%s\n", *((char**) value) ? *((char**) value) :
1252
_("(No default value)"));
1255
printf("%s\n", *((bool*) value) ? _("true") : _("false"));
1258
printf("%d\n", *((int*) value));
1261
printf("%d\n", *((uint*) value));
1264
printf("%ld\n", *((long*) value));
1267
printf("%u\n", *((uint32_t*) value));
1269
case GET_ULONG_IS_FAIL:
1270
printf("%lu\n", *((ulong*) value));
1273
int64_t2str((uint64_t)(*(size_t*)value), buff, 10);
1274
printf("%s\n", buff);
1277
printf("%s\n", llstr(*((int64_t*) value), buff));
1281
int64_t2str(*((uint64_t*) value), buff, 10);
1282
printf("%s\n", buff);
1285
printf("%g\n", *(double*) value);
1288
printf(_("(Disabled)\n"));