Commit f7b201e1 authored by unknown's avatar unknown

Fixed some bugs in my_getopt.c, added functionality for new GET_*

types, migrated mysqld.cc to use my_getopt.


include/my_getopt.h:
  
  Added missing types; GET_INT, GET_UINT, GET_ULONG, GET_ULL
mysys/my_getopt.c:
  - Fixed a bug in processing short options; variable value was set
    wrongly after processing it in get_one_option(), when it needed
    to be done before it.
  - Fixed a bug in setting variable values; if type was OPT_ARG,
    a call without argument destroyed the default value
  - Added functionality for new GET_* types.
sql/mysqld.cc:
  Changed mysqld.cc to use my_getopt.
parent 25623f6f
...@@ -16,7 +16,8 @@ ...@@ -16,7 +16,8 @@
C_MODE_START C_MODE_START
enum get_opt_var_type { GET_NO_ARG, GET_BOOL, GET_LONG, GET_LL, GET_STR }; enum get_opt_var_type { GET_NO_ARG, GET_BOOL, GET_INT, GET_UINT, GET_LONG,
GET_ULONG, GET_LL, GET_ULL, GET_STR };
enum get_opt_arg_type { NO_ARG, OPT_ARG, REQUIRED_ARG }; enum get_opt_arg_type { NO_ARG, OPT_ARG, REQUIRED_ARG };
struct my_option struct my_option
......
...@@ -26,8 +26,11 @@ static int findopt (char *optpat, uint length, ...@@ -26,8 +26,11 @@ static int findopt (char *optpat, uint length,
static my_bool compare_strings (register const char *s, register const char *t, static my_bool compare_strings (register const char *s, register const char *t,
uint length); uint length);
static longlong getopt_ll (char *arg, const struct my_option *optp, int *err); 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 void init_variables(const struct my_option *options); static void init_variables(const struct my_option *options);
static int setval (const struct my_option *opts, char *argument,
my_bool set_maximum_value);
#define DISABLE_OPTION_COUNT 2 #define DISABLE_OPTION_COUNT 2
...@@ -66,15 +69,16 @@ int handle_options(int *argc, char ***argv, ...@@ -66,15 +69,16 @@ int handle_options(int *argc, char ***argv,
char *)) char *))
{ {
uint opt_found, argvpos= 0, length, spec_len, i; uint opt_found, argvpos= 0, length, spec_len, i;
int err= 0;
my_bool end_of_options= 0, must_be_var, set_maximum_value, special_used; my_bool end_of_options= 0, must_be_var, set_maximum_value, special_used;
char *progname= *(*argv), **pos, *optend, *prev_found; char *progname= *(*argv), **pos, *optend, *prev_found;
const struct my_option *optp; const struct my_option *optp;
int error;
LINT_INIT(opt_found); LINT_INIT(opt_found);
(*argc)--; /* Skip the program name */ (*argc)--; /* Skip the program name */
(*argv)++; /* --- || ---- */ (*argv)++; /* --- || ---- */
init_variables(longopts); init_variables(longopts);
for (pos= *argv; *pos; pos++) for (pos= *argv; *pos; pos++)
{ {
char *cur_arg= *pos; char *cur_arg= *pos;
...@@ -337,6 +341,13 @@ int handle_options(int *argc, char ***argv, ...@@ -337,6 +341,13 @@ int handle_options(int *argc, char ***argv,
/* the other loop will break, because *optend + 1 == 0 */ /* the other loop will break, because *optend + 1 == 0 */
} }
} }
if ((error= setval(optp, argument, set_maximum_value)))
{
fprintf(stderr,
"%s: Error while setting value '%s' to '%s'\n",
progname, argument, optp->name);
return error;
}
get_one_option(optp->id, optp, argument); get_one_option(optp->id, optp, argument);
break; break;
} }
...@@ -351,25 +362,12 @@ int handle_options(int *argc, char ***argv, ...@@ -351,25 +362,12 @@ int handle_options(int *argc, char ***argv,
(*argc)--; /* option handled (short), decrease argument count */ (*argc)--; /* option handled (short), decrease argument count */
continue; continue;
} }
if (optp->value) if ((error= setval(optp, argument, set_maximum_value)))
{
gptr *result_pos= (set_maximum_value) ?
optp->u_max_value : optp->value;
if (!result_pos)
{ {
fprintf(stderr, fprintf(stderr,
"%s: Can't set a value for %s\n", progname, optp->name); "%s: Error while setting value '%s' to '%s'\n",
return ERR_NO_PTR_TO_VARIABLE; progname, argument, optp->name);
} return error;
if (optp->var_type == GET_LONG)
*((long*) result_pos)= (long) getopt_ll(argument, optp, &err);
else if (optp->var_type == GET_LL)
*((longlong*) result_pos)= getopt_ll(argument, optp, &err);
else if (optp->var_type == GET_STR)
*((char**) result_pos)= argument;
if (err)
return ERR_UNKNOWN_SUFFIX;
} }
get_one_option(optp->id, optp, argument); get_one_option(optp->id, optp, argument);
...@@ -381,6 +379,41 @@ int handle_options(int *argc, char ***argv, ...@@ -381,6 +379,41 @@ int handle_options(int *argc, char ***argv,
return 0; return 0;
} }
/*
function: setval
Arguments: opts, argument
Will set the option value to given value
*/
static int setval (const struct my_option *opts, char *argument,
my_bool set_maximum_value)
{
int err= 0;
if (opts->value && argument)
{
gptr *result_pos= (set_maximum_value) ?
opts->u_max_value : opts->value;
if (!result_pos)
return ERR_NO_PTR_TO_VARIABLE;
if (opts->var_type == GET_INT || opts->var_type == GET_UINT)
*((int*) result_pos)= (int) getopt_ll(argument, opts, &err);
else if (opts->var_type == GET_LONG || opts->var_type == GET_ULONG)
*((long*) result_pos)= (long) getopt_ll(argument, opts, &err);
else if (opts->var_type == GET_LL)
*((longlong*) result_pos)= getopt_ll(argument, opts, &err);
else if (opts->var_type == GET_ULL)
*((ulonglong*) result_pos)= getopt_ull(argument, opts, &err);
else if (opts->var_type == GET_STR)
*((char**) result_pos)= argument;
if (err)
return ERR_UNKNOWN_SUFFIX;
}
return 0;
}
/* /*
function: findopt function: findopt
...@@ -436,25 +469,20 @@ static my_bool compare_strings(register const char *s, register const char *t, ...@@ -436,25 +469,20 @@ static my_bool compare_strings(register const char *s, register const char *t,
return 0; return 0;
} }
/* /*
function: getopt_ll function: eval_num_suffix
Evaluates and returns the value that user gave as an argument Transforms a number with a suffix to real number. Suffix can
to a variable. Recognizes (case insensitive) K as KILO, M as MEGA be k|K for kilo, m|M for mega or g|G for giga.
and G as GIGA bytes. Some values must be in certain blocks, as
defined in the given my_option struct, this function will check
that those values are honored.
In case of an error, set error value in *err.
*/ */
static longlong getopt_ll (char *arg, const struct my_option *optp, int *err) static longlong eval_num_suffix (char *argument, int *error, char *option_name)
{ {
char *endchar; char *endchar;
longlong num; longlong num;
*err= 0; *error= 0;
num= strtoll(arg, &endchar, 10); num= strtoll(argument, &endchar, 10);
if (*endchar == 'k' || *endchar == 'K') if (*endchar == 'k' || *endchar == 'K')
num*= 1024L; num*= 1024L;
else if (*endchar == 'm' || *endchar == 'M') else if (*endchar == 'm' || *endchar == 'M')
...@@ -465,9 +493,29 @@ static longlong getopt_ll (char *arg, const struct my_option *optp, int *err) ...@@ -465,9 +493,29 @@ static longlong getopt_ll (char *arg, const struct my_option *optp, int *err)
{ {
fprintf(stderr, fprintf(stderr,
"Unknown suffix '%c' used for variable '%s' (value '%s')\n", "Unknown suffix '%c' used for variable '%s' (value '%s')\n",
*endchar, optp->name, arg); *endchar, option_name, argument);
*err= 1; *error= 1;
return 0;
} }
return num;
}
/*
function: getopt_ll
Evaluates and returns the value that user gave as an argument
to a variable. Recognizes (case insensitive) K as KILO, M as MEGA
and G as GIGA bytes. Some values must be in certain blocks, as
defined in the given my_option struct, this function will check
that those values are honored.
In case of an error, set error value in *err.
*/
static longlong getopt_ll (char *arg, const struct my_option *optp, int *err)
{
longlong num;
num= eval_num_suffix(arg, err, (char*) optp->name);
if (num < (longlong) optp->min_value) if (num < (longlong) optp->min_value)
num= (longlong) optp->min_value; num= (longlong) optp->min_value;
else if (num > 0 && (ulonglong) num > (ulonglong) (ulong) optp->max_value else if (num > 0 && (ulonglong) num > (ulonglong) (ulong) optp->max_value
...@@ -480,6 +528,29 @@ static longlong getopt_ll (char *arg, const struct my_option *optp, int *err) ...@@ -480,6 +528,29 @@ static longlong getopt_ll (char *arg, const struct my_option *optp, int *err)
1L)); 1L));
} }
/*
function: getopt_ull
This is the same as getopt_ll, but is meant for unsigned long long
values.
*/
static ulonglong getopt_ull (char *arg, const struct my_option *optp, int *err)
{
ulonglong num;
num= eval_num_suffix(arg, err, (char*) optp->name);
if (num < (ulonglong) optp->min_value)
num= (ulonglong) optp->min_value;
else if (num > 0 && (ulonglong) num > (ulonglong) (ulong) optp->max_value
&& optp->max_value) // if max value is not set -> no upper limit
num= (ulonglong) (ulong) optp->max_value;
num= ((num - (ulonglong) optp->sub_size) / (optp->block_size ?
(ulonglong) optp->block_size :
1L));
return (ulonglong) (num * (optp->block_size ? (ulonglong) optp->block_size :
1L));
}
/* /*
function: init_variables function: init_variables
...@@ -493,12 +564,24 @@ static void init_variables(const struct my_option *options) ...@@ -493,12 +564,24 @@ static void init_variables(const struct my_option *options)
{ {
if (options->value) if (options->value)
{ {
if (options->var_type == GET_LONG) if (options->var_type == GET_INT)
*((int*) options->u_max_value)= *((int*) options->value)=
(int) options->def_value;
else if (options->var_type == GET_UINT)
*((uint*) options->u_max_value)= *((uint*) options->value)=
(uint) options->def_value;
else if (options->var_type == GET_LONG)
*((long*) options->u_max_value)= *((long*) options->value)= *((long*) options->u_max_value)= *((long*) options->value)=
(long) options->def_value; (long) options->def_value;
else if (options->var_type == GET_ULONG)
*((ulong*) options->u_max_value)= *((ulong*) options->value)=
(ulong) options->def_value;
else if (options->var_type == GET_LL) else if (options->var_type == GET_LL)
*((longlong*) options->u_max_value)= *((longlong*) options->value)= *((longlong*) options->u_max_value)= *((longlong*) options->value)=
options->def_value; (longlong) options->def_value;
else if (options->var_type == GET_ULL)
*((ulonglong*) options->u_max_value)= *((ulonglong*) options->value)=
(ulonglong) options->def_value;
} }
} }
} }
...@@ -604,6 +687,20 @@ void my_print_variables(const struct my_option *options) ...@@ -604,6 +687,20 @@ void my_print_variables(const struct my_option *options)
else else
printf("(No default value)\n"); printf("(No default value)\n");
} }
else if (optp->var_type == GET_INT)
{
if (!optp->def_value && !*((int*) optp->value))
printf("(No default value)\n");
else
printf("%d\n", *((int*) optp->value));
}
else if (optp->var_type == GET_UINT)
{
if (!optp->def_value && !*((uint*) optp->value))
printf("(No default value)\n");
else
printf("%d\n", *((uint*) optp->value));
}
else if (optp->var_type == GET_LONG) else if (optp->var_type == GET_LONG)
{ {
if (!optp->def_value && !*((long*) optp->value)) if (!optp->def_value && !*((long*) optp->value))
...@@ -611,13 +708,27 @@ void my_print_variables(const struct my_option *options) ...@@ -611,13 +708,27 @@ void my_print_variables(const struct my_option *options)
else else
printf("%lu\n", *((long*) optp->value)); printf("%lu\n", *((long*) optp->value));
} }
else if (optp->var_type == GET_ULONG)
{
if (!optp->def_value && !*((ulong*) optp->value))
printf("(No default value)\n");
else else
printf("%lu\n", *((ulong*) optp->value));
}
else if (optp->var_type == GET_LL)
{ {
if (!optp->def_value && !*((longlong*) optp->value)) if (!optp->def_value && !*((longlong*) optp->value))
printf("(No default value)\n"); printf("(No default value)\n");
else else
printf("%s\n", llstr(*((longlong*) optp->value), buff)); printf("%s\n", llstr(*((longlong*) optp->value), buff));
} }
else if (optp->var_type == GET_ULL)
{
if (!optp->def_value && !*((ulonglong*) optp->value))
printf("(No default value)\n");
else
printf("%s\n", longlong2str(*((ulonglong*) optp->value), buff, 10));
}
} }
} }
} }
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment