~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
212.5.39 by Monty Taylor
Phew. Moved my_base and my_global.
16
#include "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
        {
214
	  length= (uint) (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 ?
373
	  (*getopt_get_addr)(key_name, (uint) 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
  {
482 by Brian Aker
Remove uint.
582
    uint32_t len= (uint) (ptr - cur_arg);
1 by brian
clean slate
583
    set_if_smaller(len, 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:
615 by Brian Aker
Added 32bit system variable support
619
      *((uint32_t*) result_pos)= (uint) getopt_ull(argument, opts, &err);
1 by brian
clean slate
620
      break;
621
    case GET_LONG:
622
      *((long*) result_pos)= (long) getopt_ll(argument, opts, &err);
623
      break;
624
    case GET_ULONG:
625
      *((long*) result_pos)= (long) getopt_ull(argument, opts, &err);
626
      break;
627
    case GET_LL:
152 by Brian Aker
longlong replacement
628
      *((int64_t*) result_pos)= getopt_ll(argument, opts, &err);
1 by brian
clean slate
629
      break;
630
    case GET_ULL:
151 by Brian Aker
Ulonglong to uint64_t
631
      *((uint64_t*) result_pos)= getopt_ull(argument, opts, &err);
1 by brian
clean slate
632
      break;
629.4.1 by Monty Taylor
First step in support size_t sys_var stuff.
633
    case GET_SIZE:
634
      *((size_t*) result_pos)= getopt_size(argument, opts, &err);
635
      break;
1 by brian
clean slate
636
    case GET_DOUBLE:
637
      *((double*) result_pos)= getopt_double(argument, opts, &err);
638
      break;
639
    case GET_STR:
640
      *((char**) result_pos)= argument;
641
      break;
642
    case GET_STR_ALLOC:
643
      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.
644
	free((*(char**) result_pos));
656.1.26 by Monty Taylor
Finally removed all of the my_malloc stuff.
645
      if (!(*((char**) result_pos)= strdup(argument)))
1 by brian
clean slate
646
	return EXIT_OUT_OF_MEMORY;
647
      break;
648
    case GET_ENUM:
649
      if (((*(int*)result_pos)= find_type(argument, opts->typelib, 2) - 1) < 0)
650
        return EXIT_ARGUMENT_INVALID;
651
      break;
652
    case GET_SET:
151 by Brian Aker
Ulonglong to uint64_t
653
      *((uint64_t*)result_pos)= find_typeset(argument, opts->typelib, &err);
1 by brian
clean slate
654
      if (err)
655
        return EXIT_ARGUMENT_INVALID;
656
      break;
657
    default:    /* dummy default to avoid compiler warnings */
658
      break;
659
    }
660
    if (err)
661
      return EXIT_UNKNOWN_SUFFIX;
662
  }
663
  return 0;
664
}
665
666
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
667
/*
1 by brian
clean slate
668
  Find option
669
670
  SYNOPSIS
671
    findopt()
672
    optpat	Prefix of option to find (with - or _)
673
    length	Length of optpat
674
    opt_res	Options
675
    ffname	Place for pointer to first found name
676
677
  IMPLEMENTATION
678
    Go through all options in the my_option struct. Return number
679
    of options found that match the pattern and in the argument
680
    list the option found, if any. In case of ambiguous option, store
681
    the name in ffname argument
682
683
    RETURN
684
    0    No matching options
685
    #   Number of matching options
686
        ffname points to first matching option
687
*/
688
482 by Brian Aker
Remove uint.
689
static int findopt(char *optpat, uint32_t length,
1 by brian
clean slate
690
		   const struct my_option **opt_res,
691
		   char **ffname)
692
{
482 by Brian Aker
Remove uint.
693
  uint32_t count;
1 by brian
clean slate
694
  struct my_option *opt= (struct my_option *) *opt_res;
695
696
  for (count= 0; opt->name; opt++)
697
  {
698
    if (!getopt_compare_strings(opt->name, optpat, length)) /* match found */
699
    {
700
      (*opt_res)= opt;
701
      if (!opt->name[length])		/* Exact match */
702
	return 1;
703
      if (!count)
704
      {
705
	count= 1;
706
	*ffname= (char *) opt->name;	/* We only need to know one prev */
707
      }
708
      else if (strcmp(*ffname, opt->name))
709
      {
710
	/*
711
	  The above test is to not count same option twice
712
	  (see mysql.cc, option "help")
713
	*/
714
	count++;
715
      }
716
    }
717
  }
718
  return count;
719
}
720
721
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
722
/*
1 by brian
clean slate
723
  function: compare_strings
724
725
  Works like strncmp, other than 1.) considers '-' and '_' the same.
726
  2.) Returns -1 if strings differ, 0 if they are equal
727
*/
728
143 by Brian Aker
Bool cleanup.
729
bool getopt_compare_strings(register const char *s, register const char *t,
482 by Brian Aker
Remove uint.
730
			       uint32_t length)
1 by brian
clean slate
731
{
732
  char const *end= s + length;
733
  for (;s != end ; s++, t++)
734
  {
735
    if ((*s != '-' ? *s : '_') != (*t != '-' ? *t : '_'))
736
      return 1;
737
  }
738
  return 0;
739
}
740
741
/*
742
  function: eval_num_suffix
743
744
  Transforms a number with a suffix to real number. Suffix can
745
  be k|K for kilo, m|M for mega or g|G for giga.
746
*/
747
152 by Brian Aker
longlong replacement
748
static int64_t eval_num_suffix(char *argument, int *error, char *option_name)
1 by brian
clean slate
749
{
750
  char *endchar;
152 by Brian Aker
longlong replacement
751
  int64_t num;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
752
1 by brian
clean slate
753
  *error= 0;
754
  errno= 0;
755
  num= strtoll(argument, &endchar, 10);
756
  if (errno == ERANGE)
757
  {
758
    my_getopt_error_reporter(ERROR_LEVEL,
759
                             "Incorrect integer value: '%s'", argument);
760
    *error= 1;
761
    return 0;
762
  }
763
  if (*endchar == 'k' || *endchar == 'K')
764
    num*= 1024L;
765
  else if (*endchar == 'm' || *endchar == 'M')
766
    num*= 1024L * 1024L;
767
  else if (*endchar == 'g' || *endchar == 'G')
768
    num*= 1024L * 1024L * 1024L;
769
  else if (*endchar)
770
  {
771
    fprintf(stderr,
264.1.2 by Monty Taylor
Added some strings from my_error and my_getopt we'd missed before.
772
	    _("Unknown suffix '%c' used for variable '%s' (value '%s')\n"),
1 by brian
clean slate
773
	    *endchar, option_name, argument);
774
    *error= 1;
775
    return 0;
776
  }
777
  return num;
778
}
779
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
780
/*
1 by brian
clean slate
781
  function: getopt_ll
782
783
  Evaluates and returns the value that user gave as an argument
784
  to a variable. Recognizes (case insensitive) K as KILO, M as MEGA
785
  and G as GIGA bytes. Some values must be in certain blocks, as
786
  defined in the given my_option struct, this function will check
787
  that those values are honored.
788
  In case of an error, set error value in *err.
789
*/
790
152 by Brian Aker
longlong replacement
791
static int64_t getopt_ll(char *arg, const struct my_option *optp, int *err)
1 by brian
clean slate
792
{
152 by Brian Aker
longlong replacement
793
  int64_t num=eval_num_suffix(arg, err, (char*) optp->name);
1 by brian
clean slate
794
  return getopt_ll_limit_value(num, optp, NULL);
795
}
796
797
/*
798
  function: getopt_ll_limit_value
799
800
  Applies min/max/block_size to a numeric value of an option.
801
  Returns "fixed" value.
802
*/
803
152 by Brian Aker
longlong replacement
804
int64_t getopt_ll_limit_value(int64_t num, const struct my_option *optp,
143 by Brian Aker
Bool cleanup.
805
                               bool *fix)
1 by brian
clean slate
806
{
152 by Brian Aker
longlong replacement
807
  int64_t old= num;
163 by Brian Aker
Merge Monty's code.
808
  bool adjusted= false;
1 by brian
clean slate
809
  char buf1[255], buf2[255];
151 by Brian Aker
Ulonglong to uint64_t
810
  uint64_t block_size= (optp->block_size ? (uint64_t) optp->block_size : 1L);
1 by brian
clean slate
811
151 by Brian Aker
Ulonglong to uint64_t
812
  if (num > 0 && ((uint64_t) num > (uint64_t) optp->max_value) &&
1 by brian
clean slate
813
      optp->max_value) /* if max value is not set -> no upper limit */
814
  {
151 by Brian Aker
Ulonglong to uint64_t
815
    num= (uint64_t) optp->max_value;
163 by Brian Aker
Merge Monty's code.
816
    adjusted= true;
1 by brian
clean slate
817
  }
818
819
  switch ((optp->var_type & GET_TYPE_MASK)) {
820
  case GET_INT:
152 by Brian Aker
longlong replacement
821
    if (num > (int64_t) INT_MAX)
1 by brian
clean slate
822
    {
152 by Brian Aker
longlong replacement
823
      num= ((int64_t) INT_MAX);
163 by Brian Aker
Merge Monty's code.
824
      adjusted= true;
1 by brian
clean slate
825
    }
826
    break;
827
  case GET_LONG:
481.1.5 by Monty Taylor
Removed sizeof(long) sizeof(long long) checks.
828
    if (num > (int64_t) INT32_MAX)
1 by brian
clean slate
829
    {
481.1.5 by Monty Taylor
Removed sizeof(long) sizeof(long long) checks.
830
      num= ((int64_t) INT32_MAX);
163 by Brian Aker
Merge Monty's code.
831
      adjusted= true;
1 by brian
clean slate
832
    }
833
    break;
834
  default:
51.3.17 by Jay Pipes
Phase 4 - Remove DBUG from mysys
835
    assert((optp->var_type & GET_TYPE_MASK) == GET_LL);
1 by brian
clean slate
836
    break;
837
  }
838
839
  num= ((num - optp->sub_size) / block_size);
152 by Brian Aker
longlong replacement
840
  num= (int64_t) (num * block_size);
1 by brian
clean slate
841
842
  if (num < optp->min_value)
843
  {
844
    num= optp->min_value;
163 by Brian Aker
Merge Monty's code.
845
    adjusted= true;
1 by brian
clean slate
846
  }
847
848
  if (fix)
849
    *fix= adjusted;
850
  else if (adjusted)
851
    my_getopt_error_reporter(WARNING_LEVEL,
852
                             "option '%s': signed value %s adjusted to %s",
853
                             optp->name, llstr(old, buf1), llstr(num, buf2));
854
  return num;
855
}
856
857
/*
858
  function: getopt_ull
859
481.1.2 by Monty Taylor
Replaced all unsigned long long with uint64_t.
860
  This is the same as getopt_ll, but is meant for uint64_t
1 by brian
clean slate
861
  values.
862
*/
863
151 by Brian Aker
Ulonglong to uint64_t
864
static uint64_t getopt_ull(char *arg, const struct my_option *optp, int *err)
1 by brian
clean slate
865
{
151 by Brian Aker
Ulonglong to uint64_t
866
  uint64_t num= eval_num_suffix(arg, err, (char*) optp->name);
1 by brian
clean slate
867
  return getopt_ull_limit_value(num, optp, NULL);
868
}
869
870
629.4.1 by Monty Taylor
First step in support size_t sys_var stuff.
871
static size_t getopt_size(char *arg, const struct my_option *optp, int *err)
872
{
873
  return (size_t)getopt_ull(arg, optp, err);
874
}
875
876
877
151 by Brian Aker
Ulonglong to uint64_t
878
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.
879
				bool *fix)
1 by brian
clean slate
880
{
163 by Brian Aker
Merge Monty's code.
881
  bool adjusted= false;
151 by Brian Aker
Ulonglong to uint64_t
882
  uint64_t old= num;
1 by brian
clean slate
883
  char buf1[255], buf2[255];
884
151 by Brian Aker
Ulonglong to uint64_t
885
  if ((uint64_t) num > (uint64_t) optp->max_value &&
1 by brian
clean slate
886
      optp->max_value) /* if max value is not set -> no upper limit */
887
  {
151 by Brian Aker
Ulonglong to uint64_t
888
    num= (uint64_t) optp->max_value;
163 by Brian Aker
Merge Monty's code.
889
    adjusted= true;
1 by brian
clean slate
890
  }
891
892
  switch ((optp->var_type & GET_TYPE_MASK)) {
893
  case GET_UINT:
151 by Brian Aker
Ulonglong to uint64_t
894
    if (num > (uint64_t) UINT_MAX)
1 by brian
clean slate
895
    {
151 by Brian Aker
Ulonglong to uint64_t
896
      num= ((uint64_t) UINT_MAX);
163 by Brian Aker
Merge Monty's code.
897
      adjusted= true;
1 by brian
clean slate
898
    }
899
    break;
900
  case GET_ULONG:
481.1.5 by Monty Taylor
Removed sizeof(long) sizeof(long long) checks.
901
    if (num > (uint64_t) UINT32_MAX)
1 by brian
clean slate
902
    {
481.1.5 by Monty Taylor
Removed sizeof(long) sizeof(long long) checks.
903
      num= ((uint64_t) UINT32_MAX);
163 by Brian Aker
Merge Monty's code.
904
      adjusted= true;
1 by brian
clean slate
905
    }
906
    break;
629.4.1 by Monty Taylor
First step in support size_t sys_var stuff.
907
  case GET_SIZE:
908
    if (num > (uint64_t) SIZE_MAX)
909
    {
910
      num= ((uint64_t) SIZE_MAX);
911
      adjusted= true;
912
    }
913
    break;
1 by brian
clean slate
914
  default:
51.3.17 by Jay Pipes
Phase 4 - Remove DBUG from mysys
915
    assert((optp->var_type & GET_TYPE_MASK) == GET_ULL);
1 by brian
clean slate
916
    break;
917
  }
918
919
  if (optp->block_size > 1)
920
  {
151 by Brian Aker
Ulonglong to uint64_t
921
    num/= (uint64_t) optp->block_size;
922
    num*= (uint64_t) optp->block_size;
1 by brian
clean slate
923
  }
924
151 by Brian Aker
Ulonglong to uint64_t
925
  if (num < (uint64_t) optp->min_value)
1 by brian
clean slate
926
  {
151 by Brian Aker
Ulonglong to uint64_t
927
    num= (uint64_t) optp->min_value;
163 by Brian Aker
Merge Monty's code.
928
    adjusted= true;
1 by brian
clean slate
929
  }
930
931
  if (fix)
932
    *fix= adjusted;
933
  else if (adjusted)
934
    my_getopt_error_reporter(WARNING_LEVEL,
935
                             "option '%s': unsigned value %s adjusted to %s",
936
                             optp->name, ullstr(old, buf1), ullstr(num, buf2));
937
938
  return num;
939
}
940
941
942
/*
943
  Get double value withing ranges
944
945
  Evaluates and returns the value that user gave as an argument to a variable.
946
947
  RETURN
948
    decimal value of arg
949
950
    In case of an error, prints an error message and sets *err to
951
    EXIT_ARGUMENT_INVALID.  Otherwise err is not touched
952
*/
953
954
static double getopt_double(char *arg, const struct my_option *optp, int *err)
955
{
956
  double num;
957
  int error;
958
  char *end= arg + 1000;                     /* Big enough as *arg is \0 terminated */
959
  num= my_strtod(arg, &end, &error);
960
  if (end[0] != 0 || error)
961
  {
962
    fprintf(stderr,
264.1.2 by Monty Taylor
Added some strings from my_error and my_getopt we'd missed before.
963
            _("%s: ERROR: Invalid decimal value for option '%s'\n"),
1 by brian
clean slate
964
            my_progname, optp->name);
965
    *err= EXIT_ARGUMENT_INVALID;
966
    return 0.0;
967
  }
968
  if (optp->max_value && num > (double) optp->max_value)
969
    num= (double) optp->max_value;
398.1.4 by Monty Taylor
Renamed max/min.
970
  return cmax(num, (double) optp->min_value);
1 by brian
clean slate
971
}
972
973
/*
974
  Init one value to it's default values
975
976
  SYNOPSIS
977
    init_one_value()
978
    option		Option to initialize
979
    value		Pointer to variable
980
*/
981
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
982
static void init_one_value(const struct my_option *option, char** variable,
152 by Brian Aker
longlong replacement
983
			   int64_t value)
1 by brian
clean slate
984
{
985
  switch ((option->var_type & GET_TYPE_MASK)) {
986
  case GET_BOOL:
143 by Brian Aker
Bool cleanup.
987
    *((bool*) variable)= (bool) value;
1 by brian
clean slate
988
    break;
989
  case GET_INT:
990
    *((int*) variable)= (int) value;
991
    break;
992
  case GET_UINT:
993
  case GET_ENUM:
994
    *((uint*) variable)= (uint) value;
995
    break;
996
  case GET_LONG:
997
    *((long*) variable)= (long) value;
998
    break;
999
  case GET_ULONG:
298 by Brian Aker
ulong conversion.
1000
    *((uint32_t*) variable)= (uint32_t) value;
1 by brian
clean slate
1001
    break;
1002
  case GET_LL:
152 by Brian Aker
longlong replacement
1003
    *((int64_t*) variable)= (int64_t) value;
1 by brian
clean slate
1004
    break;
629.4.1 by Monty Taylor
First step in support size_t sys_var stuff.
1005
  case GET_SIZE:
1006
    *((size_t*) variable)= (size_t) value;
1 by brian
clean slate
1007
  case GET_ULL:
1008
  case GET_SET:
151 by Brian Aker
Ulonglong to uint64_t
1009
    *((uint64_t*) variable)=  (uint64_t) value;
1 by brian
clean slate
1010
    break;
1011
  case GET_DOUBLE:
1012
    *((double*) variable)=  (double) value;
1013
    break;
1014
  case GET_STR:
1015
    /*
1016
      Do not clear variable value if it has no default value.
1017
      The default value may already be set.
156 by Brian Aker
Cleanup around intptr_t
1018
      NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
1 by brian
clean slate
1019
      so that the value has the same size as a pointer.
1020
    */
156 by Brian Aker
Cleanup around intptr_t
1021
    if ((char*) (intptr_t) value)
1022
      *((char**) variable)= (char*) (intptr_t) value;
1 by brian
clean slate
1023
    break;
1024
  case GET_STR_ALLOC:
1025
    /*
1026
      Do not clear variable value if it has no default value.
1027
      The default value may already be set.
156 by Brian Aker
Cleanup around intptr_t
1028
      NOTE: To avoid compiler warnings, we first cast int64_t to intptr_t,
1 by brian
clean slate
1029
      so that the value has the same size as a pointer.
1030
    */
156 by Brian Aker
Cleanup around intptr_t
1031
    if ((char*) (intptr_t) value)
1 by brian
clean slate
1032
    {
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.
1033
      free((*(char**) variable));
656.1.52 by Monty Taylor
Added more return value checks.
1034
      char *tmpptr= strdup((char *) (intptr_t) value);
1035
      if (tmpptr != NULL)
1036
        *((char**) variable)= tmpptr;
1 by brian
clean slate
1037
    }
1038
    break;
1039
  default: /* dummy default to avoid compiler warnings */
1040
    break;
1041
  }
51.3.17 by Jay Pipes
Phase 4 - Remove DBUG from mysys
1042
  return;
1 by brian
clean slate
1043
}
1044
1045
1046
/*
1047
  Init one value to it's default values
1048
1049
  SYNOPSIS
1050
    init_one_value()
1051
    option		Option to initialize
1052
    value		Pointer to variable
1053
*/
1054
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
1055
static void fini_one_value(const struct my_option *option, char **variable,
632.1.11 by Monty Taylor
Fixed Sun Studio warnings in mysys.
1056
			   int64_t)
1 by brian
clean slate
1057
{
1058
  switch ((option->var_type & GET_TYPE_MASK)) {
1059
  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.
1060
    free((*(char**) variable));
1 by brian
clean slate
1061
    *((char**) variable)= NULL;
1062
    break;
1063
  default: /* dummy default to avoid compiler warnings */
1064
    break;
1065
  }
51.3.17 by Jay Pipes
Phase 4 - Remove DBUG from mysys
1066
  return;
1 by brian
clean slate
1067
}
1068
1069
1070
void my_cleanup_options(const struct my_option *options)
1071
{
1072
  init_variables(options, fini_one_value);
1073
}
1074
1075
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1076
/*
1 by brian
clean slate
1077
  initialize all variables to their default values
1078
1079
  SYNOPSIS
1080
    init_variables()
1081
    options		Array of options
1082
1083
  NOTES
1084
    We will initialize the value that is pointed to by options->value.
1085
    If the value is of type GET_ASK_ADDR, we will also ask for the address
1086
    for a value and initialize.
1087
*/
1088
1089
static void init_variables(const struct my_option *options,
1090
                           init_func_p init_one_value)
1091
{
1092
  for (; options->name; options++)
1093
  {
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
1094
    char* *variable;
1 by brian
clean slate
1095
    /*
1096
      We must set u_max_value first as for some variables
1097
      options->u_max_value == options->value and in this case we want to
1098
      set the value to default value.
1099
    */
1100
    if (options->u_max_value)
1101
      init_one_value(options, options->u_max_value, options->max_value);
1102
    if (options->value)
1103
      init_one_value(options, options->value, options->def_value);
1104
    if (options->var_type & GET_ASK_ADDR &&
1105
	(variable= (*getopt_get_addr)("", 0, options)))
1106
      init_one_value(options, variable, options->def_value);
1107
  }
51.3.17 by Jay Pipes
Phase 4 - Remove DBUG from mysys
1108
  return;
1 by brian
clean slate
1109
}
1110
1111
1112
/*
1113
  function: my_print_options
1114
1115
  Print help for all options and variables.
1116
*/
1117
1118
void my_print_help(const struct my_option *options)
1119
{
482 by Brian Aker
Remove uint.
1120
  uint32_t col, name_space= 22, comment_space= 57;
1 by brian
clean slate
1121
  const char *line_end;
1122
  const struct my_option *optp;
1123
1124
  for (optp= options; optp->id; optp++)
1125
  {
1126
    if (optp->id < 256)
1127
    {
1128
      printf("  -%c%s", optp->id, strlen(optp->name) ? ", " : "  ");
1129
      col= 6;
1130
    }
1131
    else
1132
    {
1133
      printf("  ");
1134
      col= 2;
1135
    }
1136
    if (strlen(optp->name))
1137
    {
1138
      printf("--%s", optp->name);
1139
      col+= 2 + (uint) strlen(optp->name);
1140
      if ((optp->var_type & GET_TYPE_MASK) == GET_STR ||
1141
	  (optp->var_type & GET_TYPE_MASK) == GET_STR_ALLOC)
1142
      {
1143
	printf("%s=name%s ", optp->arg_type == OPT_ARG ? "[" : "",
1144
	       optp->arg_type == OPT_ARG ? "]" : "");
1145
	col+= (optp->arg_type == OPT_ARG) ? 8 : 6;
1146
      }
1147
      else if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG ||
1148
	       (optp->var_type & GET_TYPE_MASK) == GET_BOOL)
1149
      {
1150
	putchar(' ');
1151
	col++;
1152
      }
1153
      else
1154
      {
1155
	printf("%s=#%s ", optp->arg_type == OPT_ARG ? "[" : "",
1156
	       optp->arg_type == OPT_ARG ? "]" : "");
1157
	col+= (optp->arg_type == OPT_ARG) ? 5 : 3;
1158
      }
1159
      if (col > name_space && optp->comment && *optp->comment)
1160
      {
1161
	putchar('\n');
1162
	col= 0;
1163
      }
1164
    }
1165
    for (; col < name_space; col++)
1166
      putchar(' ');
1167
    if (optp->comment && *optp->comment)
1168
    {
376 by Brian Aker
strend remove
1169
      const char *comment= _(optp->comment), *end= strchr(comment, '\0');
1 by brian
clean slate
1170
1171
      while ((uint) (end - comment) > comment_space)
1172
      {
575.3.1 by Monty Taylor
Made mysys and mystrings c++. Fixed the resulting bugs the compiler found.
1173
	for (line_end= comment + comment_space; *line_end != ' '; line_end--)
1174
          {}
1 by brian
clean slate
1175
	for (; comment != line_end; comment++)
1176
	  putchar(*comment);
1177
	comment++; /* skip the space, as a newline will take it's place now */
1178
	putchar('\n');
1179
	for (col= 0; col < name_space; col++)
1180
	  putchar(' ');
1181
      }
1182
      printf("%s", comment);
1183
    }
1184
    putchar('\n');
1185
    if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG ||
1186
             (optp->var_type & GET_TYPE_MASK) == GET_BOOL)
1187
    {
1188
      if (optp->def_value != 0)
1189
      {
264.1.2 by Monty Taylor
Added some strings from my_error and my_getopt we'd missed before.
1190
        printf(_("%*s(Defaults to on; use --skip-%s to disable.)\n"), name_space, "", optp->name);
1 by brian
clean slate
1191
      }
1192
    }
1193
  }
