cli: change api of parse_option

The idea is to allow it (in a future commit) advance to the next argv
element to get a value
This commit is contained in:
David Bremner 2017-07-01 12:18:44 -03:00
parent 15815d4e4c
commit de9baa29dc
3 changed files with 47 additions and 19 deletions

View file

@ -121,18 +121,24 @@ parse_position_arg (const char *arg_str, int pos_arg_index,
* parse a possible value, and assign to *output_var * parse a possible value, and assign to *output_var
*/ */
notmuch_bool_t int
parse_option (const char *_arg, const notmuch_opt_desc_t *options) parse_option (int argc, char **argv, const notmuch_opt_desc_t *options, int opt_index)
{ {
assert(argv);
const char *_arg = argv[opt_index];
assert(_arg); assert(_arg);
assert(options); assert(options);
const char *arg = _arg + 2; /* _arg starts with -- */ const char *arg = _arg + 2; /* _arg starts with -- */
const notmuch_opt_desc_t *try; const notmuch_opt_desc_t *try;
for (try = options; try->opt_type != NOTMUCH_OPT_END; try++) { for (try = options; try->opt_type != NOTMUCH_OPT_END; try++) {
if (try->opt_type == NOTMUCH_OPT_INHERIT && if (try->opt_type == NOTMUCH_OPT_INHERIT) {
parse_option (_arg, try->output_var)) int new_index = parse_option (argc, argv, try->output_var, opt_index);
return TRUE; if (new_index >= 0)
return new_index;
}
if (! try->name) if (! try->name)
continue; continue;
@ -155,24 +161,33 @@ parse_option (const char *_arg, const notmuch_opt_desc_t *options)
if (try->output_var == NULL) if (try->output_var == NULL)
INTERNAL_ERROR ("output pointer NULL for option %s", try->name); INTERNAL_ERROR ("output pointer NULL for option %s", try->name);
notmuch_bool_t opt_status = FALSE;
switch (try->opt_type) { switch (try->opt_type) {
case NOTMUCH_OPT_KEYWORD: case NOTMUCH_OPT_KEYWORD:
case NOTMUCH_OPT_KEYWORD_FLAGS: case NOTMUCH_OPT_KEYWORD_FLAGS:
return _process_keyword_arg (try, next, value); opt_status = _process_keyword_arg (try, next, value);
break;
case NOTMUCH_OPT_BOOLEAN: case NOTMUCH_OPT_BOOLEAN:
return _process_boolean_arg (try, next, value); opt_status = _process_boolean_arg (try, next, value);
break;
case NOTMUCH_OPT_INT: case NOTMUCH_OPT_INT:
return _process_int_arg (try, next, value); opt_status = _process_int_arg (try, next, value);
break;
case NOTMUCH_OPT_STRING: case NOTMUCH_OPT_STRING:
return _process_string_arg (try, next, value); opt_status = _process_string_arg (try, next, value);
break;
case NOTMUCH_OPT_POSITION: case NOTMUCH_OPT_POSITION:
case NOTMUCH_OPT_END: case NOTMUCH_OPT_END:
default: default:
INTERNAL_ERROR ("unknown or unhandled option type %d", try->opt_type); INTERNAL_ERROR ("unknown or unhandled option type %d", try->opt_type);
/*UNREACHED*/ /*UNREACHED*/
} }
if (opt_status)
return opt_index+1;
else
return -1;
} }
return FALSE; return -1;
} }
/* See command-line-arguments.h for description */ /* See command-line-arguments.h for description */
@ -194,18 +209,16 @@ parse_arguments (int argc, char **argv,
} }
} else { } else {
int prev_opt_index = opt_index;
if (strlen (argv[opt_index]) == 2) if (strlen (argv[opt_index]) == 2)
return opt_index+1; return opt_index+1;
more_args = parse_option (argv[opt_index], options); opt_index = parse_option (argc, argv, options, opt_index);
if (more_args) { if (opt_index < 0) {
opt_index++; fprintf (stderr, "Unrecognized option: %s\n", argv[prev_opt_index]);
} else { more_args = FALSE;
fprintf (stderr, "Unrecognized option: %s\n", argv[opt_index]);
opt_index = -1;
} }
} }
} }

View file

@ -70,8 +70,8 @@ parse_arguments (int argc, char **argv, const notmuch_opt_desc_t *options, int o
* functions. * functions.
*/ */
notmuch_bool_t int
parse_option (const char *arg, const notmuch_opt_desc_t* options); parse_option (int argc, char **argv, const notmuch_opt_desc_t* options, int opt_index);
notmuch_bool_t notmuch_bool_t
parse_position_arg (const char *arg, parse_position_arg (const char *arg,

15
test/T690-command-line-args.sh Executable file
View file

@ -0,0 +1,15 @@
#!/usr/bin/env bash
test_description="command line arguments"
. ./test-lib.sh || exit 1
NOTMUCH_NEW > /dev/null
test_begin_subtest 'bad option to show'
notmuch show --frobnicate >& OUTPUT
cat <<EOF > EXPECTED
Unrecognized option: --frobnicate
EOF
test_expect_equal_file EXPECTED OUTPUT
test_done