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