~drizzle-trunk/drizzle/development

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