~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/my_getopt.c

  • Committer: Jim Winstead
  • Date: 2008-07-19 02:56:45 UTC
  • mto: (202.1.8 codestyle)
  • mto: This revision was merged to the branch mainline in revision 207.
  • Revision ID: jimw@mysql.com-20080719025645-w2pwytebgzusjzjb
Various fixes to enable compilation on Mac OS X, and remove the glib dependency.
Temporarily disables tab-completion in the drizzle client until an appropriate
autoconf check can be added/enabled.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2002-2006 MySQL AB
 
2
 
 
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.
 
6
 
 
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.
 
11
 
 
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 */
 
15
 
 
16
#include <my_global.h>
 
17
#include <m_string.h>
 
18
#include <stdlib.h>
 
19
#include <my_sys.h>
 
20
#include <mysys_err.h>
 
21
#include <my_getopt.h>
 
22
#include <errno.h>
 
23
 
 
24
typedef void (*init_func_p)(const struct my_option *option, char **variable,
 
25
                            int64_t value);
 
26
 
 
27
static void default_reporter(enum loglevel level, const char *format, ...);
 
28
my_error_reporter my_getopt_error_reporter= &default_reporter;
 
29
 
 
30
static int findopt(char *optpat, uint length,
 
31
                   const struct my_option **opt_res,
 
32
                   char **ffname);
 
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,
 
35
                            int *err);
 
36
static double getopt_double(char *arg, const struct my_option *optp, int *err);
 
37
static void init_variables(const struct my_option *options,
 
38
                           init_func_p init_one_value);
 
39
static void init_one_value(const struct my_option *option, char **variable,
 
40
                           int64_t value);
 
41
static void fini_one_value(const struct my_option *option, char **variable,
 
42
                           int64_t value);
 
43
static int setval(const struct my_option *opts, char* *value, char *argument,
 
44
                  bool set_maximum_value);
 
45
static char *check_struct_option(char *cur_arg, char *key_name);
 
46
 
 
47
/*
 
48
  The following three variables belong to same group and the number and
 
49
  order of their arguments must correspond to each other.
 
50
*/
 
51
static const char *special_opt_prefix[]=
 
52
{"skip", "disable", "enable", "maximum", "loose", 0};
 
53
static const uint special_opt_prefix_lengths[]=
 
54
{ 4,      7,         6,        7,         5,      0};
 
55
enum enum_special_opt
 
56
{ OPT_SKIP, OPT_DISABLE, OPT_ENABLE, OPT_MAXIMUM, OPT_LOOSE};
 
57
 
 
58
char *disabled_my_option= (char*) "0";
 
59
 
 
60
/* 
 
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
 
63
   it by itself
 
64
*/
 
65
 
 
66
bool my_getopt_print_errors= 1;
 
67
 
 
68
/* 
 
69
   This is a flag that can be set in client programs. 1 means that
 
70
   my_getopt will skip over options it does not know how to handle.
 
71
*/
 
72
 
 
73
bool my_getopt_skip_unknown= 0;
 
74
 
 
75
static void default_reporter(enum loglevel level,
 
76
                             const char *format, ...)
 
77
{
 
78
  va_list args;
 
79
  va_start(args, format);
 
80
  if (level == WARNING_LEVEL)
 
81
    fprintf(stderr, "%s", "Warning: ");
 
82
  else if (level == INFORMATION_LEVEL)
 
83
    fprintf(stderr, "%s", "Info: ");
 
84
  vfprintf(stderr, format, args);
 
85
  va_end(args);
 
86
  fputc('\n', stderr);
 
87
  fflush(stderr);
 
88
}
 
89
 
 
90
/* 
 
91
  function: handle_options
 
92
 
 
93
  Sort options; put options first, until special end of options (--), or
 
94
  until end of argv. Parse options; check that the given option matches with
 
95
  one of the options in struct 'my_option', return error in case of ambiguous
 
96
  or unknown option. Check that option was given an argument if it requires
 
97
  one. Call function 'get_one_option()' once for each option.
 
98
*/
 
99
 
 
100
static char** (*getopt_get_addr)(const char *, uint, const struct my_option *);
 
101
 
 
102
void my_getopt_register_get_addr(char** (*func_addr)(const char *, uint,
 
103
                                                    const struct my_option *))
 
104
{
 
105
  getopt_get_addr= func_addr;
 
106
}
 
107
 
 
108
int handle_options(int *argc, char ***argv, 
 
109
                   const struct my_option *longopts,
 
110
                   my_get_one_option get_one_option)
 
111
{
 
112
  uint opt_found, argvpos= 0, length;
 
113
  bool end_of_options= 0, must_be_var, set_maximum_value=false,
 
114
          option_is_loose;
 
115
  char **pos, **pos_end, *optend, *prev_found=NULL,
 
116
       *opt_str, key_name[FN_REFLEN];
 
117
  const struct my_option *optp;
 
118
  char* *value;
 
119
  int error, i;
 
120
 
 
121
  /* handle_options() assumes arg0 (program name) always exists */
 
122
  assert(argc && *argc >= 1);
 
123
  assert(argv && *argv);
 
124
  (*argc)--; /* Skip the program name */
 
125
  (*argv)++; /*      --- || ----      */
 
126
  init_variables(longopts, init_one_value);
 
127
 
 
128
  for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++)
 
