summaryrefslogtreecommitdiff
path: root/mysys/my_getopt.c
diff options
context:
space:
mode:
Diffstat (limited to 'mysys/my_getopt.c')
-rw-r--r--mysys/my_getopt.c119
1 files changed, 52 insertions, 67 deletions
diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c
index c4f83475f7b..9747ee4214e 100644
--- a/mysys/my_getopt.c
+++ b/mysys/my_getopt.c
@@ -1,6 +1,6 @@
/*
Copyright (c) 2002, 2013, Oracle and/or its affiliates
- Copyright (c) 2009, 2015, MariaDB
+ Copyright (c) 2009, 2020, MariaDB
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
@@ -15,15 +15,15 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
-#include <my_global.h>
+#include <mysys_priv.h>
#include <my_default.h>
#include <m_string.h>
#include <stdlib.h>
-#include <my_sys.h>
#include <mysys_err.h>
#include <my_getopt.h>
#include <errno.h>
+my_bool is_file_marker(const char* arg);
typedef void (*init_func_p)(const struct my_option *option, void *variable,
longlong value);
@@ -31,7 +31,7 @@ static void default_reporter(enum loglevel level, const char *format, ...);
my_error_reporter my_getopt_error_reporter= &default_reporter;
static int findopt(char *, uint, const struct my_option **, const char **);
-my_bool getopt_compare_strings(const char *, const char *, uint);
+static 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 *, const struct my_option *, int *);
static double getopt_double(char *arg, const struct my_option *optp, int *err);
@@ -85,8 +85,9 @@ my_bool my_getopt_prefix_matching= 1;
*/
my_bool my_handle_options_init_variables = 1;
-static void default_reporter(enum loglevel level,
- const char *format, ...)
+my_getopt_value my_getopt_get_addr= 0;
+
+static void default_reporter(enum loglevel level, const char *format, ...)
{
va_list args;
DBUG_ENTER("default_reporter");
@@ -103,13 +104,6 @@ static void default_reporter(enum loglevel level,
DBUG_VOID_RETURN;
}
-static my_getopt_value getopt_get_addr;
-
-void my_getopt_register_get_addr(my_getopt_value func_addr)
-{
- getopt_get_addr= func_addr;
-}
-
union ull_dbl
{
ulonglong ull;
@@ -146,7 +140,7 @@ double getopt_ulonglong2double(ulonglong v)
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.
+ Call the '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.
@@ -193,19 +187,18 @@ double getopt_ulonglong2double(ulonglong v)
@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.
+ @param [in] get_one_option callback function to process each option
@return error in case of ambiguous or unknown options,
0 on success.
*/
-int handle_options(int *argc, char ***argv,
- const struct my_option *longopts,
+int handle_options(int *argc, char ***argv, const struct my_option *longopts,
my_get_one_option get_one_option)
{
uint UNINIT_VAR(opt_found), argvpos= 0, length;
my_bool end_of_options= 0, must_be_var, set_maximum_value,
option_is_loose, option_is_autoset;
char **pos, **pos_end, *optend, *opt_str, key_name[FN_REFLEN];
+ char *filename= (char*)"";
const char *UNINIT_VAR(prev_found);
const struct my_option *optp;
void *value;
@@ -214,41 +207,36 @@ int handle_options(int *argc, char ***argv,
DBUG_ENTER("handle_options");
/* handle_options() assumes arg0 (program name) always exists */
- DBUG_ASSERT(argc && *argc >= 1);
- DBUG_ASSERT(argv && *argv);
+ DBUG_ASSERT(*argc >= 1);
+ DBUG_ASSERT(*argv);
(*argc)--; /* Skip the program name */
(*argv)++; /* --- || ---- */
if (my_handle_options_init_variables)
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 (my_getopt_is_args_separator(*pos))
- {
- is_cmdline_arg= 0;
- break;
- }
- }
+ is_cmdline_arg= !is_file_marker(**argv);
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 && (my_getopt_is_args_separator(cur_arg)))
+ if (!is_cmdline_arg)
{
- is_cmdline_arg= 1;
-
- /* save the separator too if skip unknown options */
- if (my_getopt_skip_unknown)
- (*argv)[argvpos++]= cur_arg;
- else
- (*argc)--;
- continue;
+ if (is_file_marker(cur_arg))
+ {
+ pos++;
+ filename= *pos;
+ is_cmdline_arg= *filename == 0; /* empty file name = command line */
+ if (my_getopt_skip_unknown)
+ {
+ (*argv)[argvpos++]= cur_arg;
+ (*argv)[argvpos++]= filename;
+ }
+ else
+ (*argc)-= 2;
+ continue;
+ }
}
if (cur_arg[0] == '-' && cur_arg[1] && !end_of_options) /* must be opt */
{
@@ -415,9 +403,9 @@ int handle_options(int *argc, char ***argv,
DBUG_RETURN(EXIT_OPTION_DISABLED);
}
error= 0;
- value= optp->var_type & GET_ASK_ADDR ?
- (*getopt_get_addr)(key_name, (uint) strlen(key_name), optp, &error) :
- optp->value;
+ value= optp->var_type & GET_ASK_ADDR
+ ? (*my_getopt_get_addr)(key_name, (uint)strlen(key_name), optp, &error)
+ : optp->value;
if (error)
DBUG_RETURN(error);
@@ -460,9 +448,9 @@ int handle_options(int *argc, char ***argv,
my_progname, optp->name, optend);
continue;
}
- if (get_one_option && get_one_option(optp->id, optp,
- *((my_bool*) value) ?
- enabled_my_option : disabled_my_option))
+ if (get_one_option(optp, *((my_bool*) value) ?
+ enabled_my_option : disabled_my_option,
+ filename))
DBUG_RETURN(EXIT_ARGUMENT_INVALID);
continue;
}
@@ -479,12 +467,7 @@ int handle_options(int *argc, char ***argv,
DBUG_RETURN(EXIT_NO_ARGUMENT_ALLOWED);
}
- /*
- We support automatic setup only via get_one_option and only for
- marked options.
- */
- if (!get_one_option ||
- !(optp->var_type & GET_AUTO))
+ if (!(optp->var_type & GET_AUTO))
{
my_getopt_error_reporter(option_is_loose ?
WARNING_LEVEL : ERROR_LEVEL,
@@ -500,10 +483,11 @@ int handle_options(int *argc, char ***argv,
}
else if (optp->arg_type == REQUIRED_ARG && !optend)
{
- /* 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'.
- */
+ /*
+ 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)
@@ -541,7 +525,7 @@ int handle_options(int *argc, char ***argv,
optp->arg_type == NO_ARG)
{
*((my_bool*) optp->value)= (my_bool) 1;
- if (get_one_option && get_one_option(optp->id, optp, argument))
+ if (get_one_option(optp, argument, filename))
DBUG_RETURN(EXIT_UNSPECIFIED_ERROR);
continue;
}
@@ -561,7 +545,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 && get_one_option(optp->id, optp, argument))
+ if (get_one_option(optp, argument, filename))
DBUG_RETURN(EXIT_UNSPECIFIED_ERROR);
continue;
}
@@ -582,7 +566,7 @@ int handle_options(int *argc, char ***argv,
if ((error= setval(optp, optp->value, argument,
set_maximum_value)))
DBUG_RETURN(error);
- if (get_one_option && get_one_option(optp->id, optp, argument))
+ if (get_one_option(optp, argument, filename))
DBUG_RETURN(EXIT_UNSPECIFIED_ERROR);
break;
}
@@ -629,7 +613,7 @@ int handle_options(int *argc, char ***argv,
((error= setval(optp, value, argument, set_maximum_value))) &&
!option_is_loose)
DBUG_RETURN(error);
- if (get_one_option && get_one_option(optp->id, optp, argument))
+ if (get_one_option(optp, argument, filename))
DBUG_RETURN(EXIT_UNSPECIFIED_ERROR);
(*argc)--; /* option handled (long), decrease argument count */
@@ -776,7 +760,8 @@ static int setval(const struct my_option *opts, void *value, char *argument,
break;
case GET_STR_ALLOC:
my_free(*((char**) value));
- if (!(*((char**) value)= my_strdup(argument == enabled_my_option ? "" :
+ if (!(*((char**) value)= my_strdup(key_memory_defaults,
+ argument == enabled_my_option ? "" :
argument, MYF(MY_WME))))
{
res= EXIT_OUT_OF_MEMORY;
@@ -1365,7 +1350,7 @@ static void init_one_value(const struct my_option *option, void *variable,
{
char **pstr= (char **) variable;
my_free(*pstr);
- *pstr= my_strdup((char*) (intptr) value, MYF(MY_WME));
+ *pstr= my_strdup(key_memory_defaults, (char*) (intptr) value, MYF(MY_WME));
}
break;
default: /* dummy default to avoid compiler warnings */
@@ -1437,8 +1422,8 @@ static void init_variables(const struct my_option *options,
*/
if (options->u_max_value)
func_init_one_value(options, options->u_max_value, options->max_value);
- value= (options->var_type & GET_ASK_ADDR ?
- (*getopt_get_addr)("", 0, options, 0) : options->value);
+ value= options->var_type & GET_ASK_ADDR ?
+ (*my_getopt_get_addr)("", 0, options, 0) : options->value;
if (value)
func_init_one_value(options, value, options->def_value);
}
@@ -1642,8 +1627,8 @@ void my_print_variables(const struct my_option *options)
for (optp= options; optp->name; optp++)
{
- void *value= (optp->var_type & GET_ASK_ADDR ?
- (*getopt_get_addr)("", 0, optp, 0) : optp->value);
+ void *value= optp->var_type & GET_ASK_ADDR ?
+ (*my_getopt_get_addr)("", 0, optp, 0) : optp->value;
if (value)
{
length= print_name(optp);