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 "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"
20
25
#include <stdlib.h>
22
#include <mysys_err.h>
23
#include <my_getopt.h>
26
32
typedef void (*init_func_p)(const struct my_option *option, char **variable,
29
static void default_reporter(enum loglevel level, const char *format, ...);
35
extern "C" void default_reporter(enum loglevel level, const char *format, ...);
30
36
my_error_reporter my_getopt_error_reporter= &default_reporter;
32
static int findopt(char *optpat, uint length,
38
static int findopt(char *optpat, uint32_t length,
33
39
const struct my_option **opt_res,
35
41
static int64_t getopt_ll(char *arg, const struct my_option *optp, int *err);
36
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);
38
45
static double getopt_double(char *arg, const struct my_option *optp, int *err);
39
46
static void init_variables(const struct my_option *options,
40
47
init_func_p init_one_value);
53
60
static const char *special_opt_prefix[]=
54
61
{"skip", "disable", "enable", "maximum", "loose", 0};
55
static const uint special_opt_prefix_lengths[]=
62
static const uint32_t special_opt_prefix_lengths[]=
56
63
{ 4, 7, 6, 7, 5, 0};
57
64
enum enum_special_opt
58
65
{ OPT_SKIP, OPT_DISABLE, OPT_ENABLE, OPT_MAXIMUM, OPT_LOOSE};
60
67
char *disabled_my_option= (char*) "0";
63
This is a flag that can be set in client programs. 0 means that
64
my_getopt will not print error messages, but the client should do
68
bool my_getopt_print_errors= 1;
71
70
This is a flag that can be set in client programs. 1 means that
72
71
my_getopt will skip over options it does not know how to handle.
75
74
bool my_getopt_skip_unknown= 0;
77
static void default_reporter(enum loglevel level,
78
const char *format, ...)
76
extern "C" void default_reporter(enum loglevel level, const char *format, ...)
81
79
va_start(args, format);
99
97
one. Call function 'get_one_option()' once for each option.
102
static char** (*getopt_get_addr)(const char *, uint, const struct my_option *);
104
void my_getopt_register_get_addr(char** (*func_addr)(const char *, uint,
105
const struct my_option *))
107
getopt_get_addr= func_addr;
110
int handle_options(int *argc, char ***argv,
100
static getopt_get_addr_func getopt_get_addr;
102
int handle_options(int *argc, char ***argv,
111
103
const struct my_option *longopts,
112
104
my_get_one_option get_one_option)
114
uint opt_found, argvpos= 0, length;
106
uint32_t opt_found, argvpos= 0, length;
115
107
bool end_of_options= 0, must_be_var, set_maximum_value=false,
117
109
char **pos, **pos_end, *optend, *prev_found=NULL,
150
142
/* the argument must be in next argv */
153
if (my_getopt_print_errors)
154
my_getopt_error_reporter(ERROR_LEVEL,
155
"%s: Option '-O' requires an argument",
145
my_getopt_error_reporter(ERROR_LEVEL,
146
"%s: Option '-O' requires an argument",
157
148
return EXIT_ARGUMENT_REQUIRED;
171
if (my_getopt_print_errors)
172
my_getopt_error_reporter(ERROR_LEVEL,
173
"%s: Option '--set-variable' requires an argument",
162
my_getopt_error_reporter(ERROR_LEVEL,
163
"%s: Option '--set-variable' requires an argument",
175
165
return EXIT_ARGUMENT_REQUIRED;
182
172
/* the argument must be in next argv */
185
if (my_getopt_print_errors)
186
my_getopt_error_reporter(ERROR_LEVEL,
187
"%s: Option '--set-variable' requires an argument",
175
my_getopt_error_reporter(ERROR_LEVEL,
176
"%s: Option '--set-variable' requires an argument",
189
178
return EXIT_ARGUMENT_REQUIRED;
206
195
optend= strrchr(opt_str, '=');
207
196
if (optend != NULL)
209
length= (uint) (optend - opt_str);
198
length= (uint32_t) (optend - opt_str);
214
length= strlen(opt_str);
203
length= static_cast<uint32_t>(strlen(opt_str));
249
238
if (opt_found > 1)
251
if (my_getopt_print_errors)
252
my_getopt_error_reporter(ERROR_LEVEL,
253
"%s: ambiguous option '--%s-%s' (--%s-%s)",
254
my_progname, special_opt_prefix[i],
255
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],
257
245
return EXIT_AMBIGUOUS_OPTION;
301
if (my_getopt_print_errors)
302
my_getopt_error_reporter(option_is_loose ?
303
WARNING_LEVEL : ERROR_LEVEL,
304
"%s: unknown variable '%s'",
305
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);
306
293
if (!option_is_loose)
307
294
return EXIT_UNKNOWN_VARIABLE;
311
if (my_getopt_print_errors)
312
my_getopt_error_reporter(option_is_loose ?
313
WARNING_LEVEL : ERROR_LEVEL,
314
"%s: unknown option '--%s'",
315
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);
316
302
if (!option_is_loose)
317
303
return EXIT_UNKNOWN_OPTION;
330
if (my_getopt_print_errors)
331
my_getopt_error_reporter(ERROR_LEVEL,
332
"%s: variable prefix '%s' is not unique",
333
my_progname, opt_str);
316
my_getopt_error_reporter(ERROR_LEVEL,
317
"%s: variable prefix '%s' is not unique",
318
my_progname, opt_str);
334
319
return EXIT_VAR_PREFIX_NOT_UNIQUE;
338
if (my_getopt_print_errors)
339
my_getopt_error_reporter(ERROR_LEVEL,
340
"%s: ambiguous option '--%s' (%s, %s)",
341
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,
343
327
return EXIT_AMBIGUOUS_OPTION;
346
330
if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
348
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);
333
_("%s: %s: Option '%s' used, but is disabled\n"), my_progname,
334
option_is_loose ? _("WARNING") : _("ERROR"), opt_str);
352
335
if (option_is_loose)
359
342
if (must_be_var && (optp->var_type & GET_TYPE_MASK) == GET_NO_ARG)
361
if (my_getopt_print_errors)
362
my_getopt_error_reporter(ERROR_LEVEL,
363
"%s: option '%s' cannot take an argument",
364
my_progname, optp->name);
344
my_getopt_error_reporter(ERROR_LEVEL,
345
"%s: option '%s' cannot take an argument",
346
my_progname, optp->name);
365
347
return EXIT_NO_ARGUMENT_ALLOWED;
367
349
value= optp->var_type & GET_ASK_ADDR ?
368
(*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;
370
352
if (optp->arg_type == NO_ARG)
372
354
if (optend && (optp->var_type & GET_TYPE_MASK) != GET_BOOL)
374
if (my_getopt_print_errors)
375
my_getopt_error_reporter(ERROR_LEVEL,
376
"%s: option '--%s' cannot take an argument",
377
my_progname, optp->name);
356
my_getopt_error_reporter(ERROR_LEVEL,
357
"%s: option '--%s' cannot take an argument",
358
my_progname, optp->name);
378
359
return EXIT_NO_ARGUMENT_ALLOWED;
380
361
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL)
388
369
if (!optend || *optend == '1' ||
389
!my_strcasecmp(&my_charset_latin1, optend, "true"))
370
!my_strcasecmp(&my_charset_utf8_general_ci, optend, "true"))
390
371
*((bool*) value)= (bool) 1;
391
372
else if (*optend == '0' ||
392
!my_strcasecmp(&my_charset_latin1, optend, "false"))
373
!my_strcasecmp(&my_charset_utf8_general_ci, optend, "false"))
393
374
*((bool*) value)= (bool) 0;
424
405
/* Check if there are more arguments after this one */
427
if (my_getopt_print_errors)
428
my_getopt_error_reporter(ERROR_LEVEL,
429
"%s: option '--%s' requires an argument",
430
my_progname, optp->name);
408
my_getopt_error_reporter(ERROR_LEVEL,
409
"%s: option '--%s' requires an argument",
410
my_progname, optp->name);
431
411
return EXIT_ARGUMENT_REQUIRED;
444
424
for (optp= longopts; optp->id; optp++)
446
if (optp->id == (int) (uchar) *optend)
426
if (optp->id == (int) (unsigned char) *optend)
448
428
/* Option recognized. Find next what to do with it */
450
430
if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
452
if (my_getopt_print_errors)
454
_("%s: ERROR: Option '-%c' used, but is disabled\n"),
455
my_progname, optp->id);
433
_("%s: ERROR: Option '-%c' used, but is disabled\n"),
434
my_progname, optp->id);
456
435
return EXIT_OPTION_DISABLED;
458
437
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL &&
484
463
/* Check if there are more arguments after this one */
487
if (my_getopt_print_errors)
488
my_getopt_error_reporter(ERROR_LEVEL,
489
"%s: option '-%c' requires an argument",
490
my_progname, optp->id);
466
my_getopt_error_reporter(ERROR_LEVEL,
467
"%s: option '-%c' requires an argument",
468
my_progname, optp->id);
491
469
return EXIT_ARGUMENT_REQUIRED;
493
471
argument= *++pos;
512
if (my_getopt_print_errors)
513
my_getopt_error_reporter(ERROR_LEVEL,
514
"%s: unknown option '-%c'",
515
my_progname, *optend);
490
my_getopt_error_reporter(ERROR_LEVEL,
491
"%s: unknown option '-%c'",
492
my_progname, *optend);
516
493
return EXIT_UNKNOWN_OPTION;
565
542
ptr= strrchr(cur_arg + 1, '.'); /* Skip the first character */
566
543
end= strrchr(cur_arg, '=');
569
546
If the first dot is after an equal sign, then it is part
570
547
of a variable value and the option is not a struct option.
571
548
Also, if the last character in the string before the ending
575
552
if ((ptr != NULL) && (end != NULL) && (end - ptr > 1))
577
uint len= (uint) (ptr - cur_arg);
578
set_if_smaller(len, FN_REFLEN-1);
579
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);
611
585
*((bool*) result_pos)= (bool) atoi(argument) != 0;
614
*((int*) result_pos)= (int) getopt_ll(argument, opts, &err);
588
*((int32_t*) result_pos)= (int) getopt_ll(argument, opts, &err);
617
*((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);
620
598
*((long*) result_pos)= (long) getopt_ll(argument, opts, &err);
623
*((long*) result_pos)= (long) getopt_ull(argument, opts, &err);
626
601
*((int64_t*) result_pos)= getopt_ll(argument, opts, &err);
629
605
*((uint64_t*) result_pos)= getopt_ull(argument, opts, &err);
608
*((size_t*) result_pos)= getopt_size(argument, opts, &err);
632
611
*((double*) result_pos)= getopt_double(argument, opts, &err);
637
616
case GET_STR_ALLOC:
638
617
if ((*((char**) result_pos)))
639
my_free((*(char**) result_pos), MYF(MY_WME | MY_FAE));
640
if (!(*((char**) result_pos)= my_strdup(argument, MYF(MY_WME))))
618
free((*(char**) result_pos));
619
if (!(*((char**) result_pos)= strdup(argument)))
641
620
return EXIT_OUT_OF_MEMORY;
681
660
ffname points to first matching option
684
static int findopt(char *optpat, uint length,
663
static int findopt(char *optpat, uint32_t length,
685
664
const struct my_option **opt_res,
689
668
struct my_option *opt= (struct my_option *) *opt_res;
691
670
for (count= 0; opt->name; opt++)
724
703
bool getopt_compare_strings(register const char *s, register const char *t,
727
706
char const *end= s + length;
728
707
for (;s != end ; s++, t++)
823
#if SIZEOF_LONG < SIZEOF_LONG_LONG
824
if (num > (int64_t) LONG_MAX)
802
if (num > (int64_t) INT32_MAX)
826
num= ((int64_t) LONG_MAX);
804
num= ((int64_t) INT32_MAX);
832
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);
868
852
uint64_t getopt_ull_limit_value(uint64_t num, const struct my_option *optp,
871
855
bool adjusted= false;
872
856
uint64_t old= num;
891
#if SIZEOF_LONG < SIZEOF_LONG_LONG
892
if (num > (uint64_t) ULONG_MAX)
894
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);
900
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));
979
*((uint*) variable)= (uint) value;
970
*((uint*) variable)= (uint32_t) value;
982
973
*((long*) variable)= (long) value;
985
976
*((uint32_t*) variable)= (uint32_t) value;
978
case GET_ULONG_IS_FAIL:
979
*((ulong*) variable)= (ulong) value;
988
982
*((int64_t*) variable)= (int64_t) value;
985
*((size_t*) variable)= (size_t) value;
992
990
*((uint64_t*) variable)= (uint64_t) value;
1014
1012
if ((char*) (intptr_t) value)
1016
my_free((*(char**) variable), MYF(MY_ALLOW_ZERO_PTR));
1017
*((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;
1020
1020
default: /* dummy default to avoid compiler warnings */
1036
1036
static void fini_one_value(const struct my_option *option, char **variable,
1037
int64_t value __attribute__ ((unused)))
1039
1039
switch ((option->var_type & GET_TYPE_MASK)) {
1040
1040
case GET_STR_ALLOC:
1041
my_free((*(char**) variable), MYF(MY_ALLOW_ZERO_PTR));
1041
free((*(char**) variable));
1042
1042
*((char**) variable)= NULL;
1044
1044
default: /* dummy default to avoid compiler warnings */
1099
1099
void my_print_help(const struct my_option *options)
1101
uint col, name_space= 22, comment_space= 57;
1101
uint32_t col, name_space= 22, comment_space= 57;
1102
1102
const char *line_end;
1103
1103
const struct my_option *optp;
1117
1117
if (strlen(optp->name))
1119
1119
printf("--%s", optp->name);
1120
col+= 2 + (uint) strlen(optp->name);
1120
col+= 2 + (uint32_t) strlen(optp->name);
1121
1121
if ((optp->var_type & GET_TYPE_MASK) == GET_STR ||
1122
1122
(optp->var_type & GET_TYPE_MASK) == GET_STR_ALLOC)
1148
1148
if (optp->comment && *optp->comment)
1150
const char *comment= _(optp->comment), *end= strend(comment);
1150
const char *comment= _(optp->comment), *end= strchr(comment, '\0');
1152
while ((uint) (end - comment) > comment_space)
1152
while ((uint32_t) (end - comment) > comment_space)
1154
for (line_end= comment + comment_space; *line_end != ' '; line_end--);
1154
for (line_end= comment + comment_space; *line_end != ' '; line_end--)
1155
1156
for (; comment != line_end; comment++)
1156
1157
putchar(*comment);
1157
1158
comment++; /* skip the space, as a newline will take it's place now */
1183
1184
void my_print_variables(const struct my_option *options)
1185
uint name_space= 34, length, nr;
1186
uint32_t name_space= 34, length, nr;
1186
1187
uint64_t bit, llvalue;
1187
1188
char buff[255];
1188
1189
const struct my_option *optp;
1199
1200
printf("%s ", optp->name);
1200
length= (uint) strlen(optp->name)+1;
1201
length= (uint32_t) strlen(optp->name)+1;
1201
1202
for (; length < name_space; length++)
1203
1204
switch ((optp->var_type & GET_TYPE_MASK)) {
1234
1235
printf("%ld\n", *((long*) value));
1237
1238
printf("%u\n", *((uint32_t*) value));
1240
case GET_ULONG_IS_FAIL:
1241
printf("%lu\n", *((ulong*) value));
1244
int64_t2str((uint64_t)(*(size_t*)value), buff, 10);
1245
printf("%s\n", buff);
1240
1248
printf("%s\n", llstr(*((int64_t*) value), buff));
1243
1252
int64_t2str(*((uint64_t*) value), buff, 10);
1244
1253
printf("%s\n", buff);