129
  {
 
130
    char **first= pos;
 
131
    char *cur_arg= *pos;
 
132
    if (cur_arg[0] == '-' && cur_arg[1] && !end_of_options) /* must be opt */
 
133
    {
 
134
      char *argument=    0;
 
135
      must_be_var=       0;
 
136
      set_maximum_value= 0;
 
137
      option_is_loose=   0;
 
138
 
 
139
      cur_arg++;                /* skip '-' */
 
140
      if (*cur_arg == '-' || *cur_arg == 'O') /* check for long option, */
 
141
      {                                       /* --set-variable, or -O  */
 
142
        if (*cur_arg == 'O')
 
143
        {
 
144
          must_be_var= 1;
 
145
 
 
146
          if (!(*++cur_arg))    /* If not -Ovar=# */
 
147
          {
 
148
            /* the argument must be in next argv */
 
149
            if (!*++pos)
 
150
            {
 
151
              if (my_getopt_print_errors)
 
152
                my_getopt_error_reporter(ERROR_LEVEL,
 
153
                                         "%s: Option '-O' requires an argument",
 
154
                                         my_progname);
 
155
              return EXIT_ARGUMENT_REQUIRED;
 
156
            }
 
157
            cur_arg= *pos;
 
158
            (*argc)--;
 
159
          }
 
160
        }
 
161
        else if (!getopt_compare_strings(cur_arg, "-set-variable", 13))
 
162
        {
 
163
          must_be_var= 1;
 
164
          if (cur_arg[13] == '=')
 
165
          {
 
166
            cur_arg+= 14;
 
167
            if (!*cur_arg)
 
168
            {
 
169
              if (my_getopt_print_errors)
 
170
                my_getopt_error_reporter(ERROR_LEVEL,
 
171
                                         "%s: Option '--set-variable' requires an argument",
 
172
                                         my_progname);
 
173
              return EXIT_ARGUMENT_REQUIRED;
 
174
            }
 
175
          }
 
176
          else if (cur_arg[14]) /* garbage, or another option. break out */
 
177
            must_be_var= 0;
 
178
          else
 
179
          {
 
180
            /* the argument must be in next argv */
 
181
            if (!*++pos)
 
182
            {
 
183
              if (my_getopt_print_errors)
 
184
                my_getopt_error_reporter(ERROR_LEVEL,
 
185
                                         "%s: Option '--set-variable' requires an argument",
 
186
                                         my_progname);
 
187
              return EXIT_ARGUMENT_REQUIRED;
 
188
            }
 
189
            cur_arg= *pos;
 
190
            (*argc)--;
 
191
          }
 
192
        }
 
193
        else if (!must_be_var)
 
194
        {
 
195
          if (!*++cur_arg)      /* skip the double dash */
 
196
          {
 
197
            /* '--' means end of options, look no further */
 
198
            end_of_options= 1;
 
199
            (*argc)--;
 
200
            continue;
 
201
          }
 
202
        }
 
203
        opt_str= check_struct_option(cur_arg, key_name);
 
204
        optend= strcend(opt_str, '=');
 
205
        length= (uint) (optend - opt_str);
 
206
        if (*optend == '=')
 
207
          optend++;
 
208
        else
 
209
          optend= 0;
 
210
 
 
211
        /*
 
212
          Find first the right option. Return error in case of an ambiguous,
 
213
          or unknown option
 
214
        */
 
215
        optp= longopts;
 
216
        if (!(opt_found= findopt(opt_str, length, &optp, &prev_found)))
 
217
        {
 
218
          /*
 
219
            Didn't find any matching option. Let's see if someone called
 
220
            option with a special option prefix
 
221
          */
 
222
          if (!must_be_var)
 
223
          {
 
224
            if (optend)
 
225
              must_be_var= 1; /* option is followed by an argument */
 
226
            for (i= 0; special_opt_prefix[i]; i++)
 
227
            {
 
228
              if (!getopt_compare_strings(special_opt_prefix[i], opt_str,
 
229
                                          special_opt_prefix_lengths[i]) &&
 
230
                  (opt_str[special_opt_prefix_lengths[i]] == '-' ||
 
231
                   opt_str[special_opt_prefix_lengths[i]] == '_'))
 
232
              {
 
233
                /*
 
234
                  We were called with a special prefix, we can reuse opt_found
 
235
                */
 
236
                opt_str+= special_opt_prefix_lengths[i] + 1;
 
237
                length-= special_opt_prefix_lengths[i] + 1;
 
238
                if (i == OPT_LOOSE)
 
239
                  option_is_loose= 1;
 
240
                if ((opt_found= findopt(opt_str, length, &optp, &prev_found)))
 
241
                {
 
242
                  if (opt_found > 1)
 
243
                  {
 
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],
 
249
                                               prev_found);
 
250
                    return EXIT_AMBIGUOUS_OPTION;
 
251
                  }
 
252
                  switch (i) {
 
253
                  case OPT_SKIP:
 
254
                  case OPT_DISABLE: /* fall through */
 
255
                    /*
 
256
                      double negation is actually enable again,
 
257
                      for example: --skip-option=0 -> option = true
 
258
                    */
 
259
                    optend= (optend && *optend == '0' && !(*(optend + 1))) ?
 
260
                      (char*) "1" : disabled_my_option;
 
261
                    break;
 
262
                  case OPT_ENABLE:
 
263
                    optend= (optend && *optend == '0' && !(*(optend + 1))) ?
 
264
                      disabled_my_option : (char*) "1";
 
265
                    break;
 
266
                  case OPT_MAXIMUM:
 
267
                    set_maximum_value= true;
 
268
                    must_be_var= true;
 
269
                    break;
 
270
                  }
 
271
                  break; /* break from the inner loop, main loop continues */
 
272
                }
 
273
                i= -1; /* restart the loop */
 
274
              }
 
275
            }
 
276
          }
 
277
          if (!opt_found)
 
278
          {
 
279
            if (my_getopt_skip_unknown)
 
280
            {
 
281
              /*
 
282
                preserve all the components of this unknown option, this may
 
283
                occurr when the user provides options like: "-O foo" or
 
284
                "--set-variable foo" (note that theres a space in there)
 
285
                Generally, these kind of options are to be avoided
 
286
              */
 
287
              do {
 
288
                (*argv)[argvpos++]= *first++;
 
289
              } while (first <= pos);
 
290
              continue;
 
291
            }
 
292
            if (must_be_var)
 
293
            {
 
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);
 
299
              if (!option_is_loose)
 
300
                return EXIT_UNKNOWN_VARIABLE;
 
301
            }
 
302
            else
 
303
            {
 
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);
 
309
              if (!option_is_loose)
 
310
                return EXIT_UNKNOWN_OPTION;
 
311
            }
 
312
            if (option_is_loose)
 
313
            {
 
314
              (*argc)--;
 
315
              continue;
 
316
            }
 
317
          }
 
