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 <my_global.h>
16
#include "drizzled/internal/mysys_priv.h"
17
#include <drizzled/gettext.h>
19
#include "drizzled/internal/m_string.h"
20
#include "drizzled/internal/my_sys.h"
21
#include "drizzled/my_error.h"
22
#include "drizzled/my_getopt.h"
18
25
#include <stdlib.h>
20
#include <mysys_err.h>
21
#include <my_getopt.h>
24
32
typedef void (*init_func_p)(const struct my_option *option, char **variable,
27
static void default_reporter(enum loglevel level, const char *format, ...);
35
extern "C" void default_reporter(enum loglevel level, const char *format, ...);
28
36
my_error_reporter my_getopt_error_reporter= &default_reporter;
30
static int findopt(char *optpat, uint length,
38
static int findopt(char *optpat, uint32_t length,
31
39
const struct my_option **opt_res,
33
41
static int64_t getopt_ll(char *arg, const struct my_option *optp, int *err);
34
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);
36
45
static double getopt_double(char *arg, const struct my_option *optp, int *err);
37
46
static void init_variables(const struct my_option *options,
38
47
init_func_p init_one_value);
51
60
static const char *special_opt_prefix[]=
52
61
{"skip", "disable", "enable", "maximum", "loose", 0};
53
static const uint special_opt_prefix_lengths[]=
62
static const uint32_t special_opt_prefix_lengths[]=
54
63
{ 4, 7, 6, 7, 5, 0};
55
64
enum enum_special_opt
56
65
{ OPT_SKIP, OPT_DISABLE, OPT_ENABLE, OPT_MAXIMUM, OPT_LOOSE};
58
67
char *disabled_my_option= (char*) "0";
61
This is a flag that can be set in client programs. 0 means that
62
my_getopt will not print error messages, but the client should do
66
bool my_getopt_print_errors= 1;
69
70
This is a flag that can be set in client programs. 1 means that
70
71
my_getopt will skip over options it does not know how to handle.
73
74
bool my_getopt_skip_unknown= 0;
75
static void default_reporter(enum loglevel level,
76
const char *format, ...)
76
extern "C" void default_reporter(enum loglevel level, const char *format, ...)
79
79
va_start(args, format);
80
80
if (level == WARNING_LEVEL)
81
fprintf(stderr, "%s", "Warning: ");
81
fprintf(stderr, "%s", _("Warning: "));
82
82
else if (level == INFORMATION_LEVEL)
83
fprintf(stderr, "%s", "Info: ");
83
fprintf(stderr, "%s", _("Info: "));
84
84
vfprintf(stderr, format, args);
86
86
fputc('\n', stderr);
91
91
function: handle_options
93
93
Sort options; put options first, until special end of options (--), or
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 *);
102
void my_getopt_register_get_addr(char** (*func_addr)(const char *, uint,
103
const struct my_option *))
105
getopt_get_addr= func_addr;
108
int handle_options(int *argc, char ***argv,
100
static getopt_get_addr_func getopt_get_addr;
102
int handle_options(int *argc, char ***argv,
109
103
const struct my_option *longopts,
110
104
my_get_one_option get_one_option)
112
uint opt_found, argvpos= 0, length;
106
uint32_t opt_found, argvpos= 0, length;
113
107
bool end_of_options= 0, must_be_var, set_maximum_value=false,
115
109
char **pos, **pos_end, *optend, *prev_found=NULL,
148
142
/* the argument must be in next argv */
151
if (my_getopt_print_errors)
152
my_getopt_error_reporter(ERROR_LEVEL,
153
"%s: Option '-O' requires an argument",
145
my_getopt_error_reporter(ERROR_LEVEL,
146
"%s: Option '-O' requires an argument",
155
148
return EXIT_ARGUMENT_REQUIRED;
169
if (my_getopt_print_errors)
170
my_getopt_error_reporter(ERROR_LEVEL,
171
"%s: Option '--set-variable' requires an argument",
162
my_getopt_error_reporter(ERROR_LEVEL,
163
"%s: Option '--set-variable' requires an argument",
173
165
return EXIT_ARGUMENT_REQUIRED;
180
172
/* the argument must be in next argv */
183
if (my_getopt_print_errors)
184
my_getopt_error_reporter(ERROR_LEVEL,
185
"%s: Option '--set-variable' requires an argument",
175
my_getopt_error_reporter(ERROR_LEVEL,
176
"%s: Option '--set-variable' requires an argument",
187
178
return EXIT_ARGUMENT_REQUIRED;
203
194
opt_str= check_struct_option(cur_arg, key_name);
204
optend= strcend(opt_str, '=');
205
length= (uint) (optend - opt_str);
195
optend= strrchr(opt_str, '=');
198
length= (uint32_t) (optend - opt_str);
203
length= static_cast<uint32_t>(strlen(opt_str));
212
208
Find first the right option. Return error in case of an ambiguous,
242
238
if (opt_found > 1)
244
if (my_getopt_print_errors)
245
my_getopt_error_reporter(ERROR_LEVEL,
246
"%s: ambiguous option '--%s-%s' (--%s-%s)",
247
my_progname, special_opt_prefix[i],
248
cur_arg, special_opt_prefix[i],
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],
250
245
return EXIT_AMBIGUOUS_OPTION;
294
if (my_getopt_print_errors)
295
my_getopt_error_reporter(option_is_loose ?
296
WARNING_LEVEL : ERROR_LEVEL,
297
"%s: unknown variable '%s'",
298
my_progname, cur_arg);
289
my_getopt_error_reporter(option_is_loose ?
290
WARNING_LEVEL : ERROR_LEVEL,
291
"%s: unknown variable '%s'",
292
my_progname, cur_arg);
299
293
if (!option_is_loose)
300
294
return EXIT_UNKNOWN_VARIABLE;
304
if (my_getopt_print_errors)
305
my_getopt_error_reporter(option_is_loose ?
306
WARNING_LEVEL : ERROR_LEVEL,
307
"%s: unknown option '--%s'",
308
my_progname, cur_arg);
298
my_getopt_error_reporter(option_is_loose ?
299
WARNING_LEVEL : ERROR_LEVEL,
300
"%s: unknown option '--%s'",
301
my_progname, cur_arg);
309
302
if (!option_is_loose)
310
303
return EXIT_UNKNOWN_OPTION;
323
if (my_getopt_print_errors)
324
my_getopt_error_reporter(ERROR_LEVEL,
325
"%s: variable prefix '%s' is not unique",
326
my_progname, opt_str);
316
my_getopt_error_reporter(ERROR_LEVEL,
317
"%s: variable prefix '%s' is not unique",
318
my_progname, opt_str);
327
319
return EXIT_VAR_PREFIX_NOT_UNIQUE;
331
if (my_getopt_print_errors)
332
my_getopt_error_reporter(ERROR_LEVEL,
333
"%s: ambiguous option '--%s' (%s, %s)",
334
my_progname, opt_str, prev_found,
323
my_getopt_error_reporter(ERROR_LEVEL,
324
"%s: ambiguous option '--%s' (%s, %s)",
325
my_progname, opt_str, prev_found,
336
327
return EXIT_AMBIGUOUS_OPTION;
339
330
if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
341
if (my_getopt_print_errors)
343
"%s: %s: Option '%s' used, but is disabled\n", my_progname,
344
option_is_loose ? "WARNING" : "ERROR", opt_str);
333
_("%s: %s: Option '%s' used, but is disabled\n"), my_progname,
334
option_is_loose ? _("WARNING") : _("ERROR"), opt_str);
345
335
if (option_is_loose)
352
342
if (must_be_var && (optp->var_type & GET_TYPE_MASK) == GET_NO_ARG)
354
if (my_getopt_print_errors)
355
my_getopt_error_reporter(ERROR_LEVEL,
356
"%s: option '%s' cannot take an argument",
357
my_progname, optp->name);
344
my_getopt_error_reporter(ERROR_LEVEL,
345
"%s: option '%s' cannot take an argument",
346
my_progname, optp->name);
358
347
return EXIT_NO_ARGUMENT_ALLOWED;
360
349
value= optp->var_type & GET_ASK_ADDR ?
361
(*getopt_get_addr)(key_name, (uint) strlen(key_name), optp) : optp->value;
350
(*getopt_get_addr)(key_name, (uint32_t) strlen(key_name), optp) : optp->value;
363
352
if (optp->arg_type == NO_ARG)
365
354
if (optend && (optp->var_type & GET_TYPE_MASK) != GET_BOOL)
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);
356
my_getopt_error_reporter(ERROR_LEVEL,
357
"%s: option '--%s' cannot take an argument",
358
my_progname, optp->name);
371
359
return EXIT_NO_ARGUMENT_ALLOWED;
373
361
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL)
381
369
if (!optend || *optend == '1' ||
382
!my_strcasecmp(&my_charset_latin1, optend, "true"))
370
!my_strcasecmp(&my_charset_utf8_general_ci, optend, "true"))
383
371
*((bool*) value)= (bool) 1;
384
372
else if (*optend == '0' ||
385
!my_strcasecmp(&my_charset_latin1, optend, "false"))
373
!my_strcasecmp(&my_charset_utf8_general_ci, optend, "false"))
386
374
*((bool*) value)= (bool) 0;
417
405
/* Check if there are more arguments after this one */
420
if (my_getopt_print_errors)
421
my_getopt_error_reporter(ERROR_LEVEL,
422
"%s: option '--%s' requires an argument",
423
my_progname, optp->name);
408
my_getopt_error_reporter(ERROR_LEVEL,
409
"%s: option '--%s' requires an argument",
410
my_progname, optp->name);
424
411
return EXIT_ARGUMENT_REQUIRED;
437
424
for (optp= longopts; optp->id; optp++)
439
if (optp->id == (int) (uchar) *optend)
426
if (optp->id == (int) (unsigned char) *optend)
441
428
/* Option recognized. Find next what to do with it */
443
430
if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
445
if (my_getopt_print_errors)
447
"%s: ERROR: Option '-%c' used, but is disabled\n",
448
my_progname, optp->id);
433
_("%s: ERROR: Option '-%c' used, but is disabled\n"),
434
my_progname, optp->id);
449
435
return EXIT_OPTION_DISABLED;
451
437
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL &&
477
463
/* Check if there are more arguments after this one */
480
if (my_getopt_print_errors)
481
my_getopt_error_reporter(ERROR_LEVEL,
482
"%s: option '-%c' requires an argument",
483
my_progname, optp->id);
466
my_getopt_error_reporter(ERROR_LEVEL,
467
"%s: option '-%c' requires an argument",
468
my_progname, optp->id);
484
469
return EXIT_ARGUMENT_REQUIRED;
486
471
argument= *++pos;
505
if (my_getopt_print_errors)
506
my_getopt_error_reporter(ERROR_LEVEL,
507
"%s: unknown option '-%c'",
508
my_progname, *optend);
490
my_getopt_error_reporter(ERROR_LEVEL,
491
"%s: unknown option '-%c'",
492
my_progname, *optend);
509
493
return EXIT_UNKNOWN_OPTION;
558
ptr= strcend(cur_arg + 1, '.'); /* Skip the first character */
559
end= strcend(cur_arg, '=');
542
ptr= strrchr(cur_arg + 1, '.'); /* Skip the first character */
543
end= strrchr(cur_arg, '=');
562
546
If the first dot is after an equal sign, then it is part
563
547
of a variable value and the option is not a struct option.
564
548
Also, if the last character in the string before the ending
565
549
NULL, or the character right before equal sign is the first
566
550
dot found, the option is not a struct option.
552
if ((ptr != NULL) && (end != NULL) && (end - ptr > 1))
570
uint len= (uint) (ptr - cur_arg);
571
set_if_smaller(len, FN_REFLEN-1);
572
strmake(key_name, cur_arg, len);
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);
604
585
*((bool*) result_pos)= (bool) atoi(argument) != 0;
607
*((int*) result_pos)= (int) getopt_ll(argument, opts, &err);
588
*((int32_t*) result_pos)= (int) getopt_ll(argument, opts, &err);
610
*((uint*) result_pos)= (uint) getopt_ull(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);
613
598
*((long*) result_pos)= (long) getopt_ll(argument, opts, &err);
616
*((long*) result_pos)= (long) getopt_ull(argument, opts, &err);
619
601
*((int64_t*) result_pos)= getopt_ll(argument, opts, &err);
622
605
*((uint64_t*) result_pos)= getopt_ull(argument, opts, &err);
608
*((size_t*) result_pos)= getopt_size(argument, opts, &err);
625
611
*((double*) result_pos)= getopt_double(argument, opts, &err);
630
616
case GET_STR_ALLOC:
631
617
if ((*((char**) result_pos)))
632
my_free((*(char**) result_pos), MYF(MY_WME | MY_FAE));
633
if (!(*((char**) result_pos)= my_strdup(argument, MYF(MY_WME))))
618
free((*(char**) result_pos));
619
if (!(*((char**) result_pos)= strdup(argument)))
634
620
return EXIT_OUT_OF_MEMORY;
674
660
ffname points to first matching option
677
static int findopt(char *optpat, uint length,
663
static int findopt(char *optpat, uint32_t length,
678
664
const struct my_option **opt_res,
682
668
struct my_option *opt= (struct my_option *) *opt_res;
684
670
for (count= 0; opt->name; opt++)
717
703
bool getopt_compare_strings(register const char *s, register const char *t,
720
706
char const *end= s + length;
721
707
for (;s != end ; s++, t++)
757
743
else if (*endchar)
760
"Unknown suffix '%c' used for variable '%s' (value '%s')\n",
746
_("Unknown suffix '%c' used for variable '%s' (value '%s')\n"),
761
747
*endchar, option_name, argument);
816
#if SIZEOF_LONG < SIZEOF_LONG_LONG
817
if (num > (int64_t) LONG_MAX)
802
if (num > (int64_t) INT32_MAX)
819
num= ((int64_t) LONG_MAX);
804
num= ((int64_t) INT32_MAX);
825
809
assert((optp->var_type & GET_TYPE_MASK) == GET_LL);
845
static size_t getopt_size(char *arg, const struct my_option *optp, int *err)
847
return (size_t)getopt_ull(arg, optp, err);
861
852
uint64_t getopt_ull_limit_value(uint64_t num, const struct my_option *optp,
864
855
bool adjusted= false;
865
856
uint64_t old= num;
884
#if SIZEOF_LONG < SIZEOF_LONG_LONG
885
if (num > (uint64_t) ULONG_MAX)
887
num= ((uint64_t) ULONG_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);
893
assert((optp->var_type & GET_TYPE_MASK) == GET_ULL);
890
assert(((optp->var_type & GET_TYPE_MASK) == GET_ULL)
891
|| ((optp->var_type & GET_TYPE_MASK) == GET_UINT64));
938
936
if (end[0] != 0 || error)
941
"%s: ERROR: Invalid decimal value for option '%s'\n",
939
_("%s: ERROR: Invalid decimal value for option '%s'\n"),
942
940
my_progname, optp->name);
943
941
*err= EXIT_ARGUMENT_INVALID;
972
*((uint*) variable)= (uint) value;
970
*((uint*) variable)= (uint32_t) value;
975
973
*((long*) variable)= (long) value;
976
*((uint32_t*) variable)= (uint32_t) value;
978
case GET_ULONG_IS_FAIL:
978
979
*((ulong*) variable)= (ulong) value;
981
982
*((int64_t*) variable)= (int64_t) value;
985
*((size_t*) variable)= (size_t) value;
985
990
*((uint64_t*) variable)= (uint64_t) value;
1007
1012
if ((char*) (intptr_t) value)
1009
my_free((*(char**) variable), MYF(MY_ALLOW_ZERO_PTR));
1010
*((char**) variable)= my_strdup((char*) (intptr_t) value, MYF(MY_WME));
1014
free((*(char**) variable));
1015
char *tmpptr= strdup((char *) (intptr_t) value);
1017
*((char**) variable)= tmpptr;
1013
1020
default: /* dummy default to avoid compiler warnings */
1029
1036
static void fini_one_value(const struct my_option *option, char **variable,
1030
int64_t value __attribute__ ((unused)))
1032
1039
switch ((option->var_type & GET_TYPE_MASK)) {
1033
1040
case GET_STR_ALLOC:
1034
my_free((*(char**) variable), MYF(MY_ALLOW_ZERO_PTR));
1041
free((*(char**) variable));
1035
1042
*((char**) variable)= NULL;
1037
1044
default: /* dummy default to avoid compiler warnings */
1092
1099
void my_print_help(const struct my_option *options)
1094
uint col, name_space= 22, comment_space= 57;
1101
uint32_t col, name_space= 22, comment_space= 57;
1095
1102
const char *line_end;
1096
1103
const struct my_option *optp;
1110
1117
if (strlen(optp->name))
1112
1119
printf("--%s", optp->name);
1113
col+= 2 + (uint) strlen(optp->name);
1120
col+= 2 + (uint32_t) strlen(optp->name);
1114
1121
if ((optp->var_type & GET_TYPE_MASK) == GET_STR ||
1115
1122
(optp->var_type & GET_TYPE_MASK) == GET_STR_ALLOC)
1141
1148
if (optp->comment && *optp->comment)
1143
const char *comment= optp->comment, *end= strend(comment);
1150
const char *comment= _(optp->comment), *end= strchr(comment, '\0');
1145
while ((uint) (end - comment) > comment_space)
1152
while ((uint32_t) (end - comment) > comment_space)
1147
for (line_end= comment + comment_space; *line_end != ' '; line_end--);
1154
for (line_end= comment + comment_space; *line_end != ' '; line_end--)
1148
1156
for (; comment != line_end; comment++)
1149
1157
putchar(*comment);
1150
1158
comment++; /* skip the space, as a newline will take it's place now */
1161
1169
if (optp->def_value != 0)
1163
printf("%*s(Defaults to on; use --skip-%s to disable.)\n", name_space, "", optp->name);
1171
printf(_("%*s(Defaults to on; use --skip-%s to disable.)\n"), name_space, "", optp->name);
1176
1184
void my_print_variables(const struct my_option *options)
1178
uint name_space= 34, length, nr;
1186
uint32_t name_space= 34, length, nr;
1179
1187
uint64_t bit, llvalue;
1180
1188
char buff[255];
1181
1189
const struct my_option *optp;
1183
printf("\nVariables (--variable-name=value)\n");
1184
printf("and boolean options {false|true} Value (after reading options)\n");
1185
printf("--------------------------------- -----------------------------\n");
1191
printf(_("\nVariables (--variable-name=value)\n"
1192
"and boolean options {false|true} Value (after reading options)\n"
1193
"--------------------------------- -----------------------------\n"));
1186
1194
for (optp= options; optp->id; optp++)
1188
1196
char* *value= (optp->var_type & GET_ASK_ADDR ?
1192
1200
printf("%s ", optp->name);
1193
length= (uint) strlen(optp->name)+1;
1201
length= (uint32_t) strlen(optp->name)+1;
1194
1202
for (; length < name_space; length++)
1196
1204
switch ((optp->var_type & GET_TYPE_MASK)) {
1198
1206
if (!(llvalue= *(uint64_t*) value))
1199
printf("%s\n", "(No default value)");
1207
printf("%s\n", _("(No default value)"));
1201
1209
for (nr= 0, bit= 1; llvalue && nr < optp->typelib->count; nr++, bit<<=1)
1213
1221
case GET_STR_ALLOC: /* fall through */
1214
1222
printf("%s\n", *((char**) value) ? *((char**) value) :
1215
"(No default value)");
1223
_("(No default value)"));
1218
printf("%s\n", *((bool*) value) ? "true" : "false");
1226
printf("%s\n", *((bool*) value) ? _("true") : _("false"));
1221
1229
printf("%d\n", *((int*) value));
1227
1235
printf("%ld\n", *((long*) value));
1238
printf("%u\n", *((uint32_t*) value));
1240
case GET_ULONG_IS_FAIL:
1230
1241
printf("%lu\n", *((ulong*) value));
1244
int64_t2str((uint64_t)(*(size_t*)value), buff, 10);
1245
printf("%s\n", buff);
1233
1248
printf("%s\n", llstr(*((int64_t*) value), buff));
1236
1252
int64_t2str(*((uint64_t*) value), buff, 10);
1237
1253
printf("%s\n", buff);