summaryrefslogtreecommitdiff
path: root/mysys/my_getopt.c
diff options
context:
space:
mode:
authorunknown <jani@rhols221.adsl.netsonic.fi>2002-05-07 20:35:06 +0300
committerunknown <jani@rhols221.adsl.netsonic.fi>2002-05-07 20:35:06 +0300
commit9f8a75a168774f9ada4b2b68fc494ac514d84388 (patch)
treeff03f00462c085ba6d187bd79a5392a47b3adf0b /mysys/my_getopt.c
parent90bd3236370ea78ee3a1e6bc04620093c08d4035 (diff)
downloadmariadb-git-9f8a75a168774f9ada4b2b68fc494ac514d84388.tar.gz
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.
Diffstat (limited to 'mysys/my_getopt.c')
-rw-r--r--mysys/my_getopt.c185
1 files changed, 148 insertions, 37 deletions
diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c
index b17d1463121..4a6bfa5036a 100644
--- a/mysys/my_getopt.c
+++ b/mysys/my_getopt.c
@@ -26,8 +26,11 @@ static int findopt (char *optpat, uint length,
static my_bool compare_strings (register const char *s, register const char *t,
uint length);
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 int setval (const struct my_option *opts, char *argument,
+ my_bool set_maximum_value);
#define DISABLE_OPTION_COUNT 2
@@ -66,15 +69,16 @@ int handle_options(int *argc, char ***argv,
char *))
{
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;
char *progname= *(*argv), **pos, *optend, *prev_found;
const struct my_option *optp;
+ int error;
LINT_INIT(opt_found);
(*argc)--; /* Skip the program name */
(*argv)++; /* --- || ---- */
init_variables(longopts);
+
for (pos= *argv; *pos; pos++)
{
char *cur_arg= *pos;
@@ -337,6 +341,13 @@ int handle_options(int *argc, char ***argv,
/* 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);
break;
}
@@ -351,25 +362,12 @@ int handle_options(int *argc, char ***argv,
(*argc)--; /* option handled (short), decrease argument count */
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,
- "%s: Can't set a value for %s\n", progname, optp->name);
- return ERR_NO_PTR_TO_VARIABLE;
- }
- 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;
+ fprintf(stderr,
+ "%s: Error while setting value '%s' to '%s'\n",
+ progname, argument, optp->name);
+ return error;
}
get_one_option(optp->id, optp, argument);
@@ -381,6 +379,41 @@ int handle_options(int *argc, char ***argv,
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
@@ -436,25 +469,20 @@ static my_bool compare_strings(register const char *s, register const char *t,
return 0;
}
+/*
+ function: eval_num_suffix
-/*
- 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.
+ Transforms a number with a suffix to real number. Suffix can
+ be k|K for kilo, m|M for mega or g|G for giga.
*/
-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;
longlong num;
- *err= 0;
- num= strtoll(arg, &endchar, 10);
+ *error= 0;
+ num= strtoll(argument, &endchar, 10);
if (*endchar == 'k' || *endchar == 'K')
num*= 1024L;
else if (*endchar == 'm' || *endchar == 'M')
@@ -465,9 +493,29 @@ static longlong getopt_ll (char *arg, const struct my_option *optp, int *err)
{
fprintf(stderr,
"Unknown suffix '%c' used for variable '%s' (value '%s')\n",
- *endchar, optp->name, arg);
- *err= 1;
+ *endchar, option_name, argument);
+ *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)
num= (longlong) optp->min_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)
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
@@ -493,12 +564,24 @@ static void init_variables(const struct my_option *options)
{
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->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)
*((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)
else
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)
{
if (!optp->def_value && !*((long*) optp->value))
@@ -611,13 +708,27 @@ void my_print_variables(const struct my_option *options)
else
printf("%lu\n", *((long*) optp->value));
}
- else
+ else if (optp->var_type == GET_ULONG)
+ {
+ if (!optp->def_value && !*((ulong*) optp->value))
+ printf("(No default value)\n");
+ else
+ printf("%lu\n", *((ulong*) optp->value));
+ }
+ else if (optp->var_type == GET_LL)
{
if (!optp->def_value && !*((longlong*) optp->value))
printf("(No default value)\n");
else
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));
+ }
}
}
}