318
        }
 
319
        if (opt_found > 1)
 
320
        {
 
321
          if (must_be_var)
 
322
          {
 
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);
 
327
            return EXIT_VAR_PREFIX_NOT_UNIQUE;
 
328
          }
 
329
          else
 
330
          {
 
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, 
 
335
                                       optp->name);
 
336
            return EXIT_AMBIGUOUS_OPTION;
 
337
          }
 
338
        }
 
339
        if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
 
340
        {
 
341
          if (my_getopt_print_errors)
 
342
            fprintf(stderr,
 
343
                    "%s: %s: Option '%s' used, but is disabled\n", my_progname,
 
344
                    option_is_loose ? "WARNING" : "ERROR", opt_str);
 
345
          if (option_is_loose)
 
346
          {
 
347
            (*argc)--;
 
348
            continue;
 
349
          }
 
350
          return EXIT_OPTION_DISABLED;
 
351
        }
 
352
        if (must_be_var && (optp->var_type & GET_TYPE_MASK) == GET_NO_ARG)
 
353
        {
 
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);
 
358
          return EXIT_NO_ARGUMENT_ALLOWED;
 
359
        }
 
360
        value= optp->var_type & GET_ASK_ADDR ?
 
361
          (*getopt_get_addr)(key_name, (uint) strlen(key_name), optp) : optp->value;
 
362
  
 
363
        if (optp->arg_type == NO_ARG)
 
364
        {
 
365
          if (optend && (optp->var_type & GET_TYPE_MASK) != GET_BOOL)
 
366
          {
 
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);
 
371
            return EXIT_NO_ARGUMENT_ALLOWED;
 
372
          }
 
373
          if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL)
 
374
          {
 
375
            /*
 
376
              Set bool to 1 if no argument or if the user has used
 
377
              --enable-'option-name'.
 
378
              *optend was set to '0' if one used --disable-option
 
379
              */
 
380
            (*argc)--;
 
381
            if (!optend || *optend == '1' ||
 
382
                !my_strcasecmp(&my_charset_latin1, optend, "true"))
 
383
              *((bool*) value)= (bool) 1;
 
384
            else if (*optend == '0' ||
 
385
                     !my_strcasecmp(&my_charset_latin1, optend, "false"))
 
386
              *((bool*) value)= (bool) 0;
 
387
            else
 
388
            {
 
389
              my_getopt_error_reporter(WARNING_LEVEL,
 
390
                                       "%s: ignoring option '--%s' due to \
 
391
invalid value '%s'",
 
392
                                       my_progname, optp->name, optend);
 
393
              continue;
 
394
            }
 
395
            get_one_option(optp->id, optp,
 
396
                           *((bool*) value) ?
 
397
                           (char*) "1" : disabled_my_option);
 
398
            continue;
 
399
          }
 
400
          argument= optend;
 
401
        }
 
402
        else if (optp->arg_type == OPT_ARG &&
 
403
                 (optp->var_type & GET_TYPE_MASK) == GET_BOOL)
 
404
        {
 
405
          if (optend == disabled_my_option)
 
406
            *((bool*) value)= (bool) 0;
 
407
          else
 
408
          {
 
409
            if (!optend) /* No argument -> enable option */
 
410
              *((bool*) value)= (bool) 1;
 
411
            else
 
412
              argument= optend;
 
413
          }
 
414
        }
 
415
        else if (optp->arg_type == REQUIRED_ARG && !optend)
 
416
        {
 
417
          /* Check if there are more arguments after this one */
 
418
          if (!*++pos)
 
419
          {
 
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);
 
424
            return EXIT_ARGUMENT_REQUIRED;
 
425
          }
 
426
          argument= *pos;
 
427
          (*argc)--;
 
428
        }
 
429
        else
 
430
          argument= optend;
 
431
      }
 
432
      else  /* must be short option */
 
433
      {
 
434
        for (optend= cur_arg; *optend; optend++)
 
435
        {
 
436
          opt_found= 0;
 
437
          for (optp= longopts; optp->id; optp++)
 
438
          {
 
439
            if (optp->id == (int) (uchar) *optend)
 
440
            {
 
441
              /* Option recognized. Find next what to do with it */
 
442
              opt_found= 1;
 
443
              if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
 
444
              {
 
445
                if (my_getopt_print_errors)
 
446
                  fprintf(stderr,
 
447
                          "%s: ERROR: Option '-%c' used, but is disabled\n",
 
448
                          my_progname, optp->id);
 
449
                return EXIT_OPTION_DISABLED;
 
450
              }
 
451
              if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL &&
 
452
                  optp->arg_type == NO_ARG)
 
453
              {
 
454
                *((bool*) optp->value)= (bool) 1;
 
455
                get_one_option(optp->id, optp, argument);
 
456
                continue;
 
457
              }
 
458
              else if (optp->arg_type == REQUIRED_ARG ||
 
459
                       optp->arg_type == OPT_ARG)
 
460
              {
 
461
                if (*(optend + 1))
 
462
                {
 
463
                  /* The rest of the option is option argument */
 
464
                  argument= optend + 1;
 
465
                  /* This is in effect a jump out of the outer loop */
 
466
                  optend= (char*) " ";
 
467
                }
 
468
                else
 
469
                {
 
470
                  if (optp->arg_type == OPT_ARG)
 
471
                  {
 
472
                    if (optp->var_type == GET_BOOL)
 
473
                      *((bool*) optp->value)= (bool) 1;
 
474
                    get_one_option(optp->id, optp, argument);
 
475
                    continue;
 
476
                  }
 
477
                  /* Check if there are more arguments after this one */
 
478
                  if (!pos[1])
 
479
                  {
 
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);
 
484
                    return EXIT_ARGUMENT_REQUIRED;
 
485
                  }
 
486
                  argument= *++pos;
 
487
                  (*argc)--;
 
488
                  /* the other loop will break, because *optend + 1 == 0 */
 
489
                }
 
490
              }
 
491
              if ((error= setval(optp, optp->value, argument,
 
492
                                 set_maximum_value)))
 
493
              {
 
494
                my_getopt_error_reporter(ERROR_LEVEL,
 
495
                                         "%s: Error while setting value '%s' to '%s'",
 
496
                                         my_progname, argument, optp->name);
 
497
                return error;
 
498
              }
 
499
              get_one_option(optp->id, optp, argument);
 
500
              break;
 
501
            }
 
502
          }
 
