~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/my_getopt.cc

Merge Stewart's dead code removal

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