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