parse-options: make OPT_ARGUMENT() more useful
authorJohannes Schindelin <johannes.schindelin@gmx.de>
Thu, 14 Mar 2019 11:25:04 +0000 (04:25 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 18 Mar 2019 02:44:14 +0000 (11:44 +0900)
`OPT_ARGUMENT()` is intended to keep the specified long option in `argv`
and not to do anything else.

However, it would make a lot of sense for the caller to know whether
this option was seen at all or not. For example, we want to teach `git
difftool` to work outside of any Git worktree, but only when
`--no-index` was specified.

Note: nothing in Git uses OPT_ARGUMENT(). Even worse, looking through
the commit history, one can easily see that nothing even
ever used it, apart from the regression test.

So not only do we make `OPT_ARGUMENT()` more useful, we are also about
to introduce its first real user!

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/technical/api-parse-options.txt
parse-options.c
parse-options.h
t/helper/test-parse-options.c
index 2b036d7838ef906153a29cf0e17d57a1dbe93109..2e2e7c10c620d86af5adbb0f7e7987dbe5feb12c 100644 (file)
@@ -198,8 +198,10 @@ There are some macros to easily define options:
        The filename will be prefixed by passing the filename along with
        the prefix argument of `parse_options()` to `prefix_filename()`.
 
-`OPT_ARGUMENT(long, description)`::
+`OPT_ARGUMENT(long, &int_var, description)`::
        Introduce a long-option argument that will be kept in `argv[]`.
+       If this option was seen, `int_var` will be set to one (except
+       if a `NULL` pointer was passed).
 
 `OPT_NUMBER_CALLBACK(&var, description, func_ptr)`::
        Recognize numerical options like -123 and feed the integer as
index cec74522e56b084fbb0c8eeec47456d0bb2f7d3e..1d57802da0e5da70cf00c2cf55b9f3945f44fe53 100644 (file)
@@ -286,6 +286,8 @@ static enum parse_opt_result parse_long_opt(
                                             optname(options, flags));
                        if (*rest)
                                continue;
+                       if (options->value)
+                               *(int *)options->value = options->defval;
                        p->out[p->cpidx++] = arg - 2;
                        return PARSE_OPT_DONE;
                }
index 7d83e2971d9afa11b11d6187bd96afb88cbb6118..c3d45ba1ac1cefb6c2a7877d02e753a0c4c3ea4b 100644 (file)
@@ -138,8 +138,8 @@ struct option {
        { OPTION_CALLBACK, (s), (l), (v), (a), (h), (f), (cb) }
 
 #define OPT_END()                   { OPTION_END }
-#define OPT_ARGUMENT(l, h)          { OPTION_ARGUMENT, 0, (l), NULL, NULL, \
-                                     (h), PARSE_OPT_NOARG}
+#define OPT_ARGUMENT(l, v, h)       { OPTION_ARGUMENT, 0, (l), (v), NULL, \
+                                     (h), PARSE_OPT_NOARG, NULL, 1 }
 #define OPT_GROUP(h)                { OPTION_GROUP, 0, NULL, NULL, NULL, (h) }
 #define OPT_BIT(s, l, v, h, b)      OPT_BIT_F(s, l, v, h, b, 0)
 #define OPT_BITOP(s, l, v, h, set, clear) { OPTION_BITOP, (s), (l), (v), NULL, (h), \
index cc88fba05752cbf67c2669c219cc0a65d4a354ee..2232b2f79ecd7524b5763716fbca5a87bed06f5d 100644 (file)
@@ -132,7 +132,7 @@ int cmd__parse_options(int argc, const char **argv)
                OPT_NOOP_NOARG(0, "obsolete"),
                OPT_STRING_LIST(0, "list", &list, "str", "add str to list"),
                OPT_GROUP("Magic arguments"),
-               OPT_ARGUMENT("quux", "means --quux"),
+               OPT_ARGUMENT("quux", NULL, "means --quux"),
                OPT_NUMBER_CALLBACK(&integer, "set integer to NUM",
                        number_callback),
                { OPTION_COUNTUP, '+', NULL, &boolean, NULL, "same as -b",