Commit 3ea51b51 authored by Sergei Golubchik's avatar Sergei Golubchik

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.
parent eb3431d5
...@@ -110,7 +110,8 @@ extern my_error_reporter my_getopt_error_reporter; ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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[]= ...@@ -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, ...) ...@@ -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() ...@@ -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() ...@@ -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() ...@@ -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() ...@@ -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() ...@@ -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() ...@@ -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() ...@@ -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() ...@@ -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() ...@@ -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() ...@@ -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)), ...@@ -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() ...@@ -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() ...@@ -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() ...@@ -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) ...@@ -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();
......
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