503
          if (!opt_found)
 
504
          {
 
505
            if (my_getopt_print_errors)
 
506
              my_getopt_error_reporter(ERROR_LEVEL,
 
507
                                       "%s: unknown option '-%c'", 
 
508
                                       my_progname, *optend);
 
509
            return EXIT_UNKNOWN_OPTION;
 
510
          }
 
511
        }
 
512
        (*argc)--; /* option handled (short), decrease argument count */
 
513
        continue;
 
514
      }
 
515
      if ((error= setval(optp, value, argument, set_maximum_value)))
 
516
      {
 
517
        my_getopt_error_reporter(ERROR_LEVEL,
 
518
                                 "%s: Error while setting value '%s' to '%s'",
 
519
                                 my_progname, argument, optp->name);
 
520
        return error;
 
521
      }
 
522
      get_one_option(optp->id, optp, argument);
 
523
 
 
524
      (*argc)--; /* option handled (short or long), decrease argument count */
 
525
    }
 
526
    else /* non-option found */
 
527
      (*argv)[argvpos++]= cur_arg;
 
528
  }
 
529
  /*
 
530
    Destroy the first, already handled option, so that programs that look
 
531
    for arguments in 'argv', without checking 'argc', know when to stop.
 
532
    Items in argv, before the destroyed one, are all non-option -arguments
 
533
    to the program, yet to be (possibly) handled.
 
534
  */
 
535
  (*argv)[argvpos]= 0;
 
536
  return 0;
 
537
}
 
538
 
 
539
 
 
540
/*
 
541
  function: check_struct_option
 
542
 
 
543
  Arguments: Current argument under processing from argv and a variable
 
544
  where to store the possible key name.
 
545
 
 
546
  Return value: In case option is a struct option, returns a pointer to
 
547
  the current argument at the position where the struct option (key_name)
 
548
  ends, the next character after the dot. In case argument is not a struct
 
549
  option, returns a pointer to the argument.
 
550
 
 
551
  key_name will hold the name of the key, or 0 if not found.
 
552
*/
 
553
 
 
554
static char *check_struct_option(char *cur_arg, char *key_name)
 
555
{
 
556
  char *ptr, *end;
 
557
 
 
558
  ptr= strcend(cur_arg + 1, '.'); /* Skip the first character */
 
559
  end= strcend(cur_arg, '=');
 
560
 
 
561
  /* 
 
562
     If the first dot is after an equal sign, then it is part
 
563
     of a variable value and the option is not a struct option.
 
564
     Also, if the last character in the string before the ending
 
565
     NULL, or the character right before equal sign is the first
 
566
     dot found, the option is not a struct option.
 
567
  */
 
568
  if (end - ptr > 1)
 
569
  {
 
570
    uint len= (uint) (ptr - cur_arg);
 
571
    set_if_smaller(len, FN_REFLEN-1);
 
572
    strmake(key_name, cur_arg, len);
 
573
    return ++ptr;
 
574
  }
 
575
  else
 
576
  {
 
577
    key_name[0]= 0;
 
578
    return cur_arg;
 
579
  }
 
580
}
 
581
 
 
582
/*
 
583
  function: setval
 
584
 
 
585
  Arguments: opts, argument
 
586
  Will set the option value to given value
 
587
*/
 
588
 
 
589
static int setval(const struct my_option *opts, char **value, char *argument,
 
590
                  bool set_maximum_value)
 
591
{
 
592
  int err= 0;
 
593
 
 
594
  if (value && argument)
 
595
  {
 
596
    char* *result_pos= ((set_maximum_value) ?
 
597
                        opts->u_max_value : value);
 
598
 
 
599
    if (!result_pos)
 
600
      return EXIT_NO_PTR_TO_VARIABLE;
 
601
 
 
602
    switch ((opts->var_type & GET_TYPE_MASK)) {
 
603
    case GET_BOOL: /* If argument differs from 0, enable option, else disable */
 
604
      *((bool*) result_pos)= (bool) atoi(argument) != 0;
 
605
      break;
 
606
    case GET_INT:
 
607
      *((int*) result_pos)= (int) getopt_ll(argument, opts, &err);
 
608
      break;
 
609
    case GET_UINT:
 
610
      *((uint*) result_pos)= (uint) getopt_ull(argument, opts, &err);
 
611
      break;
 
612
    case GET_LONG:
 
613
      *((long*) result_pos)= (long) getopt_ll(argument, opts, &err);
 
614
      break;
 
615
    case GET_ULONG:
 
616
      *((long*) result_pos)= (long) getopt_ull(argument, opts, &err);
 
617
      break;
 
618
    case GET_LL:
 
619
      *((int64_t*) result_pos)= getopt_ll(argument, opts, &err);
 
620
      break;
 
621
    case GET_ULL:
 
622
      *((uint64_t*) result_pos)= getopt_ull(argument, opts, &err);
 
623
      break;
 
624
    case GET_DOUBLE:
 
625
      *((double*) result_pos)= getopt_double(argument, opts, &err);
 
626
      break;
 
627
    case GET_STR:
 
628
      *((char**) result_pos)= argument;
 
629
      break;
 
630
    case GET_STR_ALLOC:
 
631
      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))))
 
634
        return EXIT_OUT_OF_MEMORY;
 
635
      break;
 
636
    case GET_ENUM:
 
637
      if (((*(int*)result_pos)= find_type(argument, opts->typelib, 2) - 1) < 0)
 
638
        return EXIT_ARGUMENT_INVALID;
 
639
      break;
 
640
    case GET_SET:
 
641
      *((uint64_t*)result_pos)= find_typeset(argument, opts->typelib, &err);
 
642
      if (err)
 
643
        return EXIT_ARGUMENT_INVALID;
 
644
      break;
 
645
    default:    /* dummy default to avoid compiler warnings */
 
646
      break;
 
647
    }
 
648
    if (err)
 
649
      return EXIT_UNKNOWN_SUFFIX;
 
650
  }
 
651
  return 0;
 
652
}
 
653
 
 
654
 
 
655
/* 
 
656
  Find option
 
657
 
 
658
  SYNOPSIS
 
659
    findopt()
 
660
    optpat      Prefix of option to find (with - or _)
 
661
    length      Length of optpat
 
662
    opt_res     Options
 
663
    ffname      Place for pointer to first found name
 
664
 
 
665
  IMPLEMENTATION
 
666
    Go through all options in the my_option struct. Return number
 
667
    of options found that match the pattern and in the argument
 
668
    list the option found, if any. In case of ambiguous option, store
 
669
    the name in ffname argument
 
670
 
 
671
    RETURN
 
672
    0    No matching options
 
673
    #   Number of matching options
 
674
        ffname points to first matching option
 
675
*/
 
676
 
 
677
static int findopt(char *optpat, uint length,
 
678
                   const struct my_option **opt_res,
 
679
                   char **ffname)
 
680
{
 
681
  uint count;
 
682
  struct my_option *opt= (struct my_option *) *opt_res;
 
683
 
 
684
  for (count= 0; opt->name; opt++)
 
685
  {
 
686
    if (!getopt_compare_strings(opt->name, optpat, length)) /* match found */
 
687
    {
 
688
      (*opt_res)= opt;
 
689
      if (!opt->name[length])           /* Exact match */
 
690
        return 1;
 
691
      if (!count)
 
692
      {
 
693
        count= 1;
 
694
        *ffname= (char *) opt->name;    /* We only need to know one prev */
 
695
      }
 
696
      else if (strcmp(*ffname, opt->name))
 
697
      {
 
698
        /*
 
699
          The above test is to not count same option twice
 
700
          (see mysql.cc, option "help")
 
701
        */
 
702
        count++;
 
703
      }
 
704
    }
 
705
  }
 
706
  return count;
 
707
}
 
708
 
 
709
 
 
710
/* 
 
711
  function: compare_strings
 
712
 
 
713
  Works like strncmp, other than 1.) considers '-' and '_' the same.
 
714
  2.) Returns -1 if strings differ, 0 if they are equal
 
715
*/
 
716
 
 
717
bool getopt_compare_strings(register const char *s, register const char *t,
 
718
                               uint length)
 
719
{
 
720
  char const *end= s + length;
 
721
  for (;s != end ; s++, t++)
 
722
  {
 
723
    if ((*s != '-' ? *s : '_') != (*t != '-' ? *t : '_'))
 
724
      return 1;
 
725
  }
 
726
  return 0;
 
727
}
 
728
 
 
729
/*
 
730
  function: eval_num_suffix
 
731
 
 
732
  Transforms a number with a suffix to real number. Suffix can
 
733
  be k|K for kilo, m|M for mega or g|G for giga.
 
734
*/
 
735
 
 
736
static int64_t eval_num_suffix(char *argument, int *error, char *option_name)
 
737
{
 
738
  char *endchar;
 
739
  int64_t num;
 
740
  
 
741
  *error= 0;
 
742
  errno= 0;
 
743
  num= strtoll(argument, &endchar, 10);
 
744
  if (errno == ERANGE)
 
745
  {
 
746
    my_getopt_error_reporter(ERROR_LEVEL,
 
747
                             "Incorrect integer value: '%s'", argument);
 
748
    *error= 1;
 
749
    return 0;
 
750
  }
 
751
  if (*endchar == 'k' || *endchar == 'K')
 
752
    num*= 1024L;
 
753
  else if (*endchar == 'm' || *endchar == 'M')
 
754
    num*= 1024L * 1024L;
 
755
  else if (*endchar == 'g' || *endchar == 'G')
 
756
    num*= 1024L * 1024L * 1024L;
 
757
  else if (*endchar)
 
758
  {
 
759
    fprintf(stderr,
 
760
            "Unknown suffix '%c' used for variable '%s' (value '%s')\n",
 
761
            *endchar, option_name, argument);
 
762
    *error= 1;
 
763
    return 0;
 
764
  }
 
765
  return num;
 
766
}
 
767
 
 
768
/* 
 
769
  function: getopt_ll
 
770
 
 
771
  Evaluates and returns the value that user gave as an argument
 
772
  to a variable. Recognizes (case insensitive) K as KILO, M as MEGA
 
773
  and G as GIGA bytes. Some values must be in certain blocks, as
 
774
  defined in the given my_option struct, this function will check
 
775
  that those values are honored.
 
776
  In case of an error, set error value in *err.
 
777
*/
 
778
 
 
779
static int64_t getopt_ll(char *arg, const struct my_option *optp, int *err)
 
780
{
 
781
  int64_t num=eval_num_suffix(arg, err, (char*) optp->name);
 
782
  return getopt_ll_limit_value(num, optp, NULL);
 
783
}
 
784
 
 
785
/*
 
786
  function: getopt_ll_limit_value
 
787
 
 
788
  Applies min/max/block_size to a numeric value of an option.
 
789
  Returns "fixed" value.
 
790
*/
 
791
 
 
792
int64_t getopt_ll_limit_value(int64_t num, const struct my_option *optp,
 
793
                               bool *fix)
 
