13
13
along with this program; if not, write to the Free Software
14
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
#include "mysys_priv.h"
17
#include <libdrizzle/gettext.h>
19
#include <mystrings/m_string.h>
16
#include <my_global.h>
20
18
#include <stdlib.h>
21
19
#include <my_sys.h>
22
20
#include <mysys_err.h>
23
21
#include <my_getopt.h>
26
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,
29
27
static void default_reporter(enum loglevel level, const char *format, ...);
30
28
my_error_reporter my_getopt_error_reporter= &default_reporter;
32
static int findopt(char *optpat, uint32_t length,
30
static int findopt(char *optpat, uint length,
33
31
const struct my_option **opt_res,
35
static int64_t getopt_ll(char *arg, const struct my_option *optp, int *err);
36
static uint64_t getopt_ull(char *arg, const struct my_option *optp,
33
my_bool getopt_compare_strings(const char *s,
36
static longlong getopt_ll(char *arg, const struct my_option *optp, int *err);
37
static ulonglong getopt_ull(char *arg, const struct my_option *optp,
38
39
static double getopt_double(char *arg, const struct my_option *optp, int *err);
39
40
static void init_variables(const struct my_option *options,
40
41
init_func_p init_one_value);
41
static void init_one_value(const struct my_option *option, char **variable,
43
static void fini_one_value(const struct my_option *option, char **variable,
45
static int setval(const struct my_option *opts, char* *value, char *argument,
46
bool set_maximum_value);
42
static void init_one_value(const struct my_option *option, uchar* *variable,
44
static void fini_one_value(const struct my_option *option, uchar* *variable,
46
static int setval(const struct my_option *opts, uchar* *value, char *argument,
47
my_bool set_maximum_value);
47
48
static char *check_struct_option(char *cur_arg, char *key_name);
53
54
static const char *special_opt_prefix[]=
54
55
{"skip", "disable", "enable", "maximum", "loose", 0};
55
static const uint32_t special_opt_prefix_lengths[]=
56
static const uint special_opt_prefix_lengths[]=
56
57
{ 4, 7, 6, 7, 5, 0};
57
58
enum enum_special_opt
58
59
{ OPT_SKIP, OPT_DISABLE, OPT_ENABLE, OPT_MAXIMUM, OPT_LOOSE};
68
bool my_getopt_print_errors= 1;
69
my_bool my_getopt_print_errors= 1;
71
72
This is a flag that can be set in client programs. 1 means that
72
73
my_getopt will skip over options it does not know how to handle.
75
bool my_getopt_skip_unknown= 0;
76
my_bool my_getopt_skip_unknown= 0;
77
78
static void default_reporter(enum loglevel level,
78
79
const char *format, ...)
81
82
va_start(args, format);
82
83
if (level == WARNING_LEVEL)
83
fprintf(stderr, "%s", _("Warning: "));
84
fprintf(stderr, "%s", "Warning: ");
84
85
else if (level == INFORMATION_LEVEL)
85
fprintf(stderr, "%s", _("Info: "));
86
fprintf(stderr, "%s", "Info: ");
86
87
vfprintf(stderr, format, args);
88
89
fputc('\n', stderr);
99
100
one. Call function 'get_one_option()' once for each option.
102
static char** (*getopt_get_addr)(const char *, uint, const struct my_option *);
103
static uchar** (*getopt_get_addr)(const char *, uint, const struct my_option *);
104
void my_getopt_register_get_addr(char** (*func_addr)(const char *, uint,
105
void my_getopt_register_get_addr(uchar** (*func_addr)(const char *, uint,
105
106
const struct my_option *))
107
108
getopt_get_addr= func_addr;
111
112
const struct my_option *longopts,
112
113
my_get_one_option get_one_option)
114
uint32_t opt_found, argvpos= 0, length;
115
bool end_of_options= 0, must_be_var, set_maximum_value=false,
115
uint opt_found, argvpos= 0, length;
116
my_bool end_of_options= 0, must_be_var, set_maximum_value,
117
char **pos, **pos_end, *optend, *prev_found=NULL,
118
char **pos, **pos_end, *optend, *prev_found,
118
119
*opt_str, key_name[FN_REFLEN];
119
120
const struct my_option *optp;
123
124
/* handle_options() assumes arg0 (program name) always exists */
124
assert(argc && *argc >= 1);
125
assert(argv && *argv);
125
DBUG_ASSERT(argc && *argc >= 1);
126
DBUG_ASSERT(argv && *argv);
126
127
(*argc)--; /* Skip the program name */
127
128
(*argv)++; /* --- || ---- */
128
129
init_variables(longopts, init_one_value);
205
206
opt_str= check_struct_option(cur_arg, key_name);
206
optend= strrchr(opt_str, '=');
209
length= (uint) (optend - opt_str);
207
optend= strcend(opt_str, '=');
208
length= (uint) (optend - opt_str);
214
length= strlen(opt_str);
219
215
Find first the right option. Return error in case of an ambiguous,
261
257
case OPT_DISABLE: /* fall through */
263
259
double negation is actually enable again,
264
for example: --skip-option=0 -> option = true
260
for example: --skip-option=0 -> option = TRUE
266
262
optend= (optend && *optend == '0' && !(*(optend + 1))) ?
267
263
(char*) "1" : disabled_my_option;
348
344
if (my_getopt_print_errors)
350
_("%s: %s: Option '%s' used, but is disabled\n"), my_progname,
351
option_is_loose ? _("WARNING") : _("ERROR"), opt_str);
346
"%s: %s: Option '%s' used, but is disabled\n", my_progname,
347
option_is_loose ? "WARNING" : "ERROR", opt_str);
352
348
if (option_is_loose)
388
384
if (!optend || *optend == '1' ||
389
!my_strcasecmp(&my_charset_utf8_general_ci, optend, "true"))
390
*((bool*) value)= (bool) 1;
385
!my_strcasecmp(&my_charset_latin1, optend, "true"))
386
*((my_bool*) value)= (my_bool) 1;
391
387
else if (*optend == '0' ||
392
!my_strcasecmp(&my_charset_utf8_general_ci, optend, "false"))
393
*((bool*) value)= (bool) 0;
388
!my_strcasecmp(&my_charset_latin1, optend, "false"))
389
*((my_bool*) value)= (my_bool) 0;
396
392
my_getopt_error_reporter(WARNING_LEVEL,
410
406
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
412
408
if (optend == disabled_my_option)
413
*((bool*) value)= (bool) 0;
409
*((my_bool*) value)= (my_bool) 0;
416
412
if (!optend) /* No argument -> enable option */
417
*((bool*) value)= (bool) 1;
413
*((my_bool*) value)= (my_bool) 1;
419
415
argument= optend;
452
448
if (my_getopt_print_errors)
454
_("%s: ERROR: Option '-%c' used, but is disabled\n"),
450
"%s: ERROR: Option '-%c' used, but is disabled\n",
455
451
my_progname, optp->id);
456
452
return EXIT_OPTION_DISABLED;
458
454
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL &&
459
455
optp->arg_type == NO_ARG)
461
*((bool*) optp->value)= (bool) 1;
457
*((my_bool*) optp->value)= (my_bool) 1;
462
458
get_one_option(optp->id, optp, argument);
495
491
/* the other loop will break, because *optend + 1 == 0 */
498
if ((error= setval(optp, optp->value, argument,
494
if ((error= setval(optp, optp->value, argument,
501
497
my_getopt_error_reporter(ERROR_LEVEL,
502
498
"%s: Error while setting value '%s' to '%s'",
503
499
my_progname, argument, optp->name);
506
get_one_option(optp->id, optp, argument);
512
if (my_getopt_print_errors)
502
get_one_option(optp->id, optp, argument);
508
if (my_getopt_print_errors)
513
509
my_getopt_error_reporter(ERROR_LEVEL,
514
510
"%s: unknown option '-%c'",
515
511
my_progname, *optend);
516
return EXIT_UNKNOWN_OPTION;
519
(*argc)--; /* option handled (short), decrease argument count */
512
return EXIT_UNKNOWN_OPTION;
515
(*argc)--; /* option handled (short), decrease argument count */
522
518
if ((error= setval(optp, value, argument, set_maximum_value)))
524
520
my_getopt_error_reporter(ERROR_LEVEL,
525
521
"%s: Error while setting value '%s' to '%s'",
526
522
my_progname, argument, optp->name);
529
525
get_one_option(optp->id, optp, argument);
565
ptr= strrchr(cur_arg + 1, '.'); /* Skip the first character */
566
end= strrchr(cur_arg, '=');
561
ptr= strcend(cur_arg + 1, '.'); /* Skip the first character */
562
end= strcend(cur_arg, '=');
569
565
If the first dot is after an equal sign, then it is part
572
568
NULL, or the character right before equal sign is the first
573
569
dot found, the option is not a struct option.
575
if ((ptr != NULL) && (end != NULL) && (end - ptr > 1))
577
uint32_t len= (uint) (ptr - cur_arg);
573
uint len= (uint) (ptr - cur_arg);
578
574
set_if_smaller(len, FN_REFLEN-1);
579
575
strmake(key_name, cur_arg, len);
593
589
Will set the option value to given value
596
static int setval(const struct my_option *opts, char **value, char *argument,
597
bool set_maximum_value)
592
static int setval(const struct my_option *opts, uchar* *value, char *argument,
593
my_bool set_maximum_value)
601
597
if (value && argument)
603
char* *result_pos= ((set_maximum_value) ?
604
opts->u_max_value : value);
599
uchar* *result_pos= ((set_maximum_value) ?
600
opts->u_max_value : value);
607
603
return EXIT_NO_PTR_TO_VARIABLE;
609
605
switch ((opts->var_type & GET_TYPE_MASK)) {
610
606
case GET_BOOL: /* If argument differs from 0, enable option, else disable */
611
*((bool*) result_pos)= (bool) atoi(argument) != 0;
607
*((my_bool*) result_pos)= (my_bool) atoi(argument) != 0;
614
610
*((int*) result_pos)= (int) getopt_ll(argument, opts, &err);
623
619
*((long*) result_pos)= (long) getopt_ull(argument, opts, &err);
626
*((int64_t*) result_pos)= getopt_ll(argument, opts, &err);
622
*((longlong*) result_pos)= getopt_ll(argument, opts, &err);
629
*((uint64_t*) result_pos)= getopt_ull(argument, opts, &err);
625
*((ulonglong*) result_pos)= getopt_ull(argument, opts, &err);
632
628
*((double*) result_pos)= getopt_double(argument, opts, &err);
681
677
ffname points to first matching option
684
static int findopt(char *optpat, uint32_t length,
680
static int findopt(char *optpat, uint length,
685
681
const struct my_option **opt_res,
689
685
struct my_option *opt= (struct my_option *) *opt_res;
691
687
for (count= 0; opt->name; opt++)
721
717
2.) Returns -1 if strings differ, 0 if they are equal
724
bool getopt_compare_strings(register const char *s, register const char *t,
720
my_bool getopt_compare_strings(register const char *s, register const char *t,
727
723
char const *end= s + length;
728
724
for (;s != end ; s++, t++)
783
779
In case of an error, set error value in *err.
786
static int64_t getopt_ll(char *arg, const struct my_option *optp, int *err)
782
static longlong getopt_ll(char *arg, const struct my_option *optp, int *err)
788
int64_t num=eval_num_suffix(arg, err, (char*) optp->name);
784
longlong num=eval_num_suffix(arg, err, (char*) optp->name);
789
785
return getopt_ll_limit_value(num, optp, NULL);
796
792
Returns "fixed" value.
799
int64_t getopt_ll_limit_value(int64_t num, const struct my_option *optp,
795
longlong getopt_ll_limit_value(longlong num, const struct my_option *optp,
803
bool adjusted= false;
799
my_bool adjusted= FALSE;
804
800
char buf1[255], buf2[255];
805
uint64_t block_size= (optp->block_size ? (uint64_t) optp->block_size : 1L);
801
ulonglong block_size= (optp->block_size ? (ulonglong) optp->block_size : 1L);
807
if (num > 0 && ((uint64_t) num > (uint64_t) optp->max_value) &&
803
if (num > 0 && ((ulonglong) num > (ulonglong) optp->max_value) &&
808
804
optp->max_value) /* if max value is not set -> no upper limit */
810
num= (uint64_t) optp->max_value;
806
num= (ulonglong) optp->max_value;
814
810
switch ((optp->var_type & GET_TYPE_MASK)) {
816
if (num > (int64_t) INT_MAX)
812
if (num > (longlong) INT_MAX)
818
num= ((int64_t) INT_MAX);
814
num= ((longlong) INT_MAX);
823
if (num > (int64_t) INT32_MAX)
819
#if SIZEOF_LONG < SIZEOF_LONG_LONG
820
if (num > (longlong) LONG_MAX)
825
num= ((int64_t) INT32_MAX);
822
num= ((longlong) LONG_MAX);
830
assert((optp->var_type & GET_TYPE_MASK) == GET_LL);
828
DBUG_ASSERT((optp->var_type & GET_TYPE_MASK) == GET_LL);
834
832
num= ((num - optp->sub_size) / block_size);
835
num= (int64_t) (num * block_size);
833
num= (longlong) (num * block_size);
837
835
if (num < optp->min_value)
839
837
num= optp->min_value;
853
851
function: getopt_ull
855
This is the same as getopt_ll, but is meant for uint64_t
853
This is the same as getopt_ll, but is meant for unsigned long long
859
static uint64_t getopt_ull(char *arg, const struct my_option *optp, int *err)
857
static ulonglong getopt_ull(char *arg, const struct my_option *optp, int *err)
861
uint64_t num= eval_num_suffix(arg, err, (char*) optp->name);
859
ulonglong num= eval_num_suffix(arg, err, (char*) optp->name);
862
860
return getopt_ull_limit_value(num, optp, NULL);
866
uint64_t getopt_ull_limit_value(uint64_t num, const struct my_option *optp,
864
ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp,
869
bool adjusted= false;
867
my_bool adjusted= FALSE;
871
869
char buf1[255], buf2[255];
873
if ((uint64_t) num > (uint64_t) optp->max_value &&
871
if ((ulonglong) num > (ulonglong) optp->max_value &&
874
872
optp->max_value) /* if max value is not set -> no upper limit */
876
num= (uint64_t) optp->max_value;
874
num= (ulonglong) optp->max_value;
880
878
switch ((optp->var_type & GET_TYPE_MASK)) {
882
if (num > (uint64_t) UINT_MAX)
880
if (num > (ulonglong) UINT_MAX)
884
num= ((uint64_t) UINT_MAX);
882
num= ((ulonglong) UINT_MAX);
889
if (num > (uint64_t) UINT32_MAX)
887
#if SIZEOF_LONG < SIZEOF_LONG_LONG
888
if (num > (ulonglong) ULONG_MAX)
891
num= ((uint64_t) UINT32_MAX);
890
num= ((ulonglong) ULONG_MAX);
896
assert((optp->var_type & GET_TYPE_MASK) == GET_ULL);
896
DBUG_ASSERT((optp->var_type & GET_TYPE_MASK) == GET_ULL);
900
900
if (optp->block_size > 1)
902
num/= (uint64_t) optp->block_size;
903
num*= (uint64_t) optp->block_size;
902
num/= (ulonglong) optp->block_size;
903
num*= (ulonglong) optp->block_size;
906
if (num < (uint64_t) optp->min_value)
906
if (num < (ulonglong) optp->min_value)
908
num= (uint64_t) optp->min_value;
908
num= (ulonglong) optp->min_value;
941
941
if (end[0] != 0 || error)
944
_("%s: ERROR: Invalid decimal value for option '%s'\n"),
944
"%s: ERROR: Invalid decimal value for option '%s'\n",
945
945
my_progname, optp->name);
946
946
*err= EXIT_ARGUMENT_INVALID;
949
949
if (optp->max_value && num > (double) optp->max_value)
950
950
num= (double) optp->max_value;
951
return cmax(num, (double) optp->min_value);
951
return max(num, (double) optp->min_value);
960
960
value Pointer to variable
963
static void init_one_value(const struct my_option *option, char** variable,
963
static void init_one_value(const struct my_option *option, uchar* *variable,
966
DBUG_ENTER("init_one_value");
966
967
switch ((option->var_type & GET_TYPE_MASK)) {
968
*((bool*) variable)= (bool) value;
969
*((my_bool*) variable)= (my_bool) value;
971
972
*((int*) variable)= (int) value;
978
979
*((long*) variable)= (long) value;
981
*((uint32_t*) variable)= (uint32_t) value;
982
*((ulong*) variable)= (ulong) value;
984
*((int64_t*) variable)= (int64_t) value;
985
*((longlong*) variable)= (longlong) value;
988
*((uint64_t*) variable)= (uint64_t) value;
989
*((ulonglong*) variable)= (ulonglong) value;
991
992
*((double*) variable)= (double) value;
995
996
Do not clear variable value if it has no default value.
996
997
The default value may already be set.
997
NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
998
NOTE: To avoid compiler warnings, we first cast longlong to intptr,
998
999
so that the value has the same size as a pointer.
1000
if ((char*) (intptr_t) value)
1001
*((char**) variable)= (char*) (intptr_t) value;
1001
if ((char*) (intptr) value)
1002
*((char**) variable)= (char*) (intptr) value;
1003
1004
case GET_STR_ALLOC:
1005
1006
Do not clear variable value if it has no default value.
1006
1007
The default value may already be set.
1007
NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
1008
NOTE: To avoid compiler warnings, we first cast longlong to intptr,
1008
1009
so that the value has the same size as a pointer.
1010
if ((char*) (intptr_t) value)
1011
if ((char*) (intptr) value)
1012
free((*(char**) variable));
1013
*((char**) variable)= my_strdup((char*) (intptr_t) value, MYF(MY_WME));
1013
my_free((*(char**) variable), MYF(MY_ALLOW_ZERO_PTR));
1014
*((char**) variable)= my_strdup((char*) (intptr) value, MYF(MY_WME));
1016
1017
default: /* dummy default to avoid compiler warnings */
1029
1030
value Pointer to variable
1032
static void fini_one_value(const struct my_option *option, char **variable,
1033
int64_t value __attribute__ ((unused)))
1033
static void fini_one_value(const struct my_option *option, uchar* *variable,
1034
longlong value __attribute__ ((unused)))
1036
DBUG_ENTER("fini_one_value");
1035
1037
switch ((option->var_type & GET_TYPE_MASK)) {
1036
1038
case GET_STR_ALLOC:
1037
free((*(char**) variable));
1039
my_free((*(char**) variable), MYF(MY_ALLOW_ZERO_PTR));
1038
1040
*((char**) variable)= NULL;
1040
1042
default: /* dummy default to avoid compiler warnings */
1066
1068
static void init_variables(const struct my_option *options,
1067
1069
init_func_p init_one_value)
1071
DBUG_ENTER("init_variables");
1069
1072
for (; options->name; options++)
1075
DBUG_PRINT("options", ("name: '%s'", options->name));
1073
1077
We must set u_max_value first as for some variables
1074
1078
options->u_max_value == options->value and in this case we want to
1092
1096
Print help for all options and variables.
1099
#include <help_start.h>
1095
1101
void my_print_help(const struct my_option *options)
1097
uint32_t col, name_space= 22, comment_space= 57;
1103
uint col, name_space= 22, comment_space= 57;
1098
1104
const char *line_end;
1099
1105
const struct my_option *optp;
1179
1185
void my_print_variables(const struct my_option *options)
1181
uint32_t name_space= 34, length, nr;
1182
uint64_t bit, llvalue;
1187
uint name_space= 34, length, nr;
1188
ulonglong bit, llvalue;
1183
1189
char buff[255];
1184
1190
const struct my_option *optp;
1186
printf(_("\nVariables (--variable-name=value)\n"
1187
"and boolean options {false|true} Value (after reading options)\n"
1188
"--------------------------------- -----------------------------\n"));
1192
printf("\nVariables (--variable-name=value)\n");
1193
printf("and boolean options {FALSE|TRUE} Value (after reading options)\n");
1194
printf("--------------------------------- -----------------------------\n");
1189
1195
for (optp= options; optp->id; optp++)
1191
char* *value= (optp->var_type & GET_ASK_ADDR ?
1197
uchar* *value= (optp->var_type & GET_ASK_ADDR ?
1192
1198
(*getopt_get_addr)("", 0, optp) : optp->value);
1199
1205
switch ((optp->var_type & GET_TYPE_MASK)) {
1201
if (!(llvalue= *(uint64_t*) value))
1202
printf("%s\n", _("(No default value)"));
1207
if (!(llvalue= *(ulonglong*) value))
1208
printf("%s\n", "(No default value)");
1204
1210
for (nr= 0, bit= 1; llvalue && nr < optp->typelib->count; nr++, bit<<=1)
1216
1222
case GET_STR_ALLOC: /* fall through */
1217
1223
printf("%s\n", *((char**) value) ? *((char**) value) :
1218
_("(No default value)"));
1224
"(No default value)");
1221
printf("%s\n", *((bool*) value) ? _("true") : _("false"));
1227
printf("%s\n", *((my_bool*) value) ? "TRUE" : "FALSE");
1224
1230
printf("%d\n", *((int*) value));
1230
1236
printf("%ld\n", *((long*) value));
1232
1238
case GET_ULONG:
1233
printf("%u\n", *((uint32_t*) value));
1239
printf("%lu\n", *((ulong*) value));
1236
printf("%s\n", llstr(*((int64_t*) value), buff));
1242
printf("%s\n", llstr(*((longlong*) value), buff));
1239
int64_t2str(*((uint64_t*) value), buff, 10);
1245
longlong2str(*((ulonglong*) value), buff, 10);
1240
1246
printf("%s\n", buff);
1242
1248
case GET_DOUBLE:
1243
1249
printf("%g\n", *(double*) value);
1246
printf(_("(Disabled)\n"));
1252
printf("(Disabled)\n");
1259
#include <help_end.h>