Dep/MySQL: Updated MySQL sources to version 5.5.9 (current GA)
This commit is contained in:
+376
-244
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2002-2006 MySQL AB
|
||||
/* Copyright (C) 2002-2006 MySQL AB, 2008-2009 Sun Microsystems, Inc
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -28,24 +28,15 @@ typedef void (*init_func_p)(const struct my_option *option, void *variable,
|
||||
static void default_reporter(enum loglevel level, const char *format, ...);
|
||||
my_error_reporter my_getopt_error_reporter= &default_reporter;
|
||||
|
||||
static int findopt(char *optpat, uint length,
|
||||
const struct my_option **opt_res,
|
||||
const char **ffname);
|
||||
my_bool getopt_compare_strings(const char *s,
|
||||
const char *t,
|
||||
uint length);
|
||||
static int findopt(char *, uint, const struct my_option **, const char **);
|
||||
my_bool getopt_compare_strings(const char *, const char *, uint);
|
||||
static longlong getopt_ll(char *arg, const struct my_option *optp, int *err);
|
||||
static ulonglong getopt_ull(char *arg, const struct my_option *optp,
|
||||
int *err);
|
||||
static ulonglong getopt_ull(char *, const struct my_option *, int *);
|
||||
static double getopt_double(char *arg, const struct my_option *optp, int *err);
|
||||
static void init_variables(const struct my_option *options,
|
||||
init_func_p init_one_value);
|
||||
static void init_one_value(const struct my_option *option, void *variable,
|
||||
longlong value);
|
||||
static void fini_one_value(const struct my_option *option, void *variable,
|
||||
longlong value);
|
||||
static int setval(const struct my_option *opts, void *value, char *argument,
|
||||
my_bool set_maximum_value);
|
||||
static void init_variables(const struct my_option *, init_func_p);
|
||||
static void init_one_value(const struct my_option *, void *, longlong);
|
||||
static void fini_one_value(const struct my_option *, void *, longlong);
|
||||
static int setval(const struct my_option *, void *, char *, my_bool);
|
||||
static char *check_struct_option(char *cur_arg, char *key_name);
|
||||
|
||||
/*
|
||||
@@ -60,6 +51,7 @@ enum enum_special_opt
|
||||
{ OPT_SKIP, OPT_DISABLE, OPT_ENABLE, OPT_MAXIMUM, OPT_LOOSE};
|
||||
|
||||
char *disabled_my_option= (char*) "0";
|
||||
char *enabled_my_option= (char*) "1";
|
||||
|
||||
/*
|
||||
This is a flag that can be set in client programs. 0 means that
|
||||
@@ -91,16 +83,6 @@ static void default_reporter(enum loglevel level,
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
/*
|
||||
function: handle_options
|
||||
|
||||
Sort options; put options first, until special end of options (--), or
|
||||
until end of argv. Parse options; check that the given option matches with
|
||||
one of the options in struct 'my_option', return error in case of ambiguous
|
||||
or unknown option. Check that option was given an argument if it requires
|
||||
one. Call function 'get_one_option()' once for each option.
|
||||
*/
|
||||
|
||||
static my_getopt_value getopt_get_addr;
|
||||
|
||||
void my_getopt_register_get_addr(my_getopt_value func_addr)
|
||||
@@ -108,11 +90,70 @@ void my_getopt_register_get_addr(my_getopt_value func_addr)
|
||||
getopt_get_addr= func_addr;
|
||||
}
|
||||
|
||||
/**
|
||||
Handle command line options.
|
||||
Sort options.
|
||||
Put options first, until special end of options (--),
|
||||
or until the end of argv. Parse options, check that the given option
|
||||
matches with one of the options in struct 'my_option'.
|
||||
Check that option was given an argument if it requires one
|
||||
Call the optional 'get_one_option()' function once for each option.
|
||||
|
||||
Note that handle_options() can be invoked multiple times to
|
||||
parse a command line in several steps.
|
||||
In this case, use the global flag @c my_getopt_skip_unknown to indicate
|
||||
that options unknown in the current step should be preserved in the
|
||||
command line for later parsing in subsequent steps.
|
||||
|
||||
For 'long' options (--a_long_option), @c my_getopt_skip_unknown is
|
||||
fully supported. Command line parameters such as:
|
||||
- "--a_long_option"
|
||||
- "--a_long_option=value"
|
||||
- "--a_long_option value"
|
||||
will be preserved as is when the option is not known.
|
||||
|
||||
For 'short' options (-S), support for @c my_getopt_skip_unknown
|
||||
comes with some limitation, because several short options
|
||||
can also be specified together in the same command line argument,
|
||||
as in "-XYZ".
|
||||
|
||||
The first use case supported is: all short options are declared.
|
||||
handle_options() will be able to interpret "-XYZ" as one of:
|
||||
- an unknown X option
|
||||
- "-X -Y -Z", three short options with no arguments
|
||||
- "-X -YZ", where Y is a short option with argument Z
|
||||
- "-XYZ", where X is a short option with argument YZ
|
||||
based on the full short options specifications.
|
||||
|
||||
The second use case supported is: no short option is declared.
|
||||
handle_options() will reject "-XYZ" as unknown, to be parsed later.
|
||||
|
||||
The use case that is explicitly not supported is to provide
|
||||
only a partial list of short options to handle_options().
|
||||
This function can not be expected to extract some option Y
|
||||
in the middle of the string "-XYZ" in these conditions,
|
||||
without knowing if X will be declared an option later.
|
||||
|
||||
Note that this limitation only impacts parsing of several
|
||||
short options from the same command line argument,
|
||||
as in "mysqld -anW5".
|
||||
When each short option is properly separated out in the command line
|
||||
argument, for example in "mysqld -a -n -w5", the code would actually
|
||||
work even with partial options specs given at each stage.
|
||||
|
||||
@param [in, out] argc command line options (count)
|
||||
@param [in, out] argv command line options (values)
|
||||
@param [in] longopts descriptor of all valid options
|
||||
@param [in] get_one_option optional callback function to process each option,
|
||||
can be NULL.
|
||||
@return error in case of ambiguous or unknown options,
|
||||
0 on success.
|
||||
*/
|
||||
int handle_options(int *argc, char ***argv,
|
||||
const struct my_option *longopts,
|
||||
my_get_one_option get_one_option)
|
||||
{
|
||||
uint opt_found, argvpos= 0, length;
|
||||
uint UNINIT_VAR(opt_found), argvpos= 0, length;
|
||||
my_bool end_of_options= 0, must_be_var, set_maximum_value,
|
||||
option_is_loose;
|
||||
char **pos, **pos_end, *optend, *opt_str, key_name[FN_REFLEN];
|
||||
@@ -120,8 +161,8 @@ int handle_options(int *argc, char ***argv,
|
||||
const struct my_option *optp;
|
||||
void *value;
|
||||
int error, i;
|
||||
my_bool is_cmdline_arg= 1;
|
||||
|
||||
LINT_INIT(opt_found);
|
||||
/* handle_options() assumes arg0 (program name) always exists */
|
||||
DBUG_ASSERT(argc && *argc >= 1);
|
||||
DBUG_ASSERT(argv && *argv);
|
||||
@@ -129,10 +170,35 @@ int handle_options(int *argc, char ***argv,
|
||||
(*argv)++; /* --- || ---- */
|
||||
init_variables(longopts, init_one_value);
|
||||
|
||||
/*
|
||||
Search for args_separator, if found, then the first part of the
|
||||
arguments are loaded from configs
|
||||
*/
|
||||
for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++)
|
||||
{
|
||||
if (*pos == args_separator)
|
||||
{
|
||||
is_cmdline_arg= 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++)
|
||||
{
|
||||
char **first= pos;
|
||||
char *cur_arg= *pos;
|
||||
opt_found= 0;
|
||||
if (!is_cmdline_arg && (cur_arg == args_separator))
|
||||
{
|
||||
is_cmdline_arg= 1;
|
||||
|
||||
/* save the separator too if skip unkown options */
|
||||
if (my_getopt_skip_unknown)
|
||||
(*argv)[argvpos++]= cur_arg;
|
||||
else
|
||||
(*argc)--;
|
||||
continue;
|
||||
}
|
||||
if (cur_arg[0] == '-' && cur_arg[1] && !end_of_options) /* must be opt */
|
||||
{
|
||||
char *argument= 0;
|
||||
@@ -141,78 +207,15 @@ int handle_options(int *argc, char ***argv,
|
||||
option_is_loose= 0;
|
||||
|
||||
cur_arg++; /* skip '-' */
|
||||
if (*cur_arg == '-' || *cur_arg == 'O') /* check for long option, */
|
||||
{ /* --set-variable, or -O */
|
||||
if (*cur_arg == 'O')
|
||||
{
|
||||
my_getopt_error_reporter(WARNING_LEVEL,
|
||||
"%s: Option '-O' is deprecated. "
|
||||
"Use --variable-name=value instead.",
|
||||
my_progname);
|
||||
must_be_var= 1;
|
||||
|
||||
if (!(*++cur_arg)) /* If not -Ovar=# */
|
||||
{
|
||||
/* the argument must be in next argv */
|
||||
if (!*++pos)
|
||||
{
|
||||
if (my_getopt_print_errors)
|
||||
my_getopt_error_reporter(ERROR_LEVEL,
|
||||
"%s: Option '-O' requires an argument",
|
||||
my_progname);
|
||||
return EXIT_ARGUMENT_REQUIRED;
|
||||
}
|
||||
cur_arg= *pos;
|
||||
(*argc)--;
|
||||
}
|
||||
}
|
||||
else if (!getopt_compare_strings(cur_arg, "-set-variable", 13))
|
||||
{
|
||||
my_getopt_error_reporter(WARNING_LEVEL,
|
||||
"%s: Option '--set-variable' is deprecated. "
|
||||
"Use --variable-name=value instead.",
|
||||
my_progname);
|
||||
|
||||
must_be_var= 1;
|
||||
if (cur_arg[13] == '=')
|
||||
{
|
||||
cur_arg+= 14;
|
||||
if (!*cur_arg)
|
||||
{
|
||||
if (my_getopt_print_errors)
|
||||
my_getopt_error_reporter(ERROR_LEVEL,
|
||||
"%s: Option '--set-variable' requires an argument",
|
||||
my_progname);
|
||||
return EXIT_ARGUMENT_REQUIRED;
|
||||
}
|
||||
}
|
||||
else if (cur_arg[14]) /* garbage, or another option. break out */
|
||||
must_be_var= 0;
|
||||
else
|
||||
{
|
||||
/* the argument must be in next argv */
|
||||
if (!*++pos)
|
||||
{
|
||||
if (my_getopt_print_errors)
|
||||
my_getopt_error_reporter(ERROR_LEVEL,
|
||||
"%s: Option '--set-variable' requires an argument",
|
||||
my_progname);
|
||||
return EXIT_ARGUMENT_REQUIRED;
|
||||
}
|
||||
cur_arg= *pos;
|
||||
(*argc)--;
|
||||
}
|
||||
}
|
||||
else if (!must_be_var)
|
||||
{
|
||||
if (!*++cur_arg) /* skip the double dash */
|
||||
{
|
||||
/* '--' means end of options, look no further */
|
||||
end_of_options= 1;
|
||||
(*argc)--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (*cur_arg == '-') /* check for long option, */
|
||||
{
|
||||
if (!*++cur_arg) /* skip the double dash */
|
||||
{
|
||||
/* '--' means end of options, look no further */
|
||||
end_of_options= 1;
|
||||
(*argc)--;
|
||||
continue;
|
||||
}
|
||||
opt_str= check_struct_option(cur_arg, key_name);
|
||||
optend= strcend(opt_str, '=');
|
||||
length= (uint) (optend - opt_str);
|
||||
@@ -258,7 +261,7 @@ int handle_options(int *argc, char ***argv,
|
||||
my_getopt_error_reporter(ERROR_LEVEL,
|
||||
"%s: ambiguous option '--%s-%s' (--%s-%s)",
|
||||
my_progname, special_opt_prefix[i],
|
||||
cur_arg, special_opt_prefix[i],
|
||||
opt_str, special_opt_prefix[i],
|
||||
prev_found);
|
||||
return EXIT_AMBIGUOUS_OPTION;
|
||||
}
|
||||
@@ -270,11 +273,11 @@ int handle_options(int *argc, char ***argv,
|
||||
for example: --skip-option=0 -> option = TRUE
|
||||
*/
|
||||
optend= (optend && *optend == '0' && !(*(optend + 1))) ?
|
||||
(char*) "1" : disabled_my_option;
|
||||
enabled_my_option : disabled_my_option;
|
||||
break;
|
||||
case OPT_ENABLE:
|
||||
optend= (optend && *optend == '0' && !(*(optend + 1))) ?
|
||||
disabled_my_option : (char*) "1";
|
||||
disabled_my_option : enabled_my_option;
|
||||
break;
|
||||
case OPT_MAXIMUM:
|
||||
set_maximum_value= 1;
|
||||
@@ -291,12 +294,7 @@ int handle_options(int *argc, char ***argv,
|
||||
{
|
||||
if (my_getopt_skip_unknown)
|
||||
{
|
||||
/*
|
||||
preserve all the components of this unknown option, this may
|
||||
occurr when the user provides options like: "-O foo" or
|
||||
"--set-variable foo" (note that theres a space in there)
|
||||
Generally, these kind of options are to be avoided
|
||||
*/
|
||||
/* Preserve all the components of this unknown option. */
|
||||
do {
|
||||
(*argv)[argvpos++]= *first++;
|
||||
} while (first <= pos);
|
||||
@@ -362,14 +360,6 @@ int handle_options(int *argc, char ***argv,
|
||||
}
|
||||
return EXIT_OPTION_DISABLED;
|
||||
}
|
||||
if (must_be_var && (optp->var_type & GET_TYPE_MASK) == GET_NO_ARG)
|
||||
{
|
||||
if (my_getopt_print_errors)
|
||||
my_getopt_error_reporter(ERROR_LEVEL,
|
||||
"%s: option '%s' cannot take an argument",
|
||||
my_progname, optp->name);
|
||||
return EXIT_NO_ARGUMENT_ALLOWED;
|
||||
}
|
||||
error= 0;
|
||||
value= optp->var_type & GET_ASK_ADDR ?
|
||||
(*getopt_get_addr)(key_name, (uint) strlen(key_name), optp, &error) :
|
||||
@@ -379,6 +369,11 @@ int handle_options(int *argc, char ***argv,
|
||||
|
||||
if (optp->arg_type == NO_ARG)
|
||||
{
|
||||
/*
|
||||
Due to historical reasons GET_BOOL var_types still accepts arguments
|
||||
despite the NO_ARG arg_type attribute. This can seems a bit unintuitive
|
||||
and care should be taken when refactoring this code.
|
||||
*/
|
||||
if (optend && (optp->var_type & GET_TYPE_MASK) != GET_BOOL)
|
||||
{
|
||||
if (my_getopt_print_errors)
|
||||
@@ -393,7 +388,7 @@ int handle_options(int *argc, char ***argv,
|
||||
Set bool to 1 if no argument or if the user has used
|
||||
--enable-'option-name'.
|
||||
*optend was set to '0' if one used --disable-option
|
||||
*/
|
||||
*/
|
||||
(*argc)--;
|
||||
if (!optend || *optend == '1' ||
|
||||
!my_strcasecmp(&my_charset_latin1, optend, "true"))
|
||||
@@ -404,37 +399,26 @@ int handle_options(int *argc, char ***argv,
|
||||
else
|
||||
{
|
||||
my_getopt_error_reporter(WARNING_LEVEL,
|
||||
"%s: ignoring option '--%s' due to "
|
||||
"invalid value '%s'",
|
||||
"%s: ignoring option '--%s' "
|
||||
"due to invalid value '%s'",
|
||||
my_progname, optp->name, optend);
|
||||
continue;
|
||||
}
|
||||
if (get_one_option(optp->id, optp,
|
||||
if (get_one_option && get_one_option(optp->id, optp,
|
||||
*((my_bool*) value) ?
|
||||
(char*) "1" : disabled_my_option))
|
||||
enabled_my_option : disabled_my_option))
|
||||
return EXIT_ARGUMENT_INVALID;
|
||||
continue;
|
||||
}
|
||||
argument= optend;
|
||||
}
|
||||
else if (optp->arg_type == OPT_ARG &&
|
||||
(((optp->var_type & GET_TYPE_MASK) == GET_BOOL) ||
|
||||
(optp->var_type & GET_TYPE_MASK) == GET_ENUM))
|
||||
{
|
||||
if (optend == disabled_my_option)
|
||||
init_one_value(optp, value, 0);
|
||||
else
|
||||
{
|
||||
if (!optend) /* No argument -> enable option */
|
||||
init_one_value(optp, value, 1);
|
||||
else
|
||||
argument= optend;
|
||||
}
|
||||
}
|
||||
else if (optp->arg_type == REQUIRED_ARG && !optend)
|
||||
{
|
||||
/* Check if there are more arguments after this one */
|
||||
if (!*++pos)
|
||||
/* Check if there are more arguments after this one,
|
||||
Note: options loaded from config file that requires value
|
||||
should always be in the form '--option=value'.
|
||||
*/
|
||||
if (!is_cmdline_arg || !*++pos)
|
||||
{
|
||||
if (my_getopt_print_errors)
|
||||
my_getopt_error_reporter(ERROR_LEVEL,
|
||||
@@ -453,9 +437,9 @@ int handle_options(int *argc, char ***argv,
|
||||
for (optend= cur_arg; *optend; optend++)
|
||||
{
|
||||
opt_found= 0;
|
||||
for (optp= longopts; optp->id; optp++)
|
||||
for (optp= longopts; optp->name; optp++)
|
||||
{
|
||||
if (optp->id == (int) (uchar) *optend)
|
||||
if (optp->id && optp->id == (int) (uchar) *optend)
|
||||
{
|
||||
/* Option recognized. Find next what to do with it */
|
||||
opt_found= 1;
|
||||
@@ -471,7 +455,7 @@ int handle_options(int *argc, char ***argv,
|
||||
optp->arg_type == NO_ARG)
|
||||
{
|
||||
*((my_bool*) optp->value)= (my_bool) 1;
|
||||
if (get_one_option(optp->id, optp, argument))
|
||||
if (get_one_option && get_one_option(optp->id, optp, argument))
|
||||
return EXIT_UNSPECIFIED_ERROR;
|
||||
continue;
|
||||
}
|
||||
@@ -491,7 +475,7 @@ int handle_options(int *argc, char ***argv,
|
||||
{
|
||||
if (optp->var_type == GET_BOOL)
|
||||
*((my_bool*) optp->value)= (my_bool) 1;
|
||||
if (get_one_option(optp->id, optp, argument))
|
||||
if (get_one_option && get_one_option(optp->id, optp, argument))
|
||||
return EXIT_UNSPECIFIED_ERROR;
|
||||
continue;
|
||||
}
|
||||
@@ -511,40 +495,56 @@ int handle_options(int *argc, char ***argv,
|
||||
}
|
||||
if ((error= setval(optp, optp->value, argument,
|
||||
set_maximum_value)))
|
||||
{
|
||||
my_getopt_error_reporter(ERROR_LEVEL,
|
||||
"%s: Error while setting value '%s' to '%s'",
|
||||
my_progname, argument, optp->name);
|
||||
return error;
|
||||
}
|
||||
if (get_one_option(optp->id, optp, argument))
|
||||
if (get_one_option && get_one_option(optp->id, optp, argument))
|
||||
return EXIT_UNSPECIFIED_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!opt_found)
|
||||
{
|
||||
if (my_getopt_print_errors)
|
||||
my_getopt_error_reporter(ERROR_LEVEL,
|
||||
"%s: unknown option '-%c'",
|
||||
my_progname, *optend);
|
||||
return EXIT_UNKNOWN_OPTION;
|
||||
if (my_getopt_skip_unknown)
|
||||
{
|
||||
/*
|
||||
We are currently parsing a single argv[] argument
|
||||
of the form "-XYZ".
|
||||
One or the argument found (say Y) is not an option.
|
||||
Hack the string "-XYZ" to make a "-YZ" substring in it,
|
||||
and push that to the output as an unrecognized parameter.
|
||||
*/
|
||||
DBUG_ASSERT(optend > *pos);
|
||||
DBUG_ASSERT(optend >= cur_arg);
|
||||
DBUG_ASSERT(optend <= *pos + strlen(*pos));
|
||||
DBUG_ASSERT(*optend);
|
||||
optend--;
|
||||
optend[0]= '-'; /* replace 'X' or '-' by '-' */
|
||||
(*argv)[argvpos++]= optend;
|
||||
/*
|
||||
Do not continue to parse at the current "-XYZ" argument,
|
||||
skip to the next argv[] argument instead.
|
||||
*/
|
||||
optend= (char*) " ";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (my_getopt_print_errors)
|
||||
my_getopt_error_reporter(ERROR_LEVEL,
|
||||
"%s: unknown option '-%c'",
|
||||
my_progname, *optend);
|
||||
return EXIT_UNKNOWN_OPTION;
|
||||
}
|
||||
}
|
||||
}
|
||||
(*argc)--; /* option handled (short), decrease argument count */
|
||||
if (opt_found)
|
||||
(*argc)--; /* option handled (short), decrease argument count */
|
||||
continue;
|
||||
}
|
||||
if ((error= setval(optp, value, argument, set_maximum_value)))
|
||||
{
|
||||
my_getopt_error_reporter(ERROR_LEVEL,
|
||||
"%s: Error while setting value '%s' to '%s'",
|
||||
my_progname, argument, optp->name);
|
||||
return error;
|
||||
}
|
||||
if (get_one_option(optp->id, optp, argument))
|
||||
if (get_one_option && get_one_option(optp->id, optp, argument))
|
||||
return EXIT_UNSPECIFIED_ERROR;
|
||||
|
||||
(*argc)--; /* option handled (short or long), decrease argument count */
|
||||
(*argc)--; /* option handled (long), decrease argument count */
|
||||
}
|
||||
else /* non-option found */
|
||||
(*argv)[argvpos++]= cur_arg;
|
||||
@@ -602,6 +602,24 @@ static char *check_struct_option(char *cur_arg, char *key_name)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Parse a boolean command line argument
|
||||
|
||||
"ON", "TRUE" and "1" will return true,
|
||||
other values will return false.
|
||||
|
||||
@param[in] argument The value argument
|
||||
@return boolean value
|
||||
*/
|
||||
static my_bool get_bool_argument(const char *argument)
|
||||
{
|
||||
if (!my_strcasecmp(&my_charset_latin1, argument, "true") ||
|
||||
!my_strcasecmp(&my_charset_latin1, argument, "on"))
|
||||
return 1;
|
||||
else
|
||||
return (my_bool) atoi(argument);
|
||||
}
|
||||
|
||||
/*
|
||||
function: setval
|
||||
|
||||
@@ -612,75 +630,132 @@ static char *check_struct_option(char *cur_arg, char *key_name)
|
||||
static int setval(const struct my_option *opts, void *value, char *argument,
|
||||
my_bool set_maximum_value)
|
||||
{
|
||||
int err= 0;
|
||||
int err= 0, res= 0;
|
||||
|
||||
if (value && argument)
|
||||
if (!argument)
|
||||
argument= enabled_my_option;
|
||||
|
||||
if (value)
|
||||
{
|
||||
void *result_pos= ((set_maximum_value) ? opts->u_max_value : value);
|
||||
|
||||
if (!result_pos)
|
||||
if (set_maximum_value && !(value= opts->u_max_value))
|
||||
{
|
||||
my_getopt_error_reporter(ERROR_LEVEL,
|
||||
"%s: Maximum value of '%s' cannot be set",
|
||||
my_progname, opts->name);
|
||||
return EXIT_NO_PTR_TO_VARIABLE;
|
||||
}
|
||||
|
||||
switch ((opts->var_type & GET_TYPE_MASK)) {
|
||||
case GET_BOOL: /* If argument differs from 0, enable option, else disable */
|
||||
*((my_bool*) result_pos)= (my_bool) atoi(argument) != 0;
|
||||
*((my_bool*) value)= get_bool_argument(argument);
|
||||
break;
|
||||
case GET_INT:
|
||||
*((int*) result_pos)= (int) getopt_ll(argument, opts, &err);
|
||||
*((int*) value)= (int) getopt_ll(argument, opts, &err);
|
||||
break;
|
||||
case GET_UINT:
|
||||
*((uint*) result_pos)= (uint) getopt_ull(argument, opts, &err);
|
||||
*((uint*) value)= (uint) getopt_ull(argument, opts, &err);
|
||||
break;
|
||||
case GET_LONG:
|
||||
*((long*) result_pos)= (long) getopt_ll(argument, opts, &err);
|
||||
*((long*) value)= (long) getopt_ll(argument, opts, &err);
|
||||
break;
|
||||
case GET_ULONG:
|
||||
*((long*) result_pos)= (long) getopt_ull(argument, opts, &err);
|
||||
*((long*) value)= (long) getopt_ull(argument, opts, &err);
|
||||
break;
|
||||
case GET_LL:
|
||||
*((longlong*) result_pos)= getopt_ll(argument, opts, &err);
|
||||
*((longlong*) value)= getopt_ll(argument, opts, &err);
|
||||
break;
|
||||
case GET_ULL:
|
||||
*((ulonglong*) result_pos)= getopt_ull(argument, opts, &err);
|
||||
*((ulonglong*) value)= getopt_ull(argument, opts, &err);
|
||||
break;
|
||||
case GET_DOUBLE:
|
||||
*((double*) result_pos)= getopt_double(argument, opts, &err);
|
||||
*((double*) value)= getopt_double(argument, opts, &err);
|
||||
break;
|
||||
case GET_STR:
|
||||
*((char**) result_pos)= argument;
|
||||
if (argument == enabled_my_option)
|
||||
break; /* string options don't use this default of "1" */
|
||||
*((char**) value)= argument;
|
||||
break;
|
||||
case GET_STR_ALLOC:
|
||||
if ((*((char**) result_pos)))
|
||||
my_free((*(char**) result_pos), MYF(MY_WME | MY_FAE));
|
||||
if (!(*((char**) result_pos)= my_strdup(argument, MYF(MY_WME))))
|
||||
return EXIT_OUT_OF_MEMORY;
|
||||
if (argument == enabled_my_option)
|
||||
break; /* string options don't use this default of "1" */
|
||||
my_free(*((char**) value));
|
||||
if (!(*((char**) value)= my_strdup(argument, MYF(MY_WME))))
|
||||
{
|
||||
res= EXIT_OUT_OF_MEMORY;
|
||||
goto ret;
|
||||
};
|
||||
break;
|
||||
case GET_ENUM:
|
||||
if (((*(int*)result_pos)=
|
||||
find_type(argument, opts->typelib, 2) - 1) < 0)
|
||||
{
|
||||
/*
|
||||
Accept an integer representation of the enumerated item.
|
||||
*/
|
||||
char *endptr;
|
||||
unsigned int arg= (unsigned int) strtol(argument, &endptr, 10);
|
||||
if (*endptr || arg >= opts->typelib->count)
|
||||
return EXIT_ARGUMENT_INVALID;
|
||||
*(int*)result_pos= arg;
|
||||
int type= find_type(argument, opts->typelib, 2);
|
||||
if (type == 0)
|
||||
{
|
||||
/*
|
||||
Accept an integer representation of the enumerated item.
|
||||
*/
|
||||
char *endptr;
|
||||
ulong arg= strtoul(argument, &endptr, 10);
|
||||
if (*endptr || arg >= opts->typelib->count)
|
||||
{
|
||||
res= EXIT_ARGUMENT_INVALID;
|
||||
goto ret;
|
||||
}
|
||||
*(ulong*)value= arg;
|
||||
}
|
||||
else
|
||||
*(ulong*)value= type - 1;
|
||||
}
|
||||
break;
|
||||
case GET_SET:
|
||||
*((ulonglong*)result_pos)= find_typeset(argument, opts->typelib, &err);
|
||||
*((ulonglong*)value)= find_typeset(argument, opts->typelib, &err);
|
||||
if (err)
|
||||
return EXIT_ARGUMENT_INVALID;
|
||||
{
|
||||
/* Accept an integer representation of the set */
|
||||
char *endptr;
|
||||
ulonglong arg= (ulonglong) strtol(argument, &endptr, 10);
|
||||
if (*endptr || (arg >> 1) >= (1ULL << (opts->typelib->count-1)))
|
||||
{
|
||||
res= EXIT_ARGUMENT_INVALID;
|
||||
goto ret;
|
||||
};
|
||||
*(ulonglong*)value= arg;
|
||||
err= 0;
|
||||
}
|
||||
break;
|
||||
default: /* dummy default to avoid compiler warnings */
|
||||
case GET_FLAGSET:
|
||||
{
|
||||
char *error;
|
||||
uint error_len;
|
||||
|
||||
*((ulonglong*)value)=
|
||||
find_set_from_flags(opts->typelib, opts->typelib->count,
|
||||
*(ulonglong *)value, opts->def_value,
|
||||
argument, strlen(argument),
|
||||
&error, &error_len);
|
||||
if (error)
|
||||
{
|
||||
res= EXIT_ARGUMENT_INVALID;
|
||||
goto ret;
|
||||
};
|
||||
}
|
||||
break;
|
||||
case GET_NO_ARG: /* get_one_option has taken care of the value already */
|
||||
default: /* dummy default to avoid compiler warnings */
|
||||
break;
|
||||
}
|
||||
if (err)
|
||||
return EXIT_UNKNOWN_SUFFIX;
|
||||
{
|
||||
res= EXIT_UNKNOWN_SUFFIX;
|
||||
goto ret;
|
||||
};
|
||||
}
|
||||
return 0;
|
||||
|
||||
ret:
|
||||
my_getopt_error_reporter(ERROR_LEVEL,
|
||||
"%s: Error while setting value '%s' to '%s'",
|
||||
my_progname, argument, opts->name);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -859,7 +934,7 @@ longlong getopt_ll_limit_value(longlong num, const struct my_option *optp,
|
||||
break;
|
||||
}
|
||||
|
||||
num= ((num - optp->sub_size) / block_size);
|
||||
num= (num / block_size);
|
||||
num= (longlong) (num * block_size);
|
||||
|
||||
if (num < optp->min_value)
|
||||
@@ -870,7 +945,7 @@ longlong getopt_ll_limit_value(longlong num, const struct my_option *optp,
|
||||
}
|
||||
|
||||
if (fix)
|
||||
*fix= adjusted;
|
||||
*fix= old != num;
|
||||
else if (adjusted)
|
||||
my_getopt_error_reporter(WARNING_LEVEL,
|
||||
"option '%s': signed value %s adjusted to %s",
|
||||
@@ -942,7 +1017,7 @@ ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp,
|
||||
}
|
||||
|
||||
if (fix)
|
||||
*fix= adjusted;
|
||||
*fix= old != num;
|
||||
else if (adjusted)
|
||||
my_getopt_error_reporter(WARNING_LEVEL,
|
||||
"option '%s': unsigned value %s adjusted to %s",
|
||||
@@ -951,6 +1026,29 @@ ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp,
|
||||
return num;
|
||||
}
|
||||
|
||||
double getopt_double_limit_value(double num, const struct my_option *optp,
|
||||
my_bool *fix)
|
||||
{
|
||||
my_bool adjusted= FALSE;
|
||||
double old= num;
|
||||
if (optp->max_value && num > (double) optp->max_value)
|
||||
{
|
||||
num= (double) optp->max_value;
|
||||
adjusted= TRUE;
|
||||
}
|
||||
if (num < (double) optp->min_value)
|
||||
{
|
||||
num= (double) optp->min_value;
|
||||
adjusted= TRUE;
|
||||
}
|
||||
if (fix)
|
||||
*fix= adjusted;
|
||||
else if (adjusted)
|
||||
my_getopt_error_reporter(WARNING_LEVEL,
|
||||
"option '%s': value %g adjusted to %g",
|
||||
optp->name, old, num);
|
||||
return num;
|
||||
}
|
||||
|
||||
/*
|
||||
Get double value withing ranges
|
||||
@@ -972,15 +1070,12 @@ static double getopt_double(char *arg, const struct my_option *optp, int *err)
|
||||
num= my_strtod(arg, &end, &error);
|
||||
if (end[0] != 0 || error)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: ERROR: Invalid decimal value for option '%s'\n",
|
||||
my_progname, optp->name);
|
||||
my_getopt_error_reporter(ERROR_LEVEL,
|
||||
"Invalid decimal value for option '%s'\n", optp->name);
|
||||
*err= EXIT_ARGUMENT_INVALID;
|
||||
return 0.0;
|
||||
}
|
||||
if (optp->max_value && num > (double) optp->max_value)
|
||||
num= (double) optp->max_value;
|
||||
return max(num, (double) optp->min_value);
|
||||
return getopt_double_limit_value(num, optp, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1004,7 +1099,7 @@ static void init_one_value(const struct my_option *option, void *variable,
|
||||
*((int*) variable)= (int) getopt_ll_limit_value((int) value, option, NULL);
|
||||
break;
|
||||
case GET_ENUM:
|
||||
*((uint*) variable)= (uint) value;
|
||||
*((ulong*) variable)= (ulong) value;
|
||||
break;
|
||||
case GET_UINT:
|
||||
*((uint*) variable)= (uint) getopt_ull_limit_value((uint) value, option, NULL);
|
||||
@@ -1022,10 +1117,11 @@ static void init_one_value(const struct my_option *option, void *variable,
|
||||
*((ulonglong*) variable)= (ulonglong) getopt_ull_limit_value((ulonglong) value, option, NULL);
|
||||
break;
|
||||
case GET_SET:
|
||||
case GET_FLAGSET:
|
||||
*((ulonglong*) variable)= (ulonglong) value;
|
||||
break;
|
||||
case GET_DOUBLE:
|
||||
*((double*) variable)= (double) value;
|
||||
*((double*) variable)= ulonglong2double(value);
|
||||
break;
|
||||
case GET_STR:
|
||||
/*
|
||||
@@ -1046,8 +1142,9 @@ static void init_one_value(const struct my_option *option, void *variable,
|
||||
*/
|
||||
if ((char*) (intptr) value)
|
||||
{
|
||||
my_free((*(char**) variable), MYF(MY_ALLOW_ZERO_PTR));
|
||||
*((char**) variable)= my_strdup((char*) (intptr) value, MYF(MY_WME));
|
||||
char **pstr= (char **) variable;
|
||||
my_free(*pstr);
|
||||
*pstr= my_strdup((char*) (intptr) value, MYF(MY_WME));
|
||||
}
|
||||
break;
|
||||
default: /* dummy default to avoid compiler warnings */
|
||||
@@ -1072,7 +1169,7 @@ static void fini_one_value(const struct my_option *option, void *variable,
|
||||
DBUG_ENTER("fini_one_value");
|
||||
switch ((option->var_type & GET_TYPE_MASK)) {
|
||||
case GET_STR_ALLOC:
|
||||
my_free((*(char**) variable), MYF(MY_ALLOW_ZERO_PTR));
|
||||
my_free(*((char**) variable));
|
||||
*((char**) variable)= NULL;
|
||||
break;
|
||||
default: /* dummy default to avoid compiler warnings */
|
||||
@@ -1097,7 +1194,7 @@ void my_cleanup_options(const struct my_option *options)
|
||||
|
||||
NOTES
|
||||
We will initialize the value that is pointed to by options->value.
|
||||
If the value is of type GET_ASK_ADDR, we will also ask for the address
|
||||
If the value is of type GET_ASK_ADDR, we will ask for the address
|
||||
for a value and initialize.
|
||||
*/
|
||||
|
||||
@@ -1107,7 +1204,7 @@ static void init_variables(const struct my_option *options,
|
||||
DBUG_ENTER("init_variables");
|
||||
for (; options->name; options++)
|
||||
{
|
||||
void *variable;
|
||||
void *value;
|
||||
DBUG_PRINT("options", ("name: '%s'", options->name));
|
||||
/*
|
||||
We must set u_max_value first as for some variables
|
||||
@@ -1116,15 +1213,22 @@ static void init_variables(const struct my_option *options,
|
||||
*/
|
||||
if (options->u_max_value)
|
||||
init_one_value(options, options->u_max_value, options->max_value);
|
||||
if (options->value)
|
||||
init_one_value(options, options->value, options->def_value);
|
||||
if (options->var_type & GET_ASK_ADDR &&
|
||||
(variable= (*getopt_get_addr)("", 0, options, 0)))
|
||||
init_one_value(options, variable, options->def_value);
|
||||
value= (options->var_type & GET_ASK_ADDR ?
|
||||
(*getopt_get_addr)("", 0, options, 0) : options->value);
|
||||
if (value)
|
||||
init_one_value(options, value, options->def_value);
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/** Prints variable or option name, replacing _ with - */
|
||||
static uint print_name(const struct my_option *optp)
|
||||
{
|
||||
const char *s= optp->name;
|
||||
for (;*s;s++)
|
||||
putchar(*s == '_' ? '-' : *s);
|
||||
return s - optp->name;
|
||||
}
|
||||
|
||||
/*
|
||||
function: my_print_options
|
||||
@@ -1132,17 +1236,15 @@ static void init_variables(const struct my_option *options,
|
||||
Print help for all options and variables.
|
||||
*/
|
||||
|
||||
#include <help_start.h>
|
||||
|
||||
void my_print_help(const struct my_option *options)
|
||||
{
|
||||
uint col, name_space= 22, comment_space= 57;
|
||||
const char *line_end;
|
||||
const struct my_option *optp;
|
||||
|
||||
for (optp= options; optp->id; optp++)
|
||||
for (optp= options; optp->name; optp++)
|
||||
{
|
||||
if (optp->id < 256)
|
||||
if (optp->id && optp->id < 256)
|
||||
{
|
||||
printf(" -%c%s", optp->id, strlen(optp->name) ? ", " : " ");
|
||||
col= 6;
|
||||
@@ -1154,21 +1256,24 @@ void my_print_help(const struct my_option *options)
|
||||
}
|
||||
if (strlen(optp->name))
|
||||
{
|
||||
printf("--%s", optp->name);
|
||||
col+= 2 + (uint) strlen(optp->name);
|
||||
if ((optp->var_type & GET_TYPE_MASK) == GET_STR ||
|
||||
(optp->var_type & GET_TYPE_MASK) == GET_STR_ALLOC)
|
||||
printf("--");
|
||||
col+= 2 + print_name(optp);
|
||||
if (optp->arg_type == NO_ARG ||
|
||||
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
|
||||
{
|
||||
putchar(' ');
|
||||
col++;
|
||||
}
|
||||
else if ((optp->var_type & GET_TYPE_MASK) == GET_STR ||
|
||||
(optp->var_type & GET_TYPE_MASK) == GET_STR_ALLOC ||
|
||||
(optp->var_type & GET_TYPE_MASK) == GET_ENUM ||
|
||||
(optp->var_type & GET_TYPE_MASK) == GET_SET ||
|
||||
(optp->var_type & GET_TYPE_MASK) == GET_FLAGSET )
|
||||
{
|
||||
printf("%s=name%s ", optp->arg_type == OPT_ARG ? "[" : "",
|
||||
optp->arg_type == OPT_ARG ? "]" : "");
|
||||
col+= (optp->arg_type == OPT_ARG) ? 8 : 6;
|
||||
}
|
||||
else if ((optp->var_type & GET_TYPE_MASK) == GET_NO_ARG ||
|
||||
(optp->var_type & GET_TYPE_MASK) == GET_BOOL)
|
||||
{
|
||||
putchar(' ');
|
||||
col++;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s=#%s ", optp->arg_type == OPT_ARG ? "[" : "",
|
||||
@@ -1200,6 +1305,15 @@ void my_print_help(const struct my_option *options)
|
||||
printf("%s", comment);
|
||||
}
|
||||
putchar('\n');
|
||||
if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL)
|
||||
{
|
||||
if (optp->def_value != 0)
|
||||
{
|
||||
printf("%*s(Defaults to on; use --skip-", name_space, "");
|
||||
print_name(optp);
|
||||
printf(" to disable.)\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1213,38 +1327,55 @@ void my_print_help(const struct my_option *options)
|
||||
void my_print_variables(const struct my_option *options)
|
||||
{
|
||||
uint name_space= 34, length, nr;
|
||||
ulonglong bit, llvalue;
|
||||
ulonglong llvalue;
|
||||
char buff[255];
|
||||
const struct my_option *optp;
|
||||
|
||||
for (optp= options; optp->name; optp++)
|
||||
{
|
||||
length= strlen(optp->name)+1;
|
||||
if (length > name_space)
|
||||
name_space= length;
|
||||
}
|
||||
|
||||
printf("\nVariables (--variable-name=value)\n");
|
||||
printf("and boolean options {FALSE|TRUE} Value (after reading options)\n");
|
||||
printf("--------------------------------- -----------------------------\n");
|
||||
for (optp= options; optp->id; optp++)
|
||||
printf("%-*s%s", name_space, "and boolean options {FALSE|TRUE}",
|
||||
"Value (after reading options)\n");
|
||||
for (length=1; length < 75; length++)
|
||||
putchar(length == name_space ? ' ' : '-');
|
||||
putchar('\n');
|
||||
|
||||
for (optp= options; optp->name; optp++)
|
||||
{
|
||||
void *value= (optp->var_type & GET_ASK_ADDR ?
|
||||
(*getopt_get_addr)("", 0, optp, 0) : optp->value);
|
||||
if (value)
|
||||
{
|
||||
printf("%s ", optp->name);
|
||||
length= (uint) strlen(optp->name)+1;
|
||||
length= print_name(optp);
|
||||
for (; length < name_space; length++)
|
||||
putchar(' ');
|
||||
switch ((optp->var_type & GET_TYPE_MASK)) {
|
||||
case GET_SET:
|
||||
if (!(llvalue= *(ulonglong*) value))
|
||||
printf("%s\n", "(No default value)");
|
||||
printf("%s\n", "");
|
||||
else
|
||||
for (nr= 0, bit= 1; llvalue && nr < optp->typelib->count; nr++, bit<<=1)
|
||||
for (nr= 0; llvalue && nr < optp->typelib->count; nr++, llvalue >>=1)
|
||||
{
|
||||
if (!(bit & llvalue))
|
||||
continue;
|
||||
llvalue&= ~bit;
|
||||
printf( llvalue ? "%s," : "%s\n", get_type(optp->typelib, nr));
|
||||
if (llvalue & 1)
|
||||
printf( llvalue > 1 ? "%s," : "%s\n", get_type(optp->typelib, nr));
|
||||
}
|
||||
break;
|
||||
case GET_FLAGSET:
|
||||
llvalue= *(ulonglong*) value;
|
||||
for (nr= 0; llvalue && nr < optp->typelib->count; nr++, llvalue >>=1)
|
||||
{
|
||||
printf("%s%s=", (nr ? "," : ""), get_type(optp->typelib, nr));
|
||||
printf(llvalue & 1 ? "on" : "off");
|
||||
}
|
||||
printf("\n");
|
||||
break;
|
||||
case GET_ENUM:
|
||||
printf("%s\n", get_type(optp->typelib, *(uint*) value));
|
||||
printf("%s\n", get_type(optp->typelib, *(ulong*) value));
|
||||
break;
|
||||
case GET_STR:
|
||||
case GET_STR_ALLOC: /* fall through */
|
||||
@@ -1276,6 +1407,9 @@ void my_print_variables(const struct my_option *options)
|
||||
case GET_DOUBLE:
|
||||
printf("%g\n", *(double*) value);
|
||||
break;
|
||||
case GET_NO_ARG:
|
||||
printf("(No default value)\n");
|
||||
break;
|
||||
default:
|
||||
printf("(Disabled)\n");
|
||||
break;
|
||||
@@ -1283,5 +1417,3 @@ void my_print_variables(const struct my_option *options)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include <help_end.h>
|
||||
|
||||
Reference in New Issue
Block a user