794
{
 
795
  int64_t old= num;
 
796
  bool adjusted= false;
 
797
  char buf1[255], buf2[255];
 
798
  uint64_t block_size= (optp->block_size ? (uint64_t) optp->block_size : 1L);
 
799
 
 
800
  if (num > 0 && ((uint64_t) num > (uint64_t) optp->max_value) &&
 
801
      optp->max_value) /* if max value is not set -> no upper limit */
 
802
  {
 
803
    num= (uint64_t) optp->max_value;
 
804
    adjusted= true;
 
805
  }
 
806
 
 
807
  switch ((optp->var_type & GET_TYPE_MASK)) {
 
808
  case GET_INT:
 
809
    if (num > (int64_t) INT_MAX)
 
810
    {
 
811
      num= ((int64_t) INT_MAX);
 
812
      adjusted= true;
 
813
    }
 
814
    break;
 
815
  case GET_LONG:
 
816
#if SIZEOF_LONG < SIZEOF_LONG_LONG
 
817
    if (num > (int64_t) LONG_MAX)
 
818
    {
 
819
      num= ((int64_t) LONG_MAX);
 
820
      adjusted= true;
 
821
    }
 
822
#endif
 
823
    break;
 
824
  default:
 
825
    assert((optp->var_type & GET_TYPE_MASK) == GET_LL);
 
826
    break;
 
827
  }
 
828
 
 
829
  num= ((num - optp->sub_size) / block_size);
 
830
  num= (int64_t) (num * block_size);
 
831
 
 
832
  if (num < optp->min_value)
 
833
  {
 
834
    num= optp->min_value;
 
835
    adjusted= true;
 
836
  }
 
837
 
 
838
  if (fix)
 
839
    *fix= adjusted;
 
840
  else if (adjusted)
 
841
    my_getopt_error_reporter(WARNING_LEVEL,
 
842
                             "option '%s': signed value %s adjusted to %s",
 
843
                             optp->name, llstr(old, buf1), llstr(num, buf2));
 
844
  return num;
 
845
}
 
846
 
 
847
/*
 
848
  function: getopt_ull
 
849
 
 
850
  This is the same as getopt_ll, but is meant for unsigned long long
 
851
  values.
 
852
*/
 
853
 
 
854
static uint64_t getopt_ull(char *arg, const struct my_option *optp, int *err)
 
855
{
 
856
  uint64_t num= eval_num_suffix(arg, err, (char*) optp->name);
 
857
  return getopt_ull_limit_value(num, optp, NULL);
 
858
}
 
859
 
 
860
 
 
861
uint64_t getopt_ull_limit_value(uint64_t num, const struct my_option *optp,
 
862
                                 bool *fix)
 
863
{
 
864
  bool adjusted= false;
 
865
  uint64_t old= num;
 
866
  char buf1[255], buf2[255];
 
867
 
 
868
  if ((uint64_t) num > (uint64_t) optp->max_value &&
 
869
      optp->max_value) /* if max value is not set -> no upper limit */
 
870
  {
 
871
    num= (uint64_t) optp->max_value;
 
872
    adjusted= true;
 
873
  }
 
874
 
 
875
  switch ((optp->var_type & GET_TYPE_MASK)) {
 
876
  case GET_UINT:
 
877
    if (num > (uint64_t) UINT_MAX)
 
878
    {
 
879
      num= ((uint64_t) UINT_MAX);
 
880
      adjusted= true;
 
881
    }
 
882
    break;
 
883
  case GET_ULONG:
 
884
#if SIZEOF_LONG < SIZEOF_LONG_LONG
 
885
    if (num > (uint64_t) ULONG_MAX)
 
886
    {
 
887
      num= ((uint64_t) ULONG_MAX);
 
888
      adjusted= true;
 
889
    }
 
890
#endif
 
891
    break;
 
892
  default:
 
893
    assert((optp->var_type & GET_TYPE_MASK) == GET_ULL);
 
894
    break;
 
895
  }
 
896
 
 
897
  if (optp->block_size > 1)
 
898
  {
 
899
    num/= (uint64_t) optp->block_size;
 
900
    num*= (uint64_t) optp->block_size;
 
901
  }
 
902
 
 
903
  if (num < (uint64_t) optp->min_value)
 
904
  {
 
905
    num= (uint64_t) optp->min_value;
 
906
    adjusted= true;
 
907
  }
 
908
 
 
909
  if (fix)
 
910
    *fix= adjusted;
 
911
  else if (adjusted)
 
912
    my_getopt_error_reporter(WARNING_LEVEL,
 
913
                             "option '%s': unsigned value %s adjusted to %s",
 
914
                             optp->name, ullstr(old, buf1), ullstr(num, buf2));
 
915
 
 
916
  return num;
 
917
}
 
918
 
 
919
 
 
920
/*
 
921
  Get double value withing ranges
 
922
 
 
923
  Evaluates and returns the value that user gave as an argument to a variable.
 
924
 
 
925
  RETURN
 
926
    decimal value of arg
 
927
 
 
928
    In case of an error, prints an error message and sets *err to
 
929
    EXIT_ARGUMENT_INVALID.  Otherwise err is not touched
 
930
*/
 
931
 
 
932
static double getopt_double(char *arg, const struct my_option *optp, int *err)
 
933
{
 
934
  double num;
 
935
  int error;
 
936
  char *end= arg + 1000;                     /* Big enough as *arg is \0 terminated */
 
937
  num= my_strtod(arg, &end, &error);
 
938
  if (end[0] != 0 || error)
 
939
  {
 
940
    fprintf(stderr,
 
941
            "%s: ERROR: Invalid decimal value for option '%s'\n",
 
942
            my_progname, optp->name);
 
943
    *err= EXIT_ARGUMENT_INVALID;
 
944
    return 0.0;
 
945
  }
 
946
  if (optp->max_value && num > (double) optp->max_value)
 
947
    num= (double) optp->max_value;
 
948
  return max(num, (double) optp->min_value);
 
949
}
 
