Skip to content

Commit

Permalink
parse-options: convert "command mode" to a flag
Browse files Browse the repository at this point in the history
OPTION_CMDMODE is essentially OPTION_SET_INT plus an extra check that
the variable had not set before.  In order to allow custom processing
of the option, for example a "command mode" option that also has an
argument, it would be nice to use OPTION_CALLBACK and not have to rewrite
the extra check on incompatible options.  In other words, making the
processing of the option orthogonal to the "only one of these" behavior
provided by OPTION_CMDMODE.

Add a new flag that takes care of the check, and modify OPT_CMDMODE to
use it together with OPTION_SET_INT.  The new flag still requires that the
option value points to an int, but any OPTION_* value can be specified as
long as it does not require a non-int type for opt->value.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
bonzini authored and gitster committed Feb 20, 2020
1 parent 62e7a6f commit bc8620b
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 15 deletions.
20 changes: 9 additions & 11 deletions parse-options.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ static enum parse_opt_result opt_command_mode_error(
*/
for (that = all_opts; that->type != OPTION_END; that++) {
if (that == opt ||
that->type != OPTION_CMDMODE ||
!(that->flags & PARSE_OPT_CMDMODE) ||
that->value != opt->value ||
that->defval != *(int *)opt->value)
continue;
Expand Down Expand Up @@ -95,6 +95,14 @@ static enum parse_opt_result get_value(struct parse_opt_ctx_t *p,
if (!(flags & OPT_SHORT) && p->opt && (opt->flags & PARSE_OPT_NOARG))
return error(_("%s takes no value"), optname(opt, flags));

/*
* Giving the same mode option twice, although unnecessary,
* is not a grave error, so let it pass.
*/
if ((opt->flags & PARSE_OPT_CMDMODE) &&
*(int *)opt->value && *(int *)opt->value != opt->defval)
return opt_command_mode_error(opt, all_opts, flags);

switch (opt->type) {
case OPTION_LOWLEVEL_CALLBACK:
return opt->ll_callback(p, opt, NULL, unset);
Expand Down Expand Up @@ -130,16 +138,6 @@ static enum parse_opt_result get_value(struct parse_opt_ctx_t *p,
*(int *)opt->value = unset ? 0 : opt->defval;
return 0;

case OPTION_CMDMODE:
/*
* Giving the same mode option twice, although is unnecessary,
* is not a grave error, so let it pass.
*/
if (*(int *)opt->value && *(int *)opt->value != opt->defval)
return opt_command_mode_error(opt, all_opts, flags);
*(int *)opt->value = opt->defval;
return 0;

case OPTION_STRING:
if (unset)
*(const char **)opt->value = NULL;
Expand Down
8 changes: 4 additions & 4 deletions parse-options.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ enum parse_opt_type {
OPTION_BITOP,
OPTION_COUNTUP,
OPTION_SET_INT,
OPTION_CMDMODE,
/* options with arguments (usually) */
OPTION_STRING,
OPTION_INTEGER,
Expand Down Expand Up @@ -47,7 +46,8 @@ enum parse_opt_option_flags {
PARSE_OPT_LITERAL_ARGHELP = 64,
PARSE_OPT_SHELL_EVAL = 256,
PARSE_OPT_NOCOMPLETE = 512,
PARSE_OPT_COMP_ARG = 1024
PARSE_OPT_COMP_ARG = 1024,
PARSE_OPT_CMDMODE = 2048
};

enum parse_opt_result {
Expand Down Expand Up @@ -168,8 +168,8 @@ struct option {
#define OPT_BOOL(s, l, v, h) OPT_BOOL_F(s, l, v, h, 0)
#define OPT_HIDDEN_BOOL(s, l, v, h) { OPTION_SET_INT, (s), (l), (v), NULL, \
(h), PARSE_OPT_NOARG | PARSE_OPT_HIDDEN, NULL, 1}
#define OPT_CMDMODE(s, l, v, h, i) { OPTION_CMDMODE, (s), (l), (v), NULL, \
(h), PARSE_OPT_NOARG|PARSE_OPT_NONEG, NULL, (i) }
#define OPT_CMDMODE(s, l, v, h, i) { OPTION_SET_INT, (s), (l), (v), NULL, \
(h), PARSE_OPT_CMDMODE|PARSE_OPT_NOARG|PARSE_OPT_NONEG, NULL, (i) }
#define OPT_INTEGER(s, l, v, h) OPT_INTEGER_F(s, l, v, h, 0)
#define OPT_MAGNITUDE(s, l, v, h) { OPTION_MAGNITUDE, (s), (l), (v), \
N_("n"), (h), PARSE_OPT_NONEG }
Expand Down

0 comments on commit bc8620b

Please sign in to comment.