From: Ramkumar Ramachandra Date: Thu, 08 Dec 2011 12:07:07 GMT Subject: [PATCH 1/2] parse-options: introduce OPT_SUBCOMMAND Message-ID: <1323346028-9201-2-git-send-email-artagnon@gmail.com> In-Reply-To: <1323346028-9201-1-git-send-email-artagnon@gmail.com> Several git programs take long dash-less options on the command-line to indicate different modes of operation like: git stash show git bundle verify test.bundle git bisect start Currently, the parse-options framework forbids the use of opts->long_name and OPT_PARSE_NODASH, and the parsing has to be done by hand as a result. Lift this restriction, and create a new OPT_SUBCOMMAND; this is built on top of OPTION_BIT to allow for the detection of more than one subcommand. Signed-off-by: Ramkumar Ramachandra --- parse-options.c | 5 +++-- parse-options.h | 3 +++ t/t0040-parse-options.sh | 31 +++++++++++++++++++++++++++++++ test-parse-options.c | 4 ++++ 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/parse-options.c b/parse-options.c index f0098eb..079616a 100644 --- a/parse-options.c +++ b/parse-options.c @@ -278,6 +278,8 @@ static int parse_nodash_opt(struct parse_opt_ctx_t *p, const char *arg, continue; if (options->short_name == arg[0] && arg[1] == '\0') return get_value(p, options, OPT_SHORT); + if (options->long_name && !strcmp(options->long_name, arg)) + return get_value(p, options, OPT_SHORT); } return -2; } @@ -314,8 +316,7 @@ static void parse_options_check(const struct option *opts) if (opts->flags & PARSE_OPT_NODASH && ((opts->flags & PARSE_OPT_OPTARG) || !(opts->flags & PARSE_OPT_NOARG) || - !(opts->flags & PARSE_OPT_NONEG) || - opts->long_name)) + !(opts->flags & PARSE_OPT_NONEG))) err |= optbug(opts, "uses feature " "not supported for dashless options"); switch (opts->type) { diff --git a/parse-options.h b/parse-options.h index 2e811dc..9267d46 100644 --- a/parse-options.h +++ b/parse-options.h @@ -123,6 +123,9 @@ struct option { #define OPT_GROUP(h) { OPTION_GROUP, 0, NULL, NULL, NULL, (h) } #define OPT_BIT(s, l, v, h, b) { OPTION_BIT, (s), (l), (v), NULL, (h), \ PARSE_OPT_NOARG, NULL, (b) } +#define OPT_SUBCOMMAND(l, v, h, i) { OPTION_BIT, 0, (l), (v), NULL, (h), \ + PARSE_OPT_NONEG | PARSE_OPT_NOARG | \ + PARSE_OPT_NODASH | PARSE_OPT_HIDDEN, NULL, (i) } #define OPT_NEGBIT(s, l, v, h, b) { OPTION_NEGBIT, (s), (l), (v), NULL, \ (h), PARSE_OPT_NOARG, NULL, (b) } #define OPT_COUNTUP(s, l, v, h) { OPTION_COUNTUP, (s), (l), (v), NULL, \ diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh index a1e4616..47a402e 100755 --- a/t/t0040-parse-options.sh +++ b/t/t0040-parse-options.sh @@ -55,6 +55,7 @@ mv expect expect.err cat > expect << EOF boolean: 2 +subcommand: 0 integer: 1729 timestamp: 0 string: 123 @@ -74,6 +75,7 @@ test_expect_success 'short options' ' cat > expect << EOF boolean: 2 +subcommand: 0 integer: 1729 timestamp: 0 string: 321 @@ -103,6 +105,7 @@ test_expect_success 'missing required value' ' cat > expect << EOF boolean: 1 +subcommand: 0 integer: 13 timestamp: 0 string: 123 @@ -125,6 +128,7 @@ test_expect_success 'intermingled arguments' ' cat > expect << EOF boolean: 0 +subcommand: 0 integer: 2 timestamp: 0 string: (not set) @@ -154,6 +158,7 @@ test_expect_success 'ambiguously abbreviated option' ' cat > expect << EOF boolean: 0 +subcommand: 0 integer: 0 timestamp: 0 string: 123 @@ -182,6 +187,7 @@ test_expect_success 'detect possible typos' ' cat > expect < expect < expect < expect < expect < expect < output 2> output.err && + test ! -s output.err && + test_cmp expect output +' + +cat > expect <expect <