950
 
 
951
/*
 
952
  Init one value to it's default values
 
953
 
 
954
  SYNOPSIS
 
955
    init_one_value()
 
956
    option              Option to initialize
 
957
    value               Pointer to variable
 
958
*/
 
959
 
 
960
static void init_one_value(const struct my_option *option, char** variable,
 
961
                           int64_t value)
 
962
{
 
963
  switch ((option->var_type & GET_TYPE_MASK)) {
 
964
  case GET_BOOL:
 
965
    *((bool*) variable)= (bool) value;
 
966
    break;
 
967
  case GET_INT:
 
968
    *((int*) variable)= (int) value;
 
969
    break;
 
970
  case GET_UINT:
 
971
  case GET_ENUM:
 
972
    *((uint*) variable)= (uint) value;
 
973
    break;
 
974
  case GET_LONG:
 
975
    *((long*) variable)= (long) value;
 
976
    break;
 
977
  case GET_ULONG:
 
978
    *((ulong*) variable)= (ulong) value;
 
979
    break;
 
980
  case GET_LL:
 
981
    *((int64_t*) variable)= (int64_t) value;
 
982
    break;
 
983
  case GET_ULL:
 
984
  case GET_SET:
 
985
    *((uint64_t*) variable)=  (uint64_t) value;
 
986
    break;
 
987
  case GET_DOUBLE:
 
988
    *((double*) variable)=  (double) value;
 
989
    break;
 
990
  case GET_STR:
 
991
    /*
 
992
      Do not clear variable value if it has no default value.
 
993
      The default value may already be set.
 
994
      NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
 
995
      so that the value has the same size as a pointer.
 
996
    */
 
997
    if ((char*) (intptr_t) value)
 
998
      *((char**) variable)= (char*) (intptr_t) value;
 
999
    break;
 
1000
  case GET_STR_ALLOC:
 
1001
    /*
 
1002
      Do not clear variable value if it has no default value.
 
1003
      The default value may already be set.
 
1004
      NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
 
1005
      so that the value has the same size as a pointer.
 
1006
    */
 
1007
    if ((char*) (intptr_t) value)
 
1008
    {
 
1009
      my_free((*(char**) variable), MYF(MY_ALLOW_ZERO_PTR));
 
1010
      *((char**) variable)= my_strdup((char*) (intptr_t) value, MYF(MY_WME));
 
1011
    }
 
1012
    break;
 
1013
  default: /* dummy default to avoid compiler warnings */
 
1014
    break;
 
1015
  }
 
1016
  return;
 
1017
}
 
1018
 
 
1019
 
 
1020
/*
 
1021
  Init one value to it's default values
 
1022
 
 
1023
  SYNOPSIS
 
1024
    init_one_value()
 
1025
    option              Option to initialize
 
1026
    value               Pointer to variable
 
1027
*/
 
1028
 
 
1029
static void fini_one_value(const struct my_option *option, char **variable,
 
1030
                           int64_t value __attribute__ ((unused)))
 
1031
{
 
1032
  switch ((option->var_type & GET_TYPE_MASK)) {
 
1033
  case GET_STR_ALLOC:
 
1034
    my_free((*(char**) variable), MYF(MY_ALLOW_ZERO_PTR));
 
1035
    *((char**) variable)= NULL;
 
1036
    break;
 
1037
  default: /* dummy default to avoid compiler warnings */
 
1038
    break;
 
1039
  }
 
1040
  return;
 
1041
}
 
1042
 
 
1043
 
 
1044
void my_cleanup_options(const struct my_option *options)
 
1045
{
 
1046
  init_variables(options, fini_one_value);
 
1047
}
 
1048
 
 
1049
 
 
1050
/* 
 
1051
  initialize all variables to their default values
 
1052
 
 
1053
  SYNOPSIS
 
1054
    init_variables()
 
1055
    options             Array of options
 
1056
 
 
1057
  NOTES
 
1058
    We will initialize the value that is pointed to by options->value.
 
1059
    If the value is of type GET_ASK_ADDR, we will also ask for the address
 
1060
    for a value and initialize.
 
1061
*/
 
1062
 
 
1063
static void init_variables(const struct my_option *options,
 
1064
                           init_func_p init_one_value)
 
1065
{
 
1066
  for (; options->name; options++)
 
1067
  {
 
1068
    char* *variable;
 
1069
    /*
 
1070
      We must set u_max_value first as for some variables
 
1071
      options->u_max_value == options->value and in this case we want to
 
1072
      set the value to default value.
 
1073
    */
 
1074
    if (options->u_max_value)
 
1075
      init_one_value(options, options->u_max_value, options->max_value);
 
1076
    if (options->value)
 
1077
      init_one_value(options, options->value, options->def_value);
 
1078
    if (options->var_type & GET_ASK_ADDR &&
 
1079
        (variable= (*getopt_get_addr)("", 0, options)))
 
1080
      init_one_value(options, variable, options->def_value);
 
1081
  }
 
1082
  return;
 
1083
}
 
1084
 
 
1085
 
 
1086
/*
 
1087
  function: my_print_options
 
1088
 
 
1089
  Print help for all options and variables.
 
1090
*/
 
1091
 
 
1092
#include <help_start.h>
 
1093
 
 
1094
void my_print_help(const struct my_option *options)
 
