21
21
#include <my_getopt.h>
24
typedef void (*init_func_p)(const struct my_option *option, char **variable,
24
typedef void (*init_func_p)(const struct my_option *option, uchar* *variable,
27
27
static void default_reporter(enum loglevel level, const char *format, ...);
28
28
my_error_reporter my_getopt_error_reporter= &default_reporter;
30
30
static int findopt(char *optpat, uint length,
31
31
const struct my_option **opt_res,
33
static int64_t getopt_ll(char *arg, const struct my_option *optp, int *err);
34
static uint64_t getopt_ull(char *arg, const struct my_option *optp,
33
static longlong getopt_ll(char *arg, const struct my_option *optp, int *err);
34
static ulonglong getopt_ull(char *arg, const struct my_option *optp,
36
36
static double getopt_double(char *arg, const struct my_option *optp, int *err);
37
37
static void init_variables(const struct my_option *options,
38
38
init_func_p init_one_value);
39
static void init_one_value(const struct my_option *option, char **variable,
41
static void fini_one_value(const struct my_option *option, char **variable,
43
static int setval(const struct my_option *opts, char* *value, char *argument,
44
bool set_maximum_value);
39
static void init_one_value(const struct my_option *option, uchar* *variable,
41
static void fini_one_value(const struct my_option *option, uchar* *variable,
43
static int setval(const struct my_option *opts, uchar* *value, char *argument,
44
my_bool set_maximum_value);
45
45
static char *check_struct_option(char *cur_arg, char *key_name);
66
bool my_getopt_print_errors= 1;
66
my_bool my_getopt_print_errors= 1;
69
69
This is a flag that can be set in client programs. 1 means that
70
70
my_getopt will skip over options it does not know how to handle.
73
bool my_getopt_skip_unknown= 0;
73
my_bool my_getopt_skip_unknown= 0;
75
75
static void default_reporter(enum loglevel level,
76
76
const char *format, ...)
97
97
one. Call function 'get_one_option()' once for each option.
100
static char** (*getopt_get_addr)(const char *, uint, const struct my_option *);
100
static uchar** (*getopt_get_addr)(const char *, uint, const struct my_option *);
102
void my_getopt_register_get_addr(char** (*func_addr)(const char *, uint,
102
void my_getopt_register_get_addr(uchar** (*func_addr)(const char *, uint,
103
103
const struct my_option *))
105
105
getopt_get_addr= func_addr;
110
110
my_get_one_option get_one_option)
112
112
uint opt_found, argvpos= 0, length;
113
bool end_of_options= 0, must_be_var, set_maximum_value=false,
113
my_bool end_of_options= 0, must_be_var, set_maximum_value,
115
char **pos, **pos_end, *optend, *prev_found=NULL,
115
char **pos, **pos_end, *optend, *prev_found,
116
116
*opt_str, key_name[FN_REFLEN];
117
117
const struct my_option *optp;
121
121
/* handle_options() assumes arg0 (program name) always exists */
122
assert(argc && *argc >= 1);
123
assert(argv && *argv);
122
DBUG_ASSERT(argc && *argc >= 1);
123
DBUG_ASSERT(argv && *argv);
124
124
(*argc)--; /* Skip the program name */
125
125
(*argv)++; /* --- || ---- */
126
126
init_variables(longopts, init_one_value);
254
254
case OPT_DISABLE: /* fall through */
256
256
double negation is actually enable again,
257
for example: --skip-option=0 -> option = true
257
for example: --skip-option=0 -> option = TRUE
259
259
optend= (optend && *optend == '0' && !(*(optend + 1))) ?
260
260
(char*) "1" : disabled_my_option;
381
381
if (!optend || *optend == '1' ||
382
382
!my_strcasecmp(&my_charset_latin1, optend, "true"))
383
*((bool*) value)= (bool) 1;
383
*((my_bool*) value)= (my_bool) 1;
384
384
else if (*optend == '0' ||
385
385
!my_strcasecmp(&my_charset_latin1, optend, "false"))
386
*((bool*) value)= (bool) 0;
386
*((my_bool*) value)= (my_bool) 0;
389
389
my_getopt_error_reporter(WARNING_LEVEL,
403
403
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
405
405
if (optend == disabled_my_option)
406
*((bool*) value)= (bool) 0;
406
*((my_bool*) value)= (my_bool) 0;
409
409
if (!optend) /* No argument -> enable option */
410
*((bool*) value)= (bool) 1;
410
*((my_bool*) value)= (my_bool) 1;
412
412
argument= optend;
451
451
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL &&
452
452
optp->arg_type == NO_ARG)
454
*((bool*) optp->value)= (bool) 1;
454
*((my_bool*) optp->value)= (my_bool) 1;
455
455
get_one_option(optp->id, optp, argument);
470
470
if (optp->arg_type == OPT_ARG)
472
472
if (optp->var_type == GET_BOOL)
473
*((bool*) optp->value)= (bool) 1;
473
*((my_bool*) optp->value)= (my_bool) 1;
474
474
get_one_option(optp->id, optp, argument);
488
488
/* the other loop will break, because *optend + 1 == 0 */
491
if ((error= setval(optp, optp->value, argument,
491
if ((error= setval(optp, optp->value, argument,
494
494
my_getopt_error_reporter(ERROR_LEVEL,
495
495
"%s: Error while setting value '%s' to '%s'",
496
496
my_progname, argument, optp->name);
499
get_one_option(optp->id, optp, argument);
505
if (my_getopt_print_errors)
499
get_one_option(optp->id, optp, argument);
505
if (my_getopt_print_errors)
506
506
my_getopt_error_reporter(ERROR_LEVEL,
507
507
"%s: unknown option '-%c'",
508
508
my_progname, *optend);
509
return EXIT_UNKNOWN_OPTION;
512
(*argc)--; /* option handled (short), decrease argument count */
509
return EXIT_UNKNOWN_OPTION;
512
(*argc)--; /* option handled (short), decrease argument count */
515
515
if ((error= setval(optp, value, argument, set_maximum_value)))
517
517
my_getopt_error_reporter(ERROR_LEVEL,
518
518
"%s: Error while setting value '%s' to '%s'",
519
519
my_progname, argument, optp->name);
522
522
get_one_option(optp->id, optp, argument);
586
586
Will set the option value to given value
589
static int setval(const struct my_option *opts, char **value, char *argument,
590
bool set_maximum_value)
589
static int setval(const struct my_option *opts, uchar* *value, char *argument,
590
my_bool set_maximum_value)
594
594
if (value && argument)
596
char* *result_pos= ((set_maximum_value) ?
597
opts->u_max_value : value);
596
uchar* *result_pos= ((set_maximum_value) ?
597
opts->u_max_value : value);
600
600
return EXIT_NO_PTR_TO_VARIABLE;
602
602
switch ((opts->var_type & GET_TYPE_MASK)) {
603
603
case GET_BOOL: /* If argument differs from 0, enable option, else disable */
604
*((bool*) result_pos)= (bool) atoi(argument) != 0;
604
*((my_bool*) result_pos)= (my_bool) atoi(argument) != 0;
607
607
*((int*) result_pos)= (int) getopt_ll(argument, opts, &err);
616
616
*((long*) result_pos)= (long) getopt_ull(argument, opts, &err);
619
*((int64_t*) result_pos)= getopt_ll(argument, opts, &err);
619
*((longlong*) result_pos)= getopt_ll(argument, opts, &err);
622
*((uint64_t*) result_pos)= getopt_ull(argument, opts, &err);
622
*((ulonglong*) result_pos)= getopt_ull(argument, opts, &err);
625
625
*((double*) result_pos)= getopt_double(argument, opts, &err);
638
638
return EXIT_ARGUMENT_INVALID;
641
*((uint64_t*)result_pos)= find_typeset(argument, opts->typelib, &err);
641
*((ulonglong*)result_pos)= find_typeset(argument, opts->typelib, &err);
643
643
return EXIT_ARGUMENT_INVALID;
714
714
2.) Returns -1 if strings differ, 0 if they are equal
717
bool getopt_compare_strings(register const char *s, register const char *t,
717
my_bool getopt_compare_strings(register const char *s, register const char *t,
720
720
char const *end= s + length;
733
733
be k|K for kilo, m|M for mega or g|G for giga.
736
static int64_t eval_num_suffix(char *argument, int *error, char *option_name)
736
static longlong eval_num_suffix(char *argument, int *error, char *option_name)
776
776
In case of an error, set error value in *err.
779
static int64_t getopt_ll(char *arg, const struct my_option *optp, int *err)
779
static longlong getopt_ll(char *arg, const struct my_option *optp, int *err)
781
int64_t num=eval_num_suffix(arg, err, (char*) optp->name);
781
longlong num=eval_num_suffix(arg, err, (char*) optp->name);
782
782
return getopt_ll_limit_value(num, optp, NULL);
789
789
Returns "fixed" value.
792
int64_t getopt_ll_limit_value(int64_t num, const struct my_option *optp,
792
longlong getopt_ll_limit_value(longlong num, const struct my_option *optp,
796
bool adjusted= false;
796
my_bool adjusted= FALSE;
797
797
char buf1[255], buf2[255];
798
uint64_t block_size= (optp->block_size ? (uint64_t) optp->block_size : 1L);
798
ulonglong block_size= (optp->block_size ? (ulonglong) optp->block_size : 1L);
800
if (num > 0 && ((uint64_t) num > (uint64_t) optp->max_value) &&
800
if (num > 0 && ((ulonglong) num > (ulonglong) optp->max_value) &&
801
801
optp->max_value) /* if max value is not set -> no upper limit */
803
num= (uint64_t) optp->max_value;
803
num= (ulonglong) optp->max_value;
807
807
switch ((optp->var_type & GET_TYPE_MASK)) {
809
if (num > (int64_t) INT_MAX)
809
if (num > (longlong) INT_MAX)
811
num= ((int64_t) INT_MAX);
811
num= ((longlong) INT_MAX);
816
816
#if SIZEOF_LONG < SIZEOF_LONG_LONG
817
if (num > (int64_t) LONG_MAX)
817
if (num > (longlong) LONG_MAX)
819
num= ((int64_t) LONG_MAX);
819
num= ((longlong) LONG_MAX);
825
assert((optp->var_type & GET_TYPE_MASK) == GET_LL);
825
DBUG_ASSERT((optp->var_type & GET_TYPE_MASK) == GET_LL);
829
829
num= ((num - optp->sub_size) / block_size);
830
num= (int64_t) (num * block_size);
830
num= (longlong) (num * block_size);
832
832
if (num < optp->min_value)
834
834
num= optp->min_value;
854
static uint64_t getopt_ull(char *arg, const struct my_option *optp, int *err)
854
static ulonglong getopt_ull(char *arg, const struct my_option *optp, int *err)
856
uint64_t num= eval_num_suffix(arg, err, (char*) optp->name);
856
ulonglong num= eval_num_suffix(arg, err, (char*) optp->name);
857
857
return getopt_ull_limit_value(num, optp, NULL);
861
uint64_t getopt_ull_limit_value(uint64_t num, const struct my_option *optp,
861
ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp,
864
bool adjusted= false;
864
my_bool adjusted= FALSE;
866
866
char buf1[255], buf2[255];
868
if ((uint64_t) num > (uint64_t) optp->max_value &&
868
if ((ulonglong) num > (ulonglong) optp->max_value &&
869
869
optp->max_value) /* if max value is not set -> no upper limit */
871
num= (uint64_t) optp->max_value;
871
num= (ulonglong) optp->max_value;
875
875
switch ((optp->var_type & GET_TYPE_MASK)) {
877
if (num > (uint64_t) UINT_MAX)
877
if (num > (ulonglong) UINT_MAX)
879
num= ((uint64_t) UINT_MAX);
879
num= ((ulonglong) UINT_MAX);
884
884
#if SIZEOF_LONG < SIZEOF_LONG_LONG
885
if (num > (uint64_t) ULONG_MAX)
885
if (num > (ulonglong) ULONG_MAX)
887
num= ((uint64_t) ULONG_MAX);
887
num= ((ulonglong) ULONG_MAX);
893
assert((optp->var_type & GET_TYPE_MASK) == GET_ULL);
893
DBUG_ASSERT((optp->var_type & GET_TYPE_MASK) == GET_ULL);
897
897
if (optp->block_size > 1)
899
num/= (uint64_t) optp->block_size;
900
num*= (uint64_t) optp->block_size;
899
num/= (ulonglong) optp->block_size;
900
num*= (ulonglong) optp->block_size;
903
if (num < (uint64_t) optp->min_value)
903
if (num < (ulonglong) optp->min_value)
905
num= (uint64_t) optp->min_value;
905
num= (ulonglong) optp->min_value;
957
957
value Pointer to variable
960
static void init_one_value(const struct my_option *option, char** variable,
960
static void init_one_value(const struct my_option *option, uchar* *variable,
963
DBUG_ENTER("init_one_value");
963
964
switch ((option->var_type & GET_TYPE_MASK)) {
965
*((bool*) variable)= (bool) value;
966
*((my_bool*) variable)= (my_bool) value;
968
969
*((int*) variable)= (int) value;
978
979
*((ulong*) variable)= (ulong) value;
981
*((int64_t*) variable)= (int64_t) value;
982
*((longlong*) variable)= (longlong) value;
985
*((uint64_t*) variable)= (uint64_t) value;
986
*((ulonglong*) variable)= (ulonglong) value;
988
989
*((double*) variable)= (double) value;
992
993
Do not clear variable value if it has no default value.
993
994
The default value may already be set.
994
NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
995
NOTE: To avoid compiler warnings, we first cast longlong to intptr,
995
996
so that the value has the same size as a pointer.
997
if ((char*) (intptr_t) value)
998
*((char**) variable)= (char*) (intptr_t) value;
998
if ((char*) (intptr) value)
999
*((char**) variable)= (char*) (intptr) value;
1000
1001
case GET_STR_ALLOC:
1002
1003
Do not clear variable value if it has no default value.
1003
1004
The default value may already be set.
1004
NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
1005
NOTE: To avoid compiler warnings, we first cast longlong to intptr,
1005
1006
so that the value has the same size as a pointer.
1007
if ((char*) (intptr_t) value)
1008
if ((char*) (intptr) value)
1009
1010
my_free((*(char**) variable), MYF(MY_ALLOW_ZERO_PTR));
1010
*((char**) variable)= my_strdup((char*) (intptr_t) value, MYF(MY_WME));
1011
*((char**) variable)= my_strdup((char*) (intptr) value, MYF(MY_WME));
1013
1014
default: /* dummy default to avoid compiler warnings */
1026
1027
value Pointer to variable
1029
static void fini_one_value(const struct my_option *option, char **variable,
1030
int64_t value __attribute__ ((unused)))
1030
static void fini_one_value(const struct my_option *option, uchar* *variable,
1031
longlong value __attribute__ ((unused)))
1033
DBUG_ENTER("fini_one_value");
1032
1034
switch ((option->var_type & GET_TYPE_MASK)) {
1033
1035
case GET_STR_ALLOC:
1034
1036
my_free((*(char**) variable), MYF(MY_ALLOW_ZERO_PTR));
1063
1065
static void init_variables(const struct my_option *options,
1064
1066
init_func_p init_one_value)
1068
DBUG_ENTER("init_variables");
1066
1069
for (; options->name; options++)
1072
DBUG_PRINT("options", ("name: '%s'", options->name));
1070
1074
We must set u_max_value first as for some variables
1071
1075
options->u_max_value == options->value and in this case we want to
1178
1182
void my_print_variables(const struct my_option *options)
1180
1184
uint name_space= 34, length, nr;
1181
uint64_t bit, llvalue;
1185
ulonglong bit, llvalue;
1182
1186
char buff[255];
1183
1187
const struct my_option *optp;
1185
1189
printf("\nVariables (--variable-name=value)\n");
1186
printf("and boolean options {false|true} Value (after reading options)\n");
1190
printf("and boolean options {FALSE|TRUE} Value (after reading options)\n");
1187
1191
printf("--------------------------------- -----------------------------\n");
1188
1192
for (optp= options; optp->id; optp++)
1190
char* *value= (optp->var_type & GET_ASK_ADDR ?
1194
uchar* *value= (optp->var_type & GET_ASK_ADDR ?
1191
1195
(*getopt_get_addr)("", 0, optp) : optp->value);
1198
1202
switch ((optp->var_type & GET_TYPE_MASK)) {
1200
if (!(llvalue= *(uint64_t*) value))
1204
if (!(llvalue= *(ulonglong*) value))
1201
1205
printf("%s\n", "(No default value)");
1203
1207
for (nr= 0, bit= 1; llvalue && nr < optp->typelib->count; nr++, bit<<=1)
1232
1236
printf("%lu\n", *((ulong*) value));
1235
printf("%s\n", llstr(*((int64_t*) value), buff));
1239
printf("%s\n", llstr(*((longlong*) value), buff));
1238
int64_t2str(*((uint64_t*) value), buff, 10);
1242
longlong2str(*((ulonglong*) value), buff, 10);
1239
1243
printf("%s\n", buff);
1241
1245
case GET_DOUBLE: