~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/my_getopt.cc

  • Committer: Monty Taylor
  • Date: 2010-03-06 02:08:13 UTC
  • mto: This revision was merged to the branch mainline in revision 1381.
  • Revision ID: mordred@inaugust.com-20100306020813-c37d0b39004nl1zf
Remove plugin deinit.

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