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