~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/my_getopt.c

  • Committer: Monty Taylor
  • Date: 2008-10-09 22:38:27 UTC
  • mto: This revision was merged to the branch mainline in revision 497.
  • Revision ID: monty@inaugust.com-20081009223827-bc9gvpiplsmvpwyq
Moved test() to its own file.
Made a new function to possibly replace int10_to_str.

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