summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Paolo Bonzini <pbonzini@redhat.com>2020-02-20 15:15:16 +0100
committerLibravatar Junio C Hamano <gitster@pobox.com>2020-02-20 13:20:40 -0800
commitbc8620b44094e9fb6fc20d141678f9b845c19193 (patch)
treea2120bed53eaf4ae3028c1dab988b3428fb5661e
parentparse-options: add testcases for OPT_CMDMODE() (diff)
downloadtgif-bc8620b44094e9fb6fc20d141678f9b845c19193.tar.xz
parse-options: convert "command mode" to a flag
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>
-rw-r--r--parse-options.c20
-rw-r--r--parse-options.h8
2 files changed, 13 insertions, 15 deletions
diff --git a/parse-options.c b/parse-options.c
index 60fae3ad21..c51be1860f 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -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;
@@ -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);
@@ -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;
diff --git a/parse-options.h b/parse-options.h
index fdc0c1cb97..05bf8245de 100644
--- a/parse-options.h
+++ b/parse-options.h
@@ -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,
@@ -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 {
@@ -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 }