~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/my_getopt.c

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

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