~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/my_getopt.c

  • Committer: Jay Pipes
  • Date: 2008-09-11 16:03:22 UTC
  • mto: (383.5.1 trunk)
  • mto: This revision was merged to the branch mainline in revision 386.
  • Revision ID: jay@mysql.com-20080911160322-vrl0k1djo6q6ytv1
Removed SQL_MODE variances from comment_table.test and ensured correct error thrown when a comment that is too long was input.  After moving to proto buffer definition for table, the 2048 length will go away.

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, uint 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 uint 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
  uint 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) (uchar) *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
    uint 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
        my_free((*(char**) result_pos), MYF(MY_WME | MY_FAE));
 
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, uint length,
 
685
                   const struct my_option **opt_res,
 
686
                   char **ffname)
 
687
{
 
688
  uint 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
                               uint 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 SIZEOF_LONG < SIZEOF_LONG_LONG
 
824
    if (num > (int64_t) LONG_MAX)
 
825
    {
 
826
      num= ((int64_t) LONG_MAX);
 
827
      adjusted= true;
 
828
    }
 
829
#endif
 
830
    break;
 
831
  default:
 
832
    assert((optp->var_type & GET_TYPE_MASK) == GET_LL);
 
833
    break;
 
834
  }
 
835
 
 
836
  num= ((num - optp->sub_size) / block_size);
 
837
  num= (int64_t) (num * block_size);
 
838
 
 
839
  if (num < optp->min_value)
 
840
  {
 
841
    num= optp->min_value;
 
842
    adjusted= true;
 
843
  }
 
844
 
 
845
  if (fix)
 
846
    *fix= adjusted;
 
847
  else if (adjusted)
 
848
    my_getopt_error_reporter(WARNING_LEVEL,
 
849
                             "option '%s': signed value %s adjusted to %s",
 
850
                             optp->name, llstr(old, buf1), llstr(num, buf2));
 
851
  return num;
 
852
}
 
853
 
 
854
/*
 
855
  function: getopt_ull
 
856
 
 
857
  This is the same as getopt_ll, but is meant for unsigned long long
 
858
  values.
 
859
*/
 
860
 
 
861
static uint64_t getopt_ull(char *arg, const struct my_option *optp, int *err)
 
862
{
 
863
  uint64_t num= eval_num_suffix(arg, err, (char*) optp->name);
 
864
  return getopt_ull_limit_value(num, optp, NULL);
 
865
}
 
866
 
 
867
 
 
868
uint64_t getopt_ull_limit_value(uint64_t num, const struct my_option *optp,
 
869
                                 bool *fix)
 
870
{
 
871
  bool adjusted= false;
 
872
  uint64_t old= num;
 
873
  char buf1[255], buf2[255];
 
874
 
 
875
  if ((uint64_t) num > (uint64_t) optp->max_value &&
 
876
      optp->max_value) /* if max value is not set -> no upper limit */
 
877
  {
 
878
    num= (uint64_t) optp->max_value;
 
879
    adjusted= true;
 
880
  }
 
881
 
 
882
  switch ((optp->var_type & GET_TYPE_MASK)) {
 
883
  case GET_UINT:
 
884
    if (num > (uint64_t) UINT_MAX)
 
885
    {
 
886
      num= ((uint64_t) UINT_MAX);
 
887
      adjusted= true;
 
888
    }
 
889
    break;
 
890
  case GET_ULONG:
 
891
#if SIZEOF_LONG < SIZEOF_LONG_LONG
 
892
    if (num > (uint64_t) ULONG_MAX)
 
893
    {
 
894
      num= ((uint64_t) ULONG_MAX);
 
895
      adjusted= true;
 
896
    }
 
897
#endif
 
898
    break;
 
899
  default:
 
900
    assert((optp->var_type & GET_TYPE_MASK) == GET_ULL);
 
901
    break;
 
902
  }
 
903
 
 
904
  if (optp->block_size > 1)
 
905
  {
 
906
    num/= (uint64_t) optp->block_size;
 
907
    num*= (uint64_t) optp->block_size;
 
908
  }
 
909
 
 
910
  if (num < (uint64_t) optp->min_value)
 
911
  {
 
912
    num= (uint64_t) optp->min_value;
 
913
    adjusted= true;
 
914
  }
 
915
 
 
916
  if (fix)
 
917
    *fix= adjusted;
 
918
  else if (adjusted)
 
919
    my_getopt_error_reporter(WARNING_LEVEL,
 
920
                             "option '%s': unsigned value %s adjusted to %s",
 
921
                             optp->name, ullstr(old, buf1), ullstr(num, buf2));
 
922
 
 
923
  return num;
 
924
}
 
925
 
 
926
 
 
927
/*
 
928
  Get double value withing ranges
 
929
 
 
930
  Evaluates and returns the value that user gave as an argument to a variable.
 
931
 
 
932
  RETURN
 
933
    decimal value of arg
 
934
 
 
935
    In case of an error, prints an error message and sets *err to
 
936
    EXIT_ARGUMENT_INVALID.  Otherwise err is not touched
 
937
*/
 
938
 
 
939
static double getopt_double(char *arg, const struct my_option *optp, int *err)
 
940
{
 
941
  double num;
 
942
  int error;
 
943
  char *end= arg + 1000;                     /* Big enough as *arg is \0 terminated */
 
944
  num= my_strtod(arg, &end, &error);
 
945
  if (end[0] != 0 || error)
 
946
  {
 
947
    fprintf(stderr,
 
948
            _("%s: ERROR: Invalid decimal value for option '%s'\n"),
 
949
            my_progname, optp->name);
 
950
    *err= EXIT_ARGUMENT_INVALID;
 
951
    return 0.0;
 
952
  }
 
953
  if (optp->max_value && num > (double) optp->max_value)
 
954
    num= (double) optp->max_value;
 
955
  return max(num, (double) optp->min_value);
 
956
}
 
957
 
 
958
/*
 
959
  Init one value to it's default values
 
960
 
 
961
  SYNOPSIS
 
962
    init_one_value()
 
963
    option              Option to initialize
 
964
    value               Pointer to variable
 
965
*/
 
966
 
 
967
static void init_one_value(const struct my_option *option, char** variable,
 
968
                           int64_t value)
 
969
{
 
970
  switch ((option->var_type & GET_TYPE_MASK)) {
 
971
  case GET_BOOL:
 
972
    *((bool*) variable)= (bool) value;
 
973
    break;
 
974
  case GET_INT:
 
975
    *((int*) variable)= (int) value;
 
976
    break;
 
977
  case GET_UINT:
 
978
  case GET_ENUM:
 
979
    *((uint*) variable)= (uint) value;
 
980
    break;
 
981
  case GET_LONG:
 
982
    *((long*) variable)= (long) value;
 
983
    break;
 
984
  case GET_ULONG:
 
985
    *((uint32_t*) variable)= (uint32_t) value;
 
986
    break;
 
987
  case GET_LL:
 
988
    *((int64_t*) variable)= (int64_t) value;
 
989
    break;
 
990
  case GET_ULL:
 
991
  case GET_SET:
 
992
    *((uint64_t*) variable)=  (uint64_t) value;
 
993
    break;
 
994
  case GET_DOUBLE:
 
995
    *((double*) variable)=  (double) value;
 
996
    break;
 
997
  case GET_STR:
 
998
    /*
 
999
      Do not clear variable value if it has no default value.
 
1000
      The default value may already be set.
 
1001
      NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
 
1002
      so that the value has the same size as a pointer.
 
1003
    */
 
1004
    if ((char*) (intptr_t) value)
 
1005
      *((char**) variable)= (char*) (intptr_t) value;
 
1006
    break;
 
1007
  case GET_STR_ALLOC:
 
1008
    /*
 
1009
      Do not clear variable value if it has no default value.
 
1010
      The default value may already be set.
 
1011
      NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
 
1012
      so that the value has the same size as a pointer.
 
1013
    */
 
1014
    if ((char*) (intptr_t) value)
 
1015
    {
 
1016
      my_free((*(char**) variable), MYF(MY_ALLOW_ZERO_PTR));
 
1017
      *((char**) variable)= my_strdup((char*) (intptr_t) value, MYF(MY_WME));
 
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 value __attribute__ ((unused)))
 
1038
{
 
1039
  switch ((option->var_type & GET_TYPE_MASK)) {
 
1040
  case GET_STR_ALLOC:
 
1041
    my_free((*(char**) variable), MYF(MY_ALLOW_ZERO_PTR));
 
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
  uint 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 + (uint) 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 ((uint) (end - comment) > comment_space)
 
1153
      {
 
1154
        for (line_end= comment + comment_space; *line_end != ' '; line_end--);
 
1155
        for (; comment != line_end; comment++)
 
1156
          putchar(*comment);
 
1157
        comment++; /* skip the space, as a newline will take it's place now */
 
1158
        putchar('\n');
 
1159
        for (col= 0; col < name_space; col++)
 
1160
          putchar(' ');
 
1161
      }
 
1162
      printf("%s", comment);
 
1163
    }
 
1164
    putchar('\n');
 
1165
    if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG ||
 
1166
             (optp->var_type & GET_TYPE_MASK) == GET_BOOL)
 
1167
    {
 
1168
      if (optp->def_value != 0)
 
1169
      {
 
1170
        printf(_("%*s(Defaults to on; use --skip-%s to disable.)\n"), name_space, "", optp->name);
 
1171
      }
 
1172
    }
 
1173
  }
 
1174
}
 
1175
 
 
1176
 
 
1177
/*
 
1178
  function: my_print_options
 
1179
 
 
1180
  Print variables.
 
1181
*/
 
1182
 
 
1183
void my_print_variables(const struct my_option *options)
 
1184
{
 
1185
  uint name_space= 34, length, nr;
 
1186
  uint64_t bit, llvalue;
 
1187
  char buff[255];
 
1188
  const struct my_option *optp;
 
1189
 
 
1190
  printf(_("\nVariables (--variable-name=value)\n"
 
1191
         "and boolean options {false|true}  Value (after reading options)\n"
 
1192
         "--------------------------------- -----------------------------\n"));
 
1193
  for (optp= options; optp->id; optp++)
 
1194
  {
 
1195
    char* *value= (optp->var_type & GET_ASK_ADDR ?
 
1196
                  (*getopt_get_addr)("", 0, optp) : optp->value);
 
1197
    if (value)
 
1198
    {
 
1199
      printf("%s ", optp->name);
 
1200
      length= (uint) strlen(optp->name)+1;
 
1201
      for (; length < name_space; length++)
 
1202
        putchar(' ');
 
1203
      switch ((optp->var_type & GET_TYPE_MASK)) {
 
1204
      case GET_SET:
 
1205
        if (!(llvalue= *(uint64_t*) value))
 
1206
          printf("%s\n", _("(No default value)"));
 
1207
        else
 
1208
        for (nr= 0, bit= 1; llvalue && nr < optp->typelib->count; nr++, bit<<=1)
 
1209
        {
 
1210
          if (!(bit & llvalue))
 
1211
            continue;
 
1212
          llvalue&= ~bit;
 
1213
          printf( llvalue ? "%s," : "%s\n", get_type(optp->typelib, nr));
 
1214
        }
 
1215
        break;
 
1216
      case GET_ENUM:
 
1217
        printf("%s\n", get_type(optp->typelib, *(uint*) value));
 
1218
        break;
 
1219
      case GET_STR:
 
1220
      case GET_STR_ALLOC:                    /* fall through */
 
1221
        printf("%s\n", *((char**) value) ? *((char**) value) :
 
1222
               _("(No default value)"));
 
1223
        break;
 
1224
      case GET_BOOL:
 
1225
        printf("%s\n", *((bool*) value) ? _("true") : _("false"));
 
1226
        break;
 
1227
      case GET_INT:
 
1228
        printf("%d\n", *((int*) value));
 
1229
        break;
 
1230
      case GET_UINT:
 
1231
        printf("%d\n", *((uint*) value));
 
1232
        break;
 
1233
      case GET_LONG:
 
1234
        printf("%ld\n", *((long*) value));
 
1235
        break;
 
1236
      case GET_ULONG:
 
1237
        printf("%u\n", *((uint32_t*) value));
 
1238
        break;
 
1239
      case GET_LL:
 
1240
        printf("%s\n", llstr(*((int64_t*) value), buff));
 
1241
        break;
 
1242
      case GET_ULL:
 
1243
        int64_t2str(*((uint64_t*) value), buff, 10);
 
1244
        printf("%s\n", buff);
 
1245
        break;
 
1246
      case GET_DOUBLE:
 
1247
        printf("%g\n", *(double*) value);
 
1248
        break;
 
1249
      default:
 
1250
        printf(_("(Disabled)\n"));
 
1251
        break;
 
1252
      }
 
1253
    }
 
1254
  }
 
1255
}