1194
}
1195
1196
1197
/*
1198
  function: my_print_options
1199
1200
  Print variables.
1201
*/
1202
1203
void my_print_variables(const struct my_option *options)
1204
{
482 by Brian Aker
Remove uint.
1205
  uint32_t name_space= 34, length, nr;
151 by Brian Aker
Ulonglong to uint64_t
1206
  uint64_t bit, llvalue;
1 by brian
clean slate
1207
  char buff[255];
1208
  const struct my_option *optp;
1209
264.1.2 by Monty Taylor
Added some strings from my_error and my_getopt we'd missed before.
1210
  printf(_("\nVariables (--variable-name=value)\n"
1211
         "and boolean options {false|true}  Value (after reading options)\n"
1212
         "--------------------------------- -----------------------------\n"));
1 by brian
clean slate
1213
  for (optp= options; optp->id; optp++)
1214
  {
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
1215
    char* *value= (optp->var_type & GET_ASK_ADDR ?
1 by brian
clean slate
1216
		  (*getopt_get_addr)("", 0, optp) : optp->value);
1217
    if (value)
1218
    {
1219
      printf("%s ", optp->name);
1220
      length= (uint) strlen(optp->name)+1;
1221
      for (; length < name_space; length++)
1222
	putchar(' ');
1223
      switch ((optp->var_type & GET_TYPE_MASK)) {
1224
      case GET_SET:
151 by Brian Aker
Ulonglong to uint64_t
1225
        if (!(llvalue= *(uint64_t*) value))
264.1.2 by Monty Taylor
Added some strings from my_error and my_getopt we'd missed before.
1226
	  printf("%s\n", _("(No default value)"));
1 by brian
clean slate
1227
	else
1228
        for (nr= 0, bit= 1; llvalue && nr < optp->typelib->count; nr++, bit<<=1)
1229
	{
1230
	  if (!(bit & llvalue))
1231
	    continue;
1232
	  llvalue&= ~bit;
1233
	  printf( llvalue ? "%s," : "%s\n", get_type(optp->typelib, nr));
1234
	}
1235
	break;
1236
      case GET_ENUM:
1237
        printf("%s\n", get_type(optp->typelib, *(uint*) value));
1238
	break;
1239
      case GET_STR:
1240
      case GET_STR_ALLOC:                    /* fall through */
1241
	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.
1242
	       _("(No default value)"));
1 by brian
clean slate
1243
	break;
1244
      case GET_BOOL:
264.1.2 by Monty Taylor
Added some strings from my_error and my_getopt we'd missed before.
1245
	printf("%s\n", *((bool*) value) ? _("true") : _("false"));
1 by brian
clean slate
1246
	break;
1247
      case GET_INT:
1248
	printf("%d\n", *((int*) value));
1249
	break;
1250
      case GET_UINT:
1251
	printf("%d\n", *((uint*) value));
1252
	break;
1253
      case GET_LONG:
1254
	printf("%ld\n", *((long*) value));
1255
	break;
1256
      case GET_ULONG:
298 by Brian Aker
ulong conversion.
1257
	printf("%u\n", *((uint32_t*) value));
1 by brian
clean slate
1258
	break;
629.4.1 by Monty Taylor
First step in support size_t sys_var stuff.
1259
      case GET_SIZE:
1260
	cout << value;
1261
	break;
1 by brian
clean slate
1262
      case GET_LL:
152 by Brian Aker
longlong replacement
1263
	printf("%s\n", llstr(*((int64_t*) value), buff));
1 by brian
clean slate
1264
	break;
1265
      case GET_ULL:
152 by Brian Aker
longlong replacement
1266
	int64_t2str(*((uint64_t*) value), buff, 10);
1 by brian
clean slate
1267
	printf("%s\n", buff);
1268
	break;
1269
      case GET_DOUBLE:
1270
	printf("%g\n", *(double*) value);
1271
	break;
1272
      default:
264.1.2 by Monty Taylor
Added some strings from my_error and my_getopt we'd missed before.
1273
	printf(_("(Disabled)\n"));
1 by brian
clean slate
1274
	break;
1275
      }
1276
    }
1277
  }
1278
}