1095
{
 
1096
  uint col, name_space= 22, comment_space= 57;
 
1097
  const char *line_end;
 
1098
  const struct my_option *optp;
 
1099
 
 
1100
  for (optp= options; optp->id; optp++)
 
1101
  {
 
1102
    if (optp->id < 256)
 
1103
    {
 
1104
      printf("  -%c%s", optp->id, strlen(optp->name) ? ", " : "  ");
 
1105
      col= 6;
 
1106
    }
 
1107
    else
 
1108
    {
 
1109
      printf("  ");
 
1110
      col= 2;
 
1111
    }
 
1112
    if (strlen(optp->name))
 
1113
    {
 
1114
      printf("--%s", optp->name);
 
1115
      col+= 2 + (uint) strlen(optp->name);
 
1116
      if ((optp->var_type & GET_TYPE_MASK) == GET_STR ||
 
1117
          (optp->var_type & GET_TYPE_MASK) == GET_STR_ALLOC)
 
1118
      {
 
1119
        printf("%s=name%s ", optp->arg_type == OPT_ARG ? "[" : "",
 
1120
               optp->arg_type == OPT_ARG ? "]" : "");
 
1121
        col+= (optp->arg_type == OPT_ARG) ? 8 : 6;
 
1122
      }
 
1123
      else if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG ||
 
1124
               (optp->var_type & GET_TYPE_MASK) == GET_BOOL)
 
1125
      {
 
1126
        putchar(' ');
 
1127
        col++;
 
1128
      }
 
1129
      else
 
1130
      {
 
1131
        printf("%s=#%s ", optp->arg_type == OPT_ARG ? "[" : "",
 
1132
               optp->arg_type == OPT_ARG ? "]" : "");
 
1133
        col+= (optp->arg_type == OPT_ARG) ? 5 : 3;
 
1134
      }
 
1135
      if (col > name_space && optp->comment && *optp->comment)
 
1136
      {
 
1137
        putchar('\n');
 
1138
        col= 0;
 
1139
      }
 
1140
    }
 
1141
    for (; col < name_space; col++)
 
1142
      putchar(' ');
 
1143
    if (optp->comment && *optp->comment)
 
1144
    {
 
1145
      const char *comment= optp->comment, *end= strend(comment);
 
1146
 
 
1147
      while ((uint) (end - comment) > comment_space)
 
1148
      {
 
1149
        for (line_end= comment + comment_space; *line_end != ' '; line_end--);
 
1150
        for (; comment != line_end; comment++)
 
1151
          putchar(*comment);
 
1152
        comment++; /* skip the space, as a newline will take it's place now */
 
1153
        putchar('\n');
 
1154
        for (col= 0; col < name_space; col++)
 
1155
          putchar(' ');
 
1156
      }
 
1157
      printf("%s", comment);
 
1158
    }
 
1159
    putchar('\n');
 
1160
    if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG ||
 
1161
             (optp->var_type & GET_TYPE_MASK) == GET_BOOL)
 
1162
    {
 
1163
      if (optp->def_value != 0)
 
1164
      {
 
1165
        printf("%*s(Defaults to on; use --skip-%s to disable.)\n", name_space, "", optp->name);
 
1166
      }
 
1167
    }
 
1168
  }
 
1169
}
 
1170
 
 
1171
 
 
1172
/*
 
1173
  function: my_print_options
 
1174
 
 
1175
  Print variables.
 
1176
*/
 
1177
 
 
1178
void my_print_variables(const struct my_option *options)
 
1179
{
 
1180
  uint name_space= 34, length, nr;
 
1181
  uint64_t bit, llvalue;
 
1182
  char buff[255];
 
1183
  const struct my_option *optp;
 
1184
 
 
1185
  printf("\nVariables (--variable-name=value)\n");
 
1186
  printf("and boolean options {false|true}  Value (after reading options)\n");
 
1187
  printf("--------------------------------- -----------------------------\n");
 
1188
  for (optp= options; optp->id; optp++)
 
1189
  {
 
1190
    char* *value= (optp->var_type & GET_ASK_ADDR ?
 
1191
                  (*getopt_get_addr)("", 0, optp) : optp->value);
 
1192
    if (value)
 
1193
    {
 
1194
      printf("%s ", optp->name);
 
1195
      length= (uint) strlen(optp->name)+1;
 
1196
      for (; length < name_space; length++)
 
1197
        putchar(' ');
 
1198
      switch ((optp->var_type & GET_TYPE_MASK)) {
 
1199
      case GET_SET:
 
1200
        if (!(llvalue= *(uint64_t*) value))
 
1201
          printf("%s\n", "(No default value)");
 
1202
        else
 
1203
        for (nr= 0, bit= 1; llvalue && nr < optp->typelib->count; nr++, bit<<=1)
 
1204
        {
 
1205
          if (!(bit & llvalue))
 
1206
            continue;
 
1207
          llvalue&= ~bit;
 
1208
          printf( llvalue ? "%s," : "%s\n", get_type(optp->typelib, nr));
 
1209
        }
 
1210
        break;
 
1211
      case GET_ENUM:
 
1212
        printf("%s\n", get_type(optp->typelib, *(uint*) value));
 
1213
        break;
 
1214
      case GET_STR:
 
1215
      case GET_STR_ALLOC:                    /* fall through */
 
1216
        printf("%s\n", *((char**) value) ? *((char**) value) :
 
1217
               "(No default value)");
 
1218
        break;
 
1219
      case GET_BOOL:
 
1220
        printf("%s\n", *((bool*) value) ? "true" : "false");
 
1221
        break;
 
1222
      case GET_INT:
 
1223
        printf("%d\n", *((int*) value));
 
1224
        break;
 
1225
      case GET_UINT:
 
1226
        printf("%d\n", *((uint*) value));
 
1227
        break;
 
1228
      case GET_LONG:
 
1229
        printf("%ld\n", *((long*) value));
 
1230
        break;
 
1231
      case GET_ULONG:
 
1232
        printf("%lu\n", *((ulong*) value));
 
1233
        break;
 
1234
      case GET_LL:
 
1235
        printf("%s\n", llstr(*((int64_t*) value), buff));
 
1236
        break;
 
1237
      case GET_ULL:
 
1238
        int64_t2str(*((uint64_t*) value), buff, 10);
 
1239
        printf("%s\n", buff);
 
1240
        break;
 
1241
      case GET_DOUBLE:
 
1242
        printf("%g\n", *(double*) value);
 
1243
        break;
 
1244
      default:
 
1245
        printf("(Disabled)\n");
 
1246
        break;
 
1247
      }
 
1248
    }
 
1249
  }
 
1250
}
 
1251
 
 
1252
#include <help_end.h>