parse-options: deprecate OPT_BOOLEAN

It is natural to expect that an option defined with OPT_BOOLEAN() could be used in this way: int option = -1; /* unspecified */ struct option options[] = { OPT_BOOLEAN(0, "option", &option, "set option"), OPT_END() }; parse_options(ac, av, prefix, options, usage, 0); if (option < 0) ... do the default thing ... else if (!option) ... --no-option was given ... else ... --option was given ... to easily tell three cases apart: - There is no mention of the `--option` on the command line; - The variable is positively set with `--option`; or - The variable is explicitly negated with `--no-option`. Unfortunately, this is not the case. OPT_BOOLEAN() increments the variable every time `--option` is given, and resets it to zero when `--no-option` is given. As a first step to remedy this, introduce a true boolean OPT_BOOL(), and rename OPT_BOOLEAN() to OPT_COUNTUP(). To help transitioning, OPT_BOOLEAN and OPTION_BOOLEAN are defined as deprecated synonyms to OPT_COUNTUP and OPTION_COUNTUP respectively. This is what db7244b (parse-options new features., 2007-11-07) from four years ago started by marking OPTION_BOOLEAN as "INCR would have been a better name". Some existing users do depend on the count-up semantics; for example, users of OPT__VERBOSE() could use it to raise the verbosity level with repeated use of `-v` on the command line, but they probably should be rewritten to use OPT__VERBOSITY() instead these days. I suspect that some users of OPT__FORCE() may also use it to implement different level of forcibleness but I didn't check. On top of this patch, here are the remaining clean-up tasks that other people can help: - Look at each hit in "git grep -e OPT_BOOLEAN"; trace all uses of the value that is set to the underlying variable, and if it can proven that the variable is only used as a boolean, replace it with OPT_BOOL(). If the caller does depend on the count-up semantics, replace it with OPT_COUNTUP() instead. - Same for OPTION_BOOLEAN; replace it with OPTION_SET_INT and arrange to set 1 to the variable for a true boolean, and otherwise replace it with OPTION_COUNTUP. - Look at each hit in "git grep -e OPT__VERBOSE -e OPT__QUIET" and see if they can be replaced with OPT__VERBOSITY(). I'll follow this message up with a separate patch as an example. Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Sep 27, 2011 at 16:56 UTC b04ba2bb42957f63567f530e092385f085b25e63
3 files changed +21 -9
Documentation/technical/api-parse-options.txt
+11 -5
@@ -135,9 +135,14 @@ There are some macros to easily define options:
135 describes the group or an empty string.
136 Start the description with an upper-case letter.
137
138 -`OPT_BOOLEAN(short, long, &int_var, description)`::
139 - Introduce a boolean option.
140 - `int_var` is incremented on each use.
138 +`OPT_BOOL(short, long, &int_var, description)`::
139 + Introduce a boolean option. `int_var` is set to one with
140 + `--option` and set to zero with `--no-option`.
141 +
142 +`OPT_COUNTUP(short, long, &int_var, description)`::
143 + Introduce a count-up option.
144 + `int_var` is incremented on each use of `--option`, and
145 + reset to zero with `--no-option`.
146
147 `OPT_BIT(short, long, &int_var, description, mask)`::
148 Introduce a boolean option.
@@ -148,8 +153,9 @@ There are some macros to easily define options:
153 If used, `int_var` is bitwise-anded with the inverted `mask`.
154
155 `OPT_SET_INT(short, long, &int_var, description, integer)`::
151 - Introduce a boolean option.
152 - If used, set `int_var` to `integer`.
156 + Introduce an integer option.
157 + `int_var` is set to `integer` with `--option`, and
158 + reset to zero with `--no-option`.
159
160 `OPT_SET_PTR(short, long, &ptr_var, description, ptr)`::
161 Introduce a boolean option.
parse-options.c
+2 -2
@@ -83,7 +83,7 @@ static int get_value(struct parse_opt_ctx_t *p,
83 *(int *)opt->value &= ~opt->defval;
84 return 0;
85
86 - case OPTION_BOOLEAN:
86 + case OPTION_COUNTUP:
87 *(int *)opt->value = unset ? 0 : *(int *)opt->value + 1;
88 return 0;
89
@@ -319,7 +319,7 @@ static void parse_options_check(const struct option *opts)
319 err |= optbug(opts, "uses feature "
320 "not supported for dashless options");
321 switch (opts->type) {
322 - case OPTION_BOOLEAN:
322 + case OPTION_COUNTUP:
323 case OPTION_BIT:
324 case OPTION_NEGBIT:
325 case OPTION_SET_INT:
parse-options.h
+8 -2
@@ -10,7 +10,7 @@ enum parse_opt_type {
10 /* options with no arguments */
11 OPTION_BIT,
12 OPTION_NEGBIT,
13 - OPTION_BOOLEAN, /* _INCR would have been a better name */
13 + OPTION_COUNTUP,
14 OPTION_SET_INT,
15 OPTION_SET_PTR,
16 /* options with arguments (usually) */
@@ -21,6 +21,9 @@ enum parse_opt_type {
21 OPTION_FILENAME
22 };
23
24 +/* Deprecated synonym */
25 +#define OPTION_BOOLEAN OPTION_COUNTUP
26 +
27 enum parse_opt_flags {
28 PARSE_OPT_KEEP_DASHDASH = 1,
29 PARSE_OPT_STOP_AT_NON_OPTION = 2,
@@ -122,10 +125,11 @@ struct option {
125 PARSE_OPT_NOARG, NULL, (b) }
126 #define OPT_NEGBIT(s, l, v, h, b) { OPTION_NEGBIT, (s), (l), (v), NULL, \
127 (h), PARSE_OPT_NOARG, NULL, (b) }
125 -#define OPT_BOOLEAN(s, l, v, h) { OPTION_BOOLEAN, (s), (l), (v), NULL, \
128 +#define OPT_COUNTUP(s, l, v, h) { OPTION_COUNTUP, (s), (l), (v), NULL, \
129 (h), PARSE_OPT_NOARG }
130 #define OPT_SET_INT(s, l, v, h, i) { OPTION_SET_INT, (s), (l), (v), NULL, \
131 (h), PARSE_OPT_NOARG, NULL, (i) }
132 +#define OPT_BOOL(s, l, v, h) OPT_SET_INT(s, l, v, h, 1)
133 #define OPT_SET_PTR(s, l, v, h, p) { OPTION_SET_PTR, (s), (l), (v), NULL, \
134 (h), PARSE_OPT_NOARG, NULL, (p) }
135 #define OPT_INTEGER(s, l, v, h) { OPTION_INTEGER, (s), (l), (v), "n", (h) }
@@ -149,6 +153,8 @@ struct option {
153 { OPTION_CALLBACK, (s), (l), (v), "when", (h), PARSE_OPT_OPTARG, \
154 parse_opt_color_flag_cb, (intptr_t)"always" }
155
156 +/* Deprecated synonym */
157 +#define OPT_BOOLEAN OPT_COUNTUP
158
159 /* parse_options() will filter out the processed options and leave the
160 * non-option arguments in argv[].