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>
31
typedef void (*init_func_p)(const struct my_option *option, char **variable,
34
void default_reporter(enum loglevel level, const char *format, ...);
35
my_error_reporter my_getopt_error_reporter= &default_reporter;
37
static int findopt(char *optpat, uint32_t length,
38
const struct my_option **opt_res,
40
static int64_t getopt_ll(char *arg, const struct my_option *optp, int *err);
41
static uint64_t getopt_ull(char *arg, const struct my_option *optp,
43
static size_t getopt_size(char *arg, const struct my_option *optp, int *err);
44
static double getopt_double(char *arg, const struct my_option *optp, int *err);
45
static void init_variables(const struct my_option *options,
46
init_func_p init_one_value);
47
static void init_one_value(const struct my_option *option, char **variable,
49
static void fini_one_value(const struct my_option *option, char **variable,
51
static int setval(const struct my_option *opts, char* *value, char *argument,
52
bool set_maximum_value);
53
static char *check_struct_option(char *cur_arg, char *key_name);
56
The following three variables belong to same group and the number and
57
order of their arguments must correspond to each other.
59
static const char *special_opt_prefix[]=
60
{"skip", "disable", "enable", "maximum", "loose", 0};
61
static const uint32_t special_opt_prefix_lengths[]=
64
{ OPT_SKIP, OPT_DISABLE, OPT_ENABLE, OPT_MAXIMUM, OPT_LOOSE};
66
char *disabled_my_option= (char*) "0";
69
This is a flag that can be set in client programs. 0 means that
70
my_getopt will not print error messages, but the client should do
74
bool my_getopt_print_errors= 1;
77
This is a flag that can be set in client programs. 1 means that
78
my_getopt will skip over options it does not know how to handle.
81
bool my_getopt_skip_unknown= 0;
83
void default_reporter(enum loglevel level,
84
const char *format, ...)
87
va_start(args, format);
88
if (level == WARNING_LEVEL)
89
fprintf(stderr, "%s", _("Warning: "));
90
else if (level == INFORMATION_LEVEL)
91
fprintf(stderr, "%s", _("Info: "));
92
vfprintf(stderr, format, args);
99
function: handle_options
101
Sort options; put options first, until special end of options (--), or
102
until end of argv. Parse options; check that the given option matches with
103
one of the options in struct 'my_option', return error in case of ambiguous
104
or unknown option. Check that option was given an argument if it requires
105
one. Call function 'get_one_option()' once for each option.
108
static getopt_get_addr_func getopt_get_addr;
110
void my_getopt_register_get_addr(getopt_get_addr_func func_addr)
112
getopt_get_addr= func_addr;
115
int handle_options(int *argc, char ***argv,
116
const struct my_option *longopts,
117
my_get_one_option get_one_option)
119
uint32_t opt_found, argvpos= 0, length;
120
bool end_of_options= 0, must_be_var, set_maximum_value=false,
122
char **pos, **pos_end, *optend, *prev_found=NULL,
123
*opt_str, key_name[FN_REFLEN];
124
const struct my_option *optp;
128
/* handle_options() assumes arg0 (program name) always exists */
129
assert(argc && *argc >= 1);
130
assert(argv && *argv);
131
(*argc)--; /* Skip the program name */
132
(*argv)++; /* --- || ---- */
133
init_variables(longopts, init_one_value);
135
for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++)
139
if (cur_arg[0] == '-' && cur_arg[1] && !end_of_options) /* must be opt */
143
set_maximum_value= 0;
146
cur_arg++; /* skip '-' */
147
if (*cur_arg == '-' || *cur_arg == 'O') /* check for long option, */
148
{ /* --set-variable, or -O */
153
if (!(*++cur_arg)) /* If not -Ovar=# */
155
/* the argument must be in next argv */
158
if (my_getopt_print_errors)
159
my_getopt_error_reporter(ERROR_LEVEL,
160
"%s: Option '-O' requires an argument",
162
return EXIT_ARGUMENT_REQUIRED;
168
else if (!getopt_compare_strings(cur_arg, "-set-variable", 13))
171
if (cur_arg[13] == '=')
176
if (my_getopt_print_errors)
177
my_getopt_error_reporter(ERROR_LEVEL,
178
"%s: Option '--set-variable' requires an argument",
180
return EXIT_ARGUMENT_REQUIRED;
183
else if (cur_arg[14]) /* garbage, or another option. break out */
187
/* the argument must be in next argv */
190
if (my_getopt_print_errors)
191
my_getopt_error_reporter(ERROR_LEVEL,
192
"%s: Option '--set-variable' requires an argument",
194
return EXIT_ARGUMENT_REQUIRED;
200
else if (!must_be_var)
202
if (!*++cur_arg) /* skip the double dash */
204
/* '--' means end of options, look no further */
210
opt_str= check_struct_option(cur_arg, key_name);
211
optend= strrchr(opt_str, '=');
214
length= (uint32_t) (optend - opt_str);
219
length= strlen(opt_str);
224
Find first the right option. Return error in case of an ambiguous,
228
if (!(opt_found= findopt(opt_str, length, &optp, &prev_found)))
231
Didn't find any matching option. Let's see if someone called
232
option with a special option prefix
237
must_be_var= 1; /* option is followed by an argument */
238
for (i= 0; special_opt_prefix[i]; i++)
240
if (!getopt_compare_strings(special_opt_prefix[i], opt_str,
241
special_opt_prefix_lengths[i]) &&
242
(opt_str[special_opt_prefix_lengths[i]] == '-' ||
243
opt_str[special_opt_prefix_lengths[i]] == '_'))
246
We were called with a special prefix, we can reuse opt_found
248
opt_str+= special_opt_prefix_lengths[i] + 1;
249
length-= special_opt_prefix_lengths[i] + 1;
252
if ((opt_found= findopt(opt_str, length, &optp, &prev_found)))
256
if (my_getopt_print_errors)
257
my_getopt_error_reporter(ERROR_LEVEL,
258
"%s: ambiguous option '--%s-%s' (--%s-%s)",
259
my_progname, special_opt_prefix[i],
260
cur_arg, special_opt_prefix[i],
262
return EXIT_AMBIGUOUS_OPTION;
266
case OPT_DISABLE: /* fall through */
268
double negation is actually enable again,
269
for example: --skip-option=0 -> option = true
271
optend= (optend && *optend == '0' && !(*(optend + 1))) ?
272
(char*) "1" : disabled_my_option;
275
optend= (optend && *optend == '0' && !(*(optend + 1))) ?
276
disabled_my_option : (char*) "1";
279
set_maximum_value= true;
283
break; /* break from the inner loop, main loop continues */
285
i= -1; /* restart the loop */
291
if (my_getopt_skip_unknown)
294
preserve all the components of this unknown option, this may
295
occurr when the user provides options like: "-O foo" or
296
"--set-variable foo" (note that theres a space in there)
297
Generally, these kind of options are to be avoided
300
(*argv)[argvpos++]= *first++;
301
} while (first <= pos);
306
if (my_getopt_print_errors)
307
my_getopt_error_reporter(option_is_loose ?
308
WARNING_LEVEL : ERROR_LEVEL,
309
"%s: unknown variable '%s'",
310
my_progname, cur_arg);
311
if (!option_is_loose)
312
return EXIT_UNKNOWN_VARIABLE;
316
if (my_getopt_print_errors)
317
my_getopt_error_reporter(option_is_loose ?
318
WARNING_LEVEL : ERROR_LEVEL,
319
"%s: unknown option '--%s'",
320
my_progname, cur_arg);
321
if (!option_is_loose)
322
return EXIT_UNKNOWN_OPTION;
335
if (my_getopt_print_errors)
336
my_getopt_error_reporter(ERROR_LEVEL,
337
"%s: variable prefix '%s' is not unique",
338
my_progname, opt_str);
339
return EXIT_VAR_PREFIX_NOT_UNIQUE;
343
if (my_getopt_print_errors)
344
my_getopt_error_reporter(ERROR_LEVEL,
345
"%s: ambiguous option '--%s' (%s, %s)",
346
my_progname, opt_str, prev_found,
348
return EXIT_AMBIGUOUS_OPTION;
351
if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
353
if (my_getopt_print_errors)
355
_("%s: %s: Option '%s' used, but is disabled\n"), my_progname,
356
option_is_loose ? _("WARNING") : _("ERROR"), opt_str);
362
return EXIT_OPTION_DISABLED;
364
if (must_be_var && (optp->var_type & GET_TYPE_MASK) == GET_NO_ARG)
366
if (my_getopt_print_errors)
367
my_getopt_error_reporter(ERROR_LEVEL,
368
"%s: option '%s' cannot take an argument",
369
my_progname, optp->name);
370
return EXIT_NO_ARGUMENT_ALLOWED;
372
value= optp->var_type & GET_ASK_ADDR ?
373
(*getopt_get_addr)(key_name, (uint32_t) strlen(key_name), optp) : optp->value;
375
if (optp->arg_type == NO_ARG)
377
if (optend && (optp->var_type & GET_TYPE_MASK) != GET_BOOL)
379
if (my_getopt_print_errors)
380
my_getopt_error_reporter(ERROR_LEVEL,
381
"%s: option '--%s' cannot take an argument",
382
my_progname, optp->name);
383
return EXIT_NO_ARGUMENT_ALLOWED;
385
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL)
388
Set bool to 1 if no argument or if the user has used
389
--enable-'option-name'.
390
*optend was set to '0' if one used --disable-option
393
if (!optend || *optend == '1' ||
394
!my_strcasecmp(&my_charset_utf8_general_ci, optend, "true"))
395
*((bool*) value)= (bool) 1;
396
else if (*optend == '0' ||
397
!my_strcasecmp(&my_charset_utf8_general_ci, optend, "false"))
398
*((bool*) value)= (bool) 0;
401
my_getopt_error_reporter(WARNING_LEVEL,
402
"%s: ignoring option '--%s' due to \
404
my_progname, optp->name, optend);
407
get_one_option(optp->id, optp,
409
(char*) "1" : disabled_my_option);
414
else if (optp->arg_type == OPT_ARG &&
415
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
417
if (optend == disabled_my_option)
418
*((bool*) value)= (bool) 0;
421
if (!optend) /* No argument -> enable option */
422
*((bool*) value)= (bool) 1;
427
else if (optp->arg_type == REQUIRED_ARG && !optend)
429
/* Check if there are more arguments after this one */
432
if (my_getopt_print_errors)
433
my_getopt_error_reporter(ERROR_LEVEL,
434
"%s: option '--%s' requires an argument",
435
my_progname, optp->name);
436
return EXIT_ARGUMENT_REQUIRED;
444
else /* must be short option */
446
for (optend= cur_arg; *optend; optend++)
449
for (optp= longopts; optp->id; optp++)
451
if (optp->id == (int) (unsigned char) *optend)
453
/* Option recognized. Find next what to do with it */
455
if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
457
if (my_getopt_print_errors)
459
_("%s: ERROR: Option '-%c' used, but is disabled\n"),
460
my_progname, optp->id);
461
return EXIT_OPTION_DISABLED;
463
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL &&
464
optp->arg_type == NO_ARG)
466
*((bool*) optp->value)= (bool) 1;
467
get_one_option(optp->id, optp, argument);
470
else if (optp->arg_type == REQUIRED_ARG ||
471
optp->arg_type == OPT_ARG)
475
/* The rest of the option is option argument */
476
argument= optend + 1;
477
/* This is in effect a jump out of the outer loop */
482
if (optp->arg_type == OPT_ARG)
484
if (optp->var_type == GET_BOOL)
485
*((bool*) optp->value)= (bool) 1;
486
get_one_option(optp->id, optp, argument);
489
/* Check if there are more arguments after this one */
492
if (my_getopt_print_errors)
493
my_getopt_error_reporter(ERROR_LEVEL,
494
"%s: option '-%c' requires an argument",
495
my_progname, optp->id);
496
return EXIT_ARGUMENT_REQUIRED;
500
/* the other loop will break, because *optend + 1 == 0 */
503
if ((error= setval(optp, optp->value, argument,
506
my_getopt_error_reporter(ERROR_LEVEL,
507
"%s: Error while setting value '%s' to '%s'",
508
my_progname, argument, optp->name);
511
get_one_option(optp->id, optp, argument);
517
if (my_getopt_print_errors)
518
my_getopt_error_reporter(ERROR_LEVEL,
519
"%s: unknown option '-%c'",
520
my_progname, *optend);
521
return EXIT_UNKNOWN_OPTION;
524
(*argc)--; /* option handled (short), decrease argument count */
527
if ((error= setval(optp, value, argument, set_maximum_value)))
529
my_getopt_error_reporter(ERROR_LEVEL,
530
"%s: Error while setting value '%s' to '%s'",
531
my_progname, argument, optp->name);
534
get_one_option(optp->id, optp, argument);
536
(*argc)--; /* option handled (short or long), decrease argument count */
538
else /* non-option found */
539
(*argv)[argvpos++]= cur_arg;
542
Destroy the first, already handled option, so that programs that look
543
for arguments in 'argv', without checking 'argc', know when to stop.
544
Items in argv, before the destroyed one, are all non-option -arguments
545
to the program, yet to be (possibly) handled.
553
function: check_struct_option
555
Arguments: Current argument under processing from argv and a variable
556
where to store the possible key name.
558
Return value: In case option is a struct option, returns a pointer to
559
the current argument at the position where the struct option (key_name)
560
ends, the next character after the dot. In case argument is not a struct
561
option, returns a pointer to the argument.
563
key_name will hold the name of the key, or 0 if not found.
566
static char *check_struct_option(char *cur_arg, char *key_name)
570
ptr= strrchr(cur_arg + 1, '.'); /* Skip the first character */
571
end= strrchr(cur_arg, '=');
574
If the first dot is after an equal sign, then it is part
575
of a variable value and the option is not a struct option.
576
Also, if the last character in the string before the ending
577
NULL, or the character right before equal sign is the first
578
dot found, the option is not a struct option.
580
if ((ptr != NULL) && (end != NULL) && (end - ptr > 1))
582
uint32_t len= (uint32_t) (ptr - cur_arg);
583
set_if_smaller(len, (uint32_t)FN_REFLEN-1);
584
strncpy(key_name, cur_arg, len);
594
Arguments: opts, argument
595
Will set the option value to given value
598
static int setval(const struct my_option *opts, char **value, char *argument,
599
bool set_maximum_value)
603
if (value && argument)
605
char* *result_pos= ((set_maximum_value) ?
606
opts->u_max_value : value);
609
return EXIT_NO_PTR_TO_VARIABLE;
611
switch ((opts->var_type & GET_TYPE_MASK)) {
612
case GET_BOOL: /* If argument differs from 0, enable option, else disable */
613
*((bool*) result_pos)= (bool) atoi(argument) != 0;
616
*((int32_t*) result_pos)= (int) getopt_ll(argument, opts, &err);
620
*((uint32_t*) result_pos)= (uint32_t) getopt_ull(argument, opts, &err);
622
case GET_ULONG_IS_FAIL:
623
*((ulong*) result_pos)= (ulong) getopt_ull(argument, opts, &err);
626
*((long*) result_pos)= (long) getopt_ll(argument, opts, &err);
629
*((int64_t*) result_pos)= getopt_ll(argument, opts, &err);
633
*((uint64_t*) result_pos)= getopt_ull(argument, opts, &err);
636
*((size_t*) result_pos)= getopt_size(argument, opts, &err);
639
*((double*) result_pos)= getopt_double(argument, opts, &err);
642
*((char**) result_pos)= argument;
645
if ((*((char**) result_pos)))
646
free((*(char**) result_pos));
647
if (!(*((char**) result_pos)= strdup(argument)))
648
return EXIT_OUT_OF_MEMORY;
651
if (((*(int*)result_pos)= find_type(argument, opts->typelib, 2) - 1) < 0)
652
return EXIT_ARGUMENT_INVALID;
655
*((uint64_t*)result_pos)= find_typeset(argument, opts->typelib, &err);
657
return EXIT_ARGUMENT_INVALID;
659
default: /* dummy default to avoid compiler warnings */
663
return EXIT_UNKNOWN_SUFFIX;
674
optpat Prefix of option to find (with - or _)
675
length Length of optpat
677
ffname Place for pointer to first found name
680
Go through all options in the my_option struct. Return number
681
of options found that match the pattern and in the argument
682
list the option found, if any. In case of ambiguous option, store
683
the name in ffname argument
686
0 No matching options
687
# Number of matching options
688
ffname points to first matching option
691
static int findopt(char *optpat, uint32_t length,
692
const struct my_option **opt_res,
696
struct my_option *opt= (struct my_option *) *opt_res;
698
for (count= 0; opt->name; opt++)
700
if (!getopt_compare_strings(opt->name, optpat, length)) /* match found */
703
if (!opt->name[length]) /* Exact match */
708
*ffname= (char *) opt->name; /* We only need to know one prev */
710
else if (strcmp(*ffname, opt->name))
713
The above test is to not count same option twice
714
(see mysql.cc, option "help")
725
function: compare_strings
727
Works like strncmp, other than 1.) considers '-' and '_' the same.
728
2.) Returns -1 if strings differ, 0 if they are equal
731
bool getopt_compare_strings(register const char *s, register const char *t,
734
char const *end= s + length;
735
for (;s != end ; s++, t++)
737
if ((*s != '-' ? *s : '_') != (*t != '-' ? *t : '_'))
744
function: eval_num_suffix
746
Transforms a number with a suffix to real number. Suffix can
747
be k|K for kilo, m|M for mega or g|G for giga.
750
static int64_t eval_num_suffix(char *argument, int *error, char *option_name)
757
num= strtoll(argument, &endchar, 10);
760
my_getopt_error_reporter(ERROR_LEVEL,
761
"Incorrect integer value: '%s'", argument);
765
if (*endchar == 'k' || *endchar == 'K')
767
else if (*endchar == 'm' || *endchar == 'M')
769
else if (*endchar == 'g' || *endchar == 'G')
770
num*= 1024L * 1024L * 1024L;
774
_("Unknown suffix '%c' used for variable '%s' (value '%s')\n"),
775
*endchar, option_name, argument);
785
Evaluates and returns the value that user gave as an argument
786
to a variable. Recognizes (case insensitive) K as KILO, M as MEGA
787
and G as GIGA bytes. Some values must be in certain blocks, as
788
defined in the given my_option struct, this function will check
789
that those values are honored.
790
In case of an error, set error value in *err.
793
static int64_t getopt_ll(char *arg, const struct my_option *optp, int *err)
795
int64_t num=eval_num_suffix(arg, err, (char*) optp->name);
796
return getopt_ll_limit_value(num, optp, NULL);
800
function: getopt_ll_limit_value
802
Applies min/max/block_size to a numeric value of an option.
803
Returns "fixed" value.
806
int64_t getopt_ll_limit_value(int64_t num, const struct my_option *optp,
810
bool adjusted= false;
811
char buf1[255], buf2[255];
812
uint64_t block_size= (optp->block_size ? (uint64_t) optp->block_size : 1L);
814
if (num > 0 && ((uint64_t) num > (uint64_t) optp->max_value) &&
815
optp->max_value) /* if max value is not set -> no upper limit */
817
num= (uint64_t) optp->max_value;
821
switch ((optp->var_type & GET_TYPE_MASK)) {
823
if (num > (int64_t) INT_MAX)
825
num= ((int64_t) INT_MAX);
830
if (num > (int64_t) INT32_MAX)
832
num= ((int64_t) INT32_MAX);
837
assert((optp->var_type & GET_TYPE_MASK) == GET_LL);
841
num= ((num - optp->sub_size) / block_size);
842
num= (int64_t) (num * block_size);
844
if (num < optp->min_value)
846
num= optp->min_value;
853
my_getopt_error_reporter(WARNING_LEVEL,
854
"option '%s': signed value %s adjusted to %s",
855
optp->name, llstr(old, buf1), llstr(num, buf2));
862
This is the same as getopt_ll, but is meant for uint64_t
866
static uint64_t getopt_ull(char *arg, const struct my_option *optp, int *err)
868
uint64_t num= eval_num_suffix(arg, err, (char*) optp->name);
869
return getopt_ull_limit_value(num, optp, NULL);
873
static size_t getopt_size(char *arg, const struct my_option *optp, int *err)
875
return (size_t)getopt_ull(arg, optp, err);
880
uint64_t getopt_ull_limit_value(uint64_t num, const struct my_option *optp,
883
bool adjusted= false;
885
char buf1[255], buf2[255];
887
if ((uint64_t) num > (uint64_t) optp->max_value &&
888
optp->max_value) /* if max value is not set -> no upper limit */
890
num= (uint64_t) optp->max_value;
894
switch ((optp->var_type & GET_TYPE_MASK)) {
896
if (num > (uint64_t) UINT_MAX)
898
num= ((uint64_t) UINT_MAX);
903
case GET_ULONG_IS_FAIL:
904
if (num > (uint64_t) UINT32_MAX)
906
num= ((uint64_t) UINT32_MAX);
911
if (num > (uint64_t) SIZE_MAX)
913
num= ((uint64_t) SIZE_MAX);
918
assert(((optp->var_type & GET_TYPE_MASK) == GET_ULL)
919
|| ((optp->var_type & GET_TYPE_MASK) == GET_UINT64));
923
if (optp->block_size > 1)
925
num/= (uint64_t) optp->block_size;
926
num*= (uint64_t) optp->block_size;
929
if (num < (uint64_t) optp->min_value)
931
num= (uint64_t) optp->min_value;
938
my_getopt_error_reporter(WARNING_LEVEL,
939
"option '%s': unsigned value %s adjusted to %s",
940
optp->name, ullstr(old, buf1), ullstr(num, buf2));
947
Get double value withing ranges
949
Evaluates and returns the value that user gave as an argument to a variable.
954
In case of an error, prints an error message and sets *err to
955
EXIT_ARGUMENT_INVALID. Otherwise err is not touched
958
static double getopt_double(char *arg, const struct my_option *optp, int *err)
962
char *end= arg + 1000; /* Big enough as *arg is \0 terminated */
963
num= my_strtod(arg, &end, &error);
964
if (end[0] != 0 || error)
967
_("%s: ERROR: Invalid decimal value for option '%s'\n"),
968
my_progname, optp->name);
969
*err= EXIT_ARGUMENT_INVALID;
972
if (optp->max_value && num > (double) optp->max_value)
973
num= (double) optp->max_value;
974
return cmax(num, (double) optp->min_value);
978
Init one value to it's default values
982
option Option to initialize
983
value Pointer to variable
986
static void init_one_value(const struct my_option *option, char** variable,
989
switch ((option->var_type & GET_TYPE_MASK)) {
991
*((bool*) variable)= (bool) value;
994
*((int*) variable)= (int) value;
998
*((uint*) variable)= (uint32_t) value;
1001
*((long*) variable)= (long) value;
1004
*((uint32_t*) variable)= (uint32_t) value;
1006
case GET_ULONG_IS_FAIL:
1007
*((ulong*) variable)= (ulong) value;
1010
*((int64_t*) variable)= (int64_t) value;
1013
*((size_t*) variable)= (size_t) value;
1018
*((uint64_t*) variable)= (uint64_t) value;
1021
*((double*) variable)= (double) value;
1025
Do not clear variable value if it has no default value.
1026
The default value may already be set.
1027
NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
1028
so that the value has the same size as a pointer.
1030
if ((char*) (intptr_t) value)
1031
*((char**) variable)= (char*) (intptr_t) value;
1035
Do not clear variable value if it has no default value.
1036
The default value may already be set.
1037
NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
1038
so that the value has the same size as a pointer.
1040
if ((char*) (intptr_t) value)
1042
free((*(char**) variable));
1043
char *tmpptr= strdup((char *) (intptr_t) value);
1045
*((char**) variable)= tmpptr;
1048
default: /* dummy default to avoid compiler warnings */
1056
Init one value to it's default values
1060
option Option to initialize
1061
value Pointer to variable
1064
static void fini_one_value(const struct my_option *option, char **variable,
1067
switch ((option->var_type & GET_TYPE_MASK)) {
1069
free((*(char**) variable));
1070
*((char**) variable)= NULL;
1072
default: /* dummy default to avoid compiler warnings */
1079
void my_cleanup_options(const struct my_option *options)
1081
init_variables(options, fini_one_value);
1086
initialize all variables to their default values
1090
options Array of options
1093
We will initialize the value that is pointed to by options->value.
1094
If the value is of type GET_ASK_ADDR, we will also ask for the address
1095
for a value and initialize.
1098
static void init_variables(const struct my_option *options,
1099
init_func_p init_one_value)
1101
for (; options->name; options++)
1105
We must set u_max_value first as for some variables
1106
options->u_max_value == options->value and in this case we want to
1107
set the value to default value.
1109
if (options->u_max_value)
1110
init_one_value(options, options->u_max_value, options->max_value);
1112
init_one_value(options, options->value, options->def_value);
1113
if (options->var_type & GET_ASK_ADDR &&
1114
(variable= (*getopt_get_addr)("", 0, options)))
1115
init_one_value(options, variable, options->def_value);
1122
function: my_print_options
1124
Print help for all options and variables.
1127
void my_print_help(const struct my_option *options)
1129
uint32_t col, name_space= 22, comment_space= 57;
1130
const char *line_end;
1131
const struct my_option *optp;
1133
for (optp= options; optp->id; optp++)
1137
printf(" -%c%s", optp->id, strlen(optp->name) ? ", " : " ");
1145
if (strlen(optp->name))
1147
printf("--%s", optp->name);
1148
col+= 2 + (uint32_t) strlen(optp->name);
1149
if ((optp->var_type & GET_TYPE_MASK) == GET_STR ||
1150
(optp->var_type & GET_TYPE_MASK) == GET_STR_ALLOC)
1152
printf("%s=name%s ", optp->arg_type == OPT_ARG ? "[" : "",
1153
optp->arg_type == OPT_ARG ? "]" : "");
1154
col+= (optp->arg_type == OPT_ARG) ? 8 : 6;
1156
else if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG ||
1157
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
1164
printf("%s=#%s ", optp->arg_type == OPT_ARG ? "[" : "",
1165
optp->arg_type == OPT_ARG ? "]" : "");
1166
col+= (optp->arg_type == OPT_ARG) ? 5 : 3;
1168
if (col > name_space && optp->comment && *optp->comment)
1174
for (; col < name_space; col++)
1176
if (optp->comment && *optp->comment)
1178
const char *comment= _(optp->comment), *end= strchr(comment, '\0');
1180
while ((uint32_t) (end - comment) > comment_space)
1182
for (line_end= comment + comment_space; *line_end != ' '; line_end--)
1184
for (; comment != line_end; comment++)
1186
comment++; /* skip the space, as a newline will take it's place now */
1188
for (col= 0; col < name_space; col++)
1191
printf("%s", comment);
1194
if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG ||
1195
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
1197
if (optp->def_value != 0)
1199
printf(_("%*s(Defaults to on; use --skip-%s to disable.)\n"), name_space, "", optp->name);
1207
function: my_print_options
1212
void my_print_variables(const struct my_option *options)
1214
uint32_t name_space= 34, length, nr;
1215
uint64_t bit, llvalue;
1217
const struct my_option *optp;
1219
printf(_("\nVariables (--variable-name=value)\n"
1220
"and boolean options {false|true} Value (after reading options)\n"
1221
"--------------------------------- -----------------------------\n"));
1222
for (optp= options; optp->id; optp++)
1224
char* *value= (optp->var_type & GET_ASK_ADDR ?
1225
(*getopt_get_addr)("", 0, optp) : optp->value);
1228
printf("%s ", optp->name);
1229
length= (uint32_t) strlen(optp->name)+1;
1230
for (; length < name_space; length++)
1232
switch ((optp->var_type & GET_TYPE_MASK)) {
1234
if (!(llvalue= *(uint64_t*) value))
1235
printf("%s\n", _("(No default value)"));
1237
for (nr= 0, bit= 1; llvalue && nr < optp->typelib->count; nr++, bit<<=1)
1239
if (!(bit & llvalue))
1242
printf( llvalue ? "%s," : "%s\n", get_type(optp->typelib, nr));
1246
printf("%s\n", get_type(optp->typelib, *(uint*) value));
1249
case GET_STR_ALLOC: /* fall through */
1250
printf("%s\n", *((char**) value) ? *((char**) value) :
1251
_("(No default value)"));
1254
printf("%s\n", *((bool*) value) ? _("true") : _("false"));
1257
printf("%d\n", *((int*) value));
1260
printf("%d\n", *((uint*) value));
1263
printf("%ld\n", *((long*) value));
1266
printf("%u\n", *((uint32_t*) value));
1268
case GET_ULONG_IS_FAIL:
1269
printf("%lu\n", *((ulong*) value));
1272
int64_t2str((uint64_t)(*(size_t*)value), buff, 10);
1273
printf("%s\n", buff);
1276
printf("%s\n", llstr(*((int64_t*) value), buff));
1280
int64_t2str(*((uint64_t*) value), buff, 10);
1281
printf("%s\n", buff);
1284
printf("%g\n", *(double*) value);
1287
printf(_("(Disabled)\n"));