mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
cleanup: my_getopt, get_one_option isn't optional
it turns out that practically every single user of handle_options() used the get_one_option callback. Simplify the code, make it mandatory, adjust unit tests.
This commit is contained in:
@@ -110,7 +110,8 @@ extern my_error_reporter my_getopt_error_reporter;
|
|||||||
extern my_getopt_value my_getopt_get_addr;
|
extern my_getopt_value my_getopt_get_addr;
|
||||||
|
|
||||||
extern int handle_options (int *argc, char ***argv,
|
extern int handle_options (int *argc, char ***argv,
|
||||||
const struct my_option *longopts, my_get_one_option);
|
const struct my_option *longopts, my_get_one_option)
|
||||||
|
__attribute__((nonnull));
|
||||||
extern void my_cleanup_options(const struct my_option *options);
|
extern void my_cleanup_options(const struct my_option *options);
|
||||||
extern void my_print_help(const struct my_option *options);
|
extern void my_print_help(const struct my_option *options);
|
||||||
extern void my_print_variables(const struct my_option *options);
|
extern void my_print_variables(const struct my_option *options);
|
||||||
|
@@ -134,7 +134,7 @@ double getopt_ulonglong2double(ulonglong v)
|
|||||||
or until the end of argv. Parse options, check that the given option
|
or until the end of argv. Parse options, check that the given option
|
||||||
matches with one of the options in struct 'my_option'.
|
matches with one of the options in struct 'my_option'.
|
||||||
Check that option was given an argument if it requires one
|
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
|
Note that handle_options() can be invoked multiple times to
|
||||||
parse a command line in several steps.
|
parse a command line in several steps.
|
||||||
@@ -181,13 +181,11 @@ double getopt_ulonglong2double(ulonglong v)
|
|||||||
@param [in, out] argc command line options (count)
|
@param [in, out] argc command line options (count)
|
||||||
@param [in, out] argv command line options (values)
|
@param [in, out] argv command line options (values)
|
||||||
@param [in] longopts descriptor of all valid options
|
@param [in] longopts descriptor of all valid options
|
||||||
@param [in] get_one_option optional callback function to process each option,
|
@param [in] get_one_option callback function to process each option
|
||||||
can be NULL.
|
|
||||||
@return error in case of ambiguous or unknown options,
|
@return error in case of ambiguous or unknown options,
|
||||||
0 on success.
|
0 on success.
|
||||||
*/
|
*/
|
||||||
int handle_options(int *argc, char ***argv,
|
int handle_options(int *argc, char ***argv, const struct my_option *longopts,
|
||||||
const struct my_option *longopts,
|
|
||||||
my_get_one_option get_one_option)
|
my_get_one_option get_one_option)
|
||||||
{
|
{
|
||||||
uint UNINIT_VAR(opt_found), argvpos= 0, length;
|
uint UNINIT_VAR(opt_found), argvpos= 0, length;
|
||||||
@@ -447,8 +445,7 @@ int handle_options(int *argc, char ***argv,
|
|||||||
my_progname, optp->name, optend);
|
my_progname, optp->name, optend);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (get_one_option && get_one_option(optp->id, optp,
|
if (get_one_option(optp->id, optp, *((my_bool*) value) ?
|
||||||
*((my_bool*) value) ?
|
|
||||||
enabled_my_option : disabled_my_option))
|
enabled_my_option : disabled_my_option))
|
||||||
DBUG_RETURN(EXIT_ARGUMENT_INVALID);
|
DBUG_RETURN(EXIT_ARGUMENT_INVALID);
|
||||||
continue;
|
continue;
|
||||||
@@ -466,12 +463,7 @@ int handle_options(int *argc, char ***argv,
|
|||||||
|
|
||||||
DBUG_RETURN(EXIT_NO_ARGUMENT_ALLOWED);
|
DBUG_RETURN(EXIT_NO_ARGUMENT_ALLOWED);
|
||||||
}
|
}
|
||||||
/*
|
if (!(optp->var_type & GET_AUTO))
|
||||||
We support automatic setup only via get_one_option and only for
|
|
||||||
marked options.
|
|
||||||
*/
|
|
||||||
if (!get_one_option ||
|
|
||||||
!(optp->var_type & GET_AUTO))
|
|
||||||
{
|
{
|
||||||
my_getopt_error_reporter(option_is_loose ?
|
my_getopt_error_reporter(option_is_loose ?
|
||||||
WARNING_LEVEL : ERROR_LEVEL,
|
WARNING_LEVEL : ERROR_LEVEL,
|
||||||
@@ -487,7 +479,8 @@ int handle_options(int *argc, char ***argv,
|
|||||||
}
|
}
|
||||||
else if (optp->arg_type == REQUIRED_ARG && !optend)
|
else if (optp->arg_type == REQUIRED_ARG && !optend)
|
||||||
{
|
{
|
||||||
/* Check if there are more arguments after this one,
|
/*
|
||||||
|
Check if there are more arguments after this one,
|
||||||
Note: options loaded from config file that requires value
|
Note: options loaded from config file that requires value
|
||||||
should always be in the form '--option=value'.
|
should always be in the form '--option=value'.
|
||||||
*/
|
*/
|
||||||
@@ -528,7 +521,7 @@ int handle_options(int *argc, char ***argv,
|
|||||||
optp->arg_type == NO_ARG)
|
optp->arg_type == NO_ARG)
|
||||||
{
|
{
|
||||||
*((my_bool*) optp->value)= (my_bool) 1;
|
*((my_bool*) optp->value)= (my_bool) 1;
|
||||||
if (get_one_option && get_one_option(optp->id, optp, argument))
|
if (get_one_option(optp->id, optp, argument))
|
||||||
DBUG_RETURN(EXIT_UNSPECIFIED_ERROR);
|
DBUG_RETURN(EXIT_UNSPECIFIED_ERROR);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -548,7 +541,7 @@ int handle_options(int *argc, char ***argv,
|
|||||||
{
|
{
|
||||||
if (optp->var_type == GET_BOOL)
|
if (optp->var_type == GET_BOOL)
|
||||||
*((my_bool*) optp->value)= (my_bool) 1;
|
*((my_bool*) optp->value)= (my_bool) 1;
|
||||||
if (get_one_option && get_one_option(optp->id, optp, argument))
|
if (get_one_option(optp->id, optp, argument))
|
||||||
DBUG_RETURN(EXIT_UNSPECIFIED_ERROR);
|
DBUG_RETURN(EXIT_UNSPECIFIED_ERROR);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -569,7 +562,7 @@ int handle_options(int *argc, char ***argv,
|
|||||||
if ((error= setval(optp, optp->value, argument,
|
if ((error= setval(optp, optp->value, argument,
|
||||||
set_maximum_value)))
|
set_maximum_value)))
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
if (get_one_option && get_one_option(optp->id, optp, argument))
|
if (get_one_option(optp->id, optp, argument))
|
||||||
DBUG_RETURN(EXIT_UNSPECIFIED_ERROR);
|
DBUG_RETURN(EXIT_UNSPECIFIED_ERROR);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -616,7 +609,7 @@ int handle_options(int *argc, char ***argv,
|
|||||||
((error= setval(optp, value, argument, set_maximum_value))) &&
|
((error= setval(optp, value, argument, set_maximum_value))) &&
|
||||||
!option_is_loose)
|
!option_is_loose)
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
if (get_one_option && get_one_option(optp->id, optp, argument))
|
if (get_one_option(optp->id, optp, argument))
|
||||||
DBUG_RETURN(EXIT_UNSPECIFIED_ERROR);
|
DBUG_RETURN(EXIT_UNSPECIFIED_ERROR);
|
||||||
|
|
||||||
(*argc)--; /* option handled (long), decrease argument count */
|
(*argc)--; /* option handled (long), decrease argument count */
|
||||||
|
@@ -60,6 +60,13 @@ static struct my_option mopts_options[]=
|
|||||||
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
|
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
my_bool dummy_get_one_option(int optid __attribute__((unused)),
|
||||||
|
const struct my_option *opt __attribute__((unused)),
|
||||||
|
char *argument __attribute__((unused)))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
void run(const char *arg, ...)
|
void run(const char *arg, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
@@ -74,7 +81,7 @@ void run(const char *arg, ...)
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
arg_c= (int)(arg_v - arg_s);
|
arg_c= (int)(arg_v - arg_s);
|
||||||
arg_v= arg_s;
|
arg_v= arg_s;
|
||||||
res= handle_options(&arg_c, &arg_v, mopts_options, 0);
|
res= handle_options(&arg_c, &arg_v, mopts_options, &dummy_get_one_option);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mopts1_argc= 4;
|
int mopts1_argc= 4;
|
||||||
@@ -84,7 +91,7 @@ void test_mopts1()
|
|||||||
int rc;
|
int rc;
|
||||||
char **av= (char **)mopts1_argv;
|
char **av= (char **)mopts1_argv;
|
||||||
|
|
||||||
rc= handle_options(&mopts1_argc, &av, mopts_options, NULL);
|
rc= handle_options(&mopts1_argc, &av, mopts_options, &dummy_get_one_option);
|
||||||
ok( (rc == 0), "%s", "test_mopts1 call");
|
ok( (rc == 0), "%s", "test_mopts1 call");
|
||||||
ok( (mopts_num == 122), "%s", "test_mopts1 num");
|
ok( (mopts_num == 122), "%s", "test_mopts1 num");
|
||||||
ok( (strncmp(mopts_str, "str", 4) == 0), "%s", "test_mopts1 str");
|
ok( (strncmp(mopts_str, "str", 4) == 0), "%s", "test_mopts1 str");
|
||||||
@@ -98,7 +105,7 @@ void test_mopts2()
|
|||||||
int rc;
|
int rc;
|
||||||
char **av= (char **)mopts2_argv;
|
char **av= (char **)mopts2_argv;
|
||||||
|
|
||||||
rc= handle_options(&mopts2_argc, &av, mopts_options, NULL);
|
rc= handle_options(&mopts2_argc, &av, mopts_options, &dummy_get_one_option);
|
||||||
ok( (rc == 0), "%s", "test_mopts2 call");
|
ok( (rc == 0), "%s", "test_mopts2 call");
|
||||||
ok( (mopts_num == 124), "%s", "test_mopts2 num");
|
ok( (mopts_num == 124), "%s", "test_mopts2 num");
|
||||||
ok( (strncmp(mopts_str, "ddd", 4) == 0), "%s", "test_mopts2 str");
|
ok( (strncmp(mopts_str, "ddd", 4) == 0), "%s", "test_mopts2 str");
|
||||||
@@ -112,7 +119,7 @@ void test_mopts3()
|
|||||||
int rc;
|
int rc;
|
||||||
char **av= (char **)mopts3_argv;
|
char **av= (char **)mopts3_argv;
|
||||||
|
|
||||||
rc= handle_options(&mopts3_argc, &av, mopts_options, NULL);
|
rc= handle_options(&mopts3_argc, &av, mopts_options, &dummy_get_one_option);
|
||||||
ok( (rc == 0), "%s", "test_mopts3 call");
|
ok( (rc == 0), "%s", "test_mopts3 call");
|
||||||
ok( (mopts_num == 1000000L), "%s", "test_mopts3 num");
|
ok( (mopts_num == 1000000L), "%s", "test_mopts3 num");
|
||||||
ok( (strncmp(mopts_str, "ddd", 4) == 0), "%s", "test_mopts3 str");
|
ok( (strncmp(mopts_str, "ddd", 4) == 0), "%s", "test_mopts3 str");
|
||||||
@@ -126,7 +133,7 @@ void test_mopts4()
|
|||||||
int rc;
|
int rc;
|
||||||
char **av= (char **)mopts4_argv;
|
char **av= (char **)mopts4_argv;
|
||||||
|
|
||||||
rc= handle_options(&mopts4_argc, &av, mopts_options, NULL);
|
rc= handle_options(&mopts4_argc, &av, mopts_options, &dummy_get_one_option);
|
||||||
ok( (rc == 0), "%s", "test_mopts4 call");
|
ok( (rc == 0), "%s", "test_mopts4 call");
|
||||||
ok( (mopts_num == 1000000L), "%s", "test_mopts4 num");
|
ok( (mopts_num == 1000000L), "%s", "test_mopts4 num");
|
||||||
ok( (strncmp(mopts_str, "aa", 3) == 0), "%s", "test_mopts4 str");
|
ok( (strncmp(mopts_str, "aa", 3) == 0), "%s", "test_mopts4 str");
|
||||||
@@ -140,7 +147,7 @@ void test_mopts5()
|
|||||||
int rc;
|
int rc;
|
||||||
char **av= (char **)mopts5_argv;
|
char **av= (char **)mopts5_argv;
|
||||||
|
|
||||||
rc= handle_options(&mopts5_argc, &av, mopts_options, NULL);
|
rc= handle_options(&mopts5_argc, &av, mopts_options, &dummy_get_one_option);
|
||||||
ok( (rc == 0), "%s", "test_mopts5 call");
|
ok( (rc == 0), "%s", "test_mopts5 call");
|
||||||
ok( (mopts_num == 1000000L), "%s", "test_mopts5 num");
|
ok( (mopts_num == 1000000L), "%s", "test_mopts5 num");
|
||||||
ok( (strncmp(mopts_str, "ddd", 4) == 0), "%s", "test_mopts5 str");
|
ok( (strncmp(mopts_str, "ddd", 4) == 0), "%s", "test_mopts5 str");
|
||||||
@@ -154,7 +161,7 @@ void test_mopts6()
|
|||||||
int rc;
|
int rc;
|
||||||
char **av= (char **)mopts6_argv;
|
char **av= (char **)mopts6_argv;
|
||||||
|
|
||||||
rc= handle_options(&mopts6_argc, &av, mopts_options, NULL);
|
rc= handle_options(&mopts6_argc, &av, mopts_options, &dummy_get_one_option);
|
||||||
ok( (rc == 0), "%s", "test_mopts6 call");
|
ok( (rc == 0), "%s", "test_mopts6 call");
|
||||||
ok( (mopts_num == 1000000L), "%s", "test_mopts6 num");
|
ok( (mopts_num == 1000000L), "%s", "test_mopts6 num");
|
||||||
ok( (strncmp(mopts_str, "ddd", 4) == 0), "%s", "test_mopts6 str");
|
ok( (strncmp(mopts_str, "ddd", 4) == 0), "%s", "test_mopts6 str");
|
||||||
@@ -168,7 +175,7 @@ void test_mopts7()
|
|||||||
int rc;
|
int rc;
|
||||||
char **av= (char **)mopts7_argv;
|
char **av= (char **)mopts7_argv;
|
||||||
|
|
||||||
rc= handle_options(&mopts7_argc, &av, mopts_options, NULL);
|
rc= handle_options(&mopts7_argc, &av, mopts_options, &dummy_get_one_option);
|
||||||
ok( (rc == 0), "%s", "test_mopts7 call");
|
ok( (rc == 0), "%s", "test_mopts7 call");
|
||||||
ok( (mopts_num == 1000000L), "%s", "test_mopts7 num");
|
ok( (mopts_num == 1000000L), "%s", "test_mopts7 num");
|
||||||
ok( (strncmp(mopts_str, "ddd", 4) == 0), "%s", "test_mopts7 str");
|
ok( (strncmp(mopts_str, "ddd", 4) == 0), "%s", "test_mopts7 str");
|
||||||
@@ -182,7 +189,7 @@ void test_mopts8()
|
|||||||
int rc;
|
int rc;
|
||||||
char **av= (char **)mopts8_argv;
|
char **av= (char **)mopts8_argv;
|
||||||
|
|
||||||
rc= handle_options(&mopts8_argc, &av, mopts_options, NULL);
|
rc= handle_options(&mopts8_argc, &av, mopts_options, &dummy_get_one_option);
|
||||||
ok( (rc == 0), "%s", "test_mopts8 call");
|
ok( (rc == 0), "%s", "test_mopts8 call");
|
||||||
ok( (mopts_num == 1000000L), "%s", "test_mopts7 num");
|
ok( (mopts_num == 1000000L), "%s", "test_mopts7 num");
|
||||||
ok( (strncmp(mopts_str, "ddd", 4) == 0), "%s", "test_mopts7 str");
|
ok( (strncmp(mopts_str, "ddd", 4) == 0), "%s", "test_mopts7 str");
|
||||||
@@ -196,7 +203,7 @@ void test_mopts9()
|
|||||||
int rc;
|
int rc;
|
||||||
char **av= (char **)mopts9_argv;
|
char **av= (char **)mopts9_argv;
|
||||||
|
|
||||||
rc= handle_options(&mopts9_argc, &av, mopts_options, NULL);
|
rc= handle_options(&mopts9_argc, &av, mopts_options, &dummy_get_one_option);
|
||||||
ok( (rc != 0), "%s", "test_mopts9 call");
|
ok( (rc != 0), "%s", "test_mopts9 call");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,7 +214,7 @@ void test_mopts10()
|
|||||||
int rc;
|
int rc;
|
||||||
char **av= (char **)mopts10_argv;
|
char **av= (char **)mopts10_argv;
|
||||||
|
|
||||||
rc= handle_options(&mopts10_argc, &av, mopts_options, NULL);
|
rc= handle_options(&mopts10_argc, &av, mopts_options, &dummy_get_one_option);
|
||||||
ok( (rc != 0), "%s", "test_mopts10 call");
|
ok( (rc != 0), "%s", "test_mopts10 call");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,17 +245,6 @@ my_bool auto_get_one_option(int optid __attribute__((unused)),
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int auto1_argc= 3;
|
|
||||||
const char *auto1_argv[]= {"auto1", "--anum=123", "--autoset-anum"};
|
|
||||||
void test_auto1()
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
char **av= (char **)auto1_argv;
|
|
||||||
|
|
||||||
rc= handle_options(&auto1_argc, &av, auto_options, NULL);
|
|
||||||
ok( (rc == EXIT_ARGUMENT_INVALID), "%s", "test_auto1 call");
|
|
||||||
}
|
|
||||||
|
|
||||||
int auto2_argc= 3;
|
int auto2_argc= 3;
|
||||||
const char *auto2_argv[]= {"auto2", "--num=123", "--autoset-num"};
|
const char *auto2_argv[]= {"auto2", "--num=123", "--autoset-num"};
|
||||||
void test_auto2()
|
void test_auto2()
|
||||||
@@ -330,7 +326,7 @@ void test_max1()
|
|||||||
int rc;
|
int rc;
|
||||||
char **av= (char **)max1_argv;
|
char **av= (char **)max1_argv;
|
||||||
|
|
||||||
rc= handle_options(&max1_argc, &av, max_options, NULL);
|
rc= handle_options(&max1_argc, &av, max_options, &dummy_get_one_option);
|
||||||
ok( (rc == 0), "%s", "test_max1 call");
|
ok( (rc == 0), "%s", "test_max1 call");
|
||||||
ok( (mopts_num == 200), "%s", "test_max1 num");
|
ok( (mopts_num == 200), "%s", "test_max1 num");
|
||||||
ok( (max_num == 1000001L), "%s", "test_max1 max_num");
|
ok( (max_num == 1000001L), "%s", "test_max1 max_num");
|
||||||
@@ -342,7 +338,7 @@ void test_max2()
|
|||||||
int rc;
|
int rc;
|
||||||
char **av= (char **)max2_argv;
|
char **av= (char **)max2_argv;
|
||||||
|
|
||||||
rc= handle_options(&max2_argc, &av, max_options, NULL);
|
rc= handle_options(&max2_argc, &av, max_options, &dummy_get_one_option);
|
||||||
ok( (rc == 0), "%s", "test_max2 call");
|
ok( (rc == 0), "%s", "test_max2 call");
|
||||||
ok( (mopts_num == 200), "%s", "test_max2 num");
|
ok( (mopts_num == 200), "%s", "test_max2 num");
|
||||||
ok( (max_num == 100), "%s", "test_max2 max_num");
|
ok( (max_num == 100), "%s", "test_max2 max_num");
|
||||||
@@ -351,7 +347,7 @@ void test_max2()
|
|||||||
int main(int argc __attribute__((unused)), char **argv)
|
int main(int argc __attribute__((unused)), char **argv)
|
||||||
{
|
{
|
||||||
MY_INIT(argv[0]);
|
MY_INIT(argv[0]);
|
||||||
plan(4*8 + 1*4 + 3*4 + 3*2 + 3);
|
plan(4*8 + 1*4 + 3*4 + 3*2 + 2);
|
||||||
|
|
||||||
/* gcc 4.1.2 doesn't want it in the initializer, we have to do it run-time */
|
/* gcc 4.1.2 doesn't want it in the initializer, we have to do it run-time */
|
||||||
mopts_options[0].def_value= (intptr)"ddd";
|
mopts_options[0].def_value= (intptr)"ddd";
|
||||||
@@ -367,7 +363,6 @@ int main(int argc __attribute__((unused)), char **argv)
|
|||||||
|
|
||||||
test_mopts9();
|
test_mopts9();
|
||||||
test_mopts10();
|
test_mopts10();
|
||||||
test_auto1();
|
|
||||||
test_auto2();
|
test_auto2();
|
||||||
|
|
||||||
test_auto3();
|
test_auto3();
|
||||||
|
Reference in New Issue
Block a user