From: Rusty Russell Date: Tue, 5 Oct 2010 05:26:19 +0000 (+1030) Subject: opt: fix reporting of arguments when multiple arguments exist. X-Git-Url: http://git.ozlabs.org/?p=ccan;a=commitdiff_plain;h=b4cf10d83d46b50468ae52fccaeb99a793505467;ds=sidebyside opt: fix reporting of arguments when multiple arguments exist. longidx is not updated in this case. We should open-code option parsing. --- diff --git a/ccan/opt/opt.c b/ccan/opt/opt.c index 155d7aaf..ea27dfa7 100644 --- a/ccan/opt/opt.c +++ b/ccan/opt/opt.c @@ -280,7 +280,6 @@ bool opt_parse(int *argc, char *argv[], void (*errlog)(const char *fmt, ...)) != -1) { char *problem; const char *name; - bool missing = false; /* optopt is 0 if it's an unknown long option, *or* if * -? is a valid short option. */ @@ -291,8 +290,10 @@ bool opt_parse(int *argc, char *argv[], void (*errlog)(const char *fmt, ...)) break; } } else if (ret == ':') { - missing = true; - ret = optopt; + /* Missing argument: longidx not updated :( */ + parse_fail(errlog, optopt, argv[optind-1]+2, + "option requires an argument"); + break; } if (ret != 0) @@ -300,13 +301,6 @@ bool opt_parse(int *argc, char *argv[], void (*errlog)(const char *fmt, ...)) else e = find_long(longidx, &name); - /* Missing argument */ - if (missing) { - parse_fail(errlog, ret, name, - "option requires an argument"); - break; - } - if (e->flags == OPT_HASARG) problem = e->cb_arg(optarg, e->arg); else diff --git a/ccan/opt/test/run-correct-reporting.c b/ccan/opt/test/run-correct-reporting.c new file mode 100644 index 00000000..44f68ae2 --- /dev/null +++ b/ccan/opt/test/run-correct-reporting.c @@ -0,0 +1,45 @@ +/* Make sure when multiple equivalent options, correct one is used for errors */ + +#include +#include +#include +#include +#include "utils.h" + +int main(int argc, char *argv[]) +{ + plan_tests(12); + + /* --aaa without args. */ + opt_register_arg("-a/--aaa", test_arg, NULL, "aaa", NULL); + ok1(!parse_args(&argc, &argv, "--aaa", NULL)); + ok1(strstr(err_output, ": --aaa: option requires an argument")); + free(err_output); + err_output = NULL; + ok1(!parse_args(&argc, &argv, "-a", NULL)); + ok1(strstr(err_output, ": -a: option requires an argument")); + free(err_output); + err_output = NULL; + + /* Multiple */ + opt_register_arg("--bbb/-b/-c/--ccc", test_arg, NULL, "aaa", NULL); + ok1(!parse_args(&argc, &argv, "--bbb", NULL)); + ok1(strstr(err_output, ": --bbb: option requires an argument")); + free(err_output); + err_output = NULL; + ok1(!parse_args(&argc, &argv, "-b", NULL)); + ok1(strstr(err_output, ": -b: option requires an argument")); + free(err_output); + err_output = NULL; + ok1(!parse_args(&argc, &argv, "-c", NULL)); + ok1(strstr(err_output, ": -c: option requires an argument")); + free(err_output); + err_output = NULL; + ok1(!parse_args(&argc, &argv, "--ccc", NULL)); + ok1(strstr(err_output, ": --ccc: option requires an argument")); + free(err_output); + err_output = NULL; + + return exit_status(); +} +