~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/my_getopt.c

  • Committer: Monty Taylor
  • Date: 2008-08-01 22:33:44 UTC
  • mto: (236.1.42 codestyle)
  • mto: This revision was merged to the branch mainline in revision 261.
  • Revision ID: monty@inaugust.com-20080801223344-vzhlflfmtijp1imv
First pass at gettexizing the error messages.

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