This is meant to be used to keep --not and --all during revision parsing. Signed-off-by: Pierre Habouzit <madcoder@xxxxxxxxxx> --- parse-options.c | 26 +++++++++++++++++++------- parse-options.h | 2 ++ t/t0040-parse-options.sh | 16 ++++++++++++++++ test-parse-options.c | 2 ++ 4 files changed, 39 insertions(+), 7 deletions(-) diff --git a/parse-options.c b/parse-options.c index be35785..8e64316 100644 --- a/parse-options.c +++ b/parse-options.c @@ -6,7 +6,8 @@ struct optparse_t { const char **argv; - int argc; + const char **out; + int argc, cpidx; const char *opt; }; @@ -159,6 +160,16 @@ static int parse_long_opt(struct optparse_t *p, const char *arg, continue; rest = skip_prefix(arg, options->long_name); + if (options->type == OPTION_ARGUMENT) { + if (!rest) + continue; + if (*rest == '=') + return opterror(options, "takes no value", flags); + if (*rest) + continue; + p->out[p->cpidx++] = arg - 2; + return 0; + } if (!rest) { /* abbreviated? */ if (!strncmp(options->long_name, arg, arg_end - arg)) { @@ -242,8 +253,7 @@ static NORETURN void usage_with_options_internal(const char * const *, int parse_options(int argc, const char **argv, const struct option *options, const char * const usagestr[], int flags) { - struct optparse_t args = { argv + 1, argc - 1, NULL }; - int j = 0; + struct optparse_t args = { argv + 1, argv, argc - 1, 0, NULL }; for (; args.argc; args.argc--, args.argv++) { const char *arg = args.argv[0]; @@ -251,7 +261,7 @@ int parse_options(int argc, const char **argv, const struct option *options, if (*arg != '-' || !arg[1]) { if (flags & PARSE_OPT_STOP_AT_NON_OPTION) break; - argv[j++] = args.argv[0]; + args.out[args.cpidx++] = args.argv[0]; continue; } @@ -288,9 +298,9 @@ int parse_options(int argc, const char **argv, const struct option *options, usage_with_options(usagestr, options); } - memmove(argv + j, args.argv, args.argc * sizeof(*argv)); - argv[j + args.argc] = NULL; - return j + args.argc; + memmove(args.out + args.cpidx, args.argv, args.argc * sizeof(*args.out)); + args.out[args.cpidx + args.argc] = NULL; + return args.cpidx + args.argc; } #define USAGE_OPTS_WIDTH 24 @@ -330,6 +340,8 @@ void usage_with_options_internal(const char * const *usagestr, pos += fprintf(stderr, "--%s", opts->long_name); switch (opts->type) { + case OPTION_ARGUMENT: + break; case OPTION_INTEGER: if (opts->flags & PARSE_OPT_OPTARG) pos += fprintf(stderr, " [<n>]"); diff --git a/parse-options.h b/parse-options.h index 0d40cd2..1af62b0 100644 --- a/parse-options.h +++ b/parse-options.h @@ -4,6 +4,7 @@ enum parse_opt_type { /* special types */ OPTION_END, + OPTION_ARGUMENT, OPTION_GROUP, /* options with no arguments */ OPTION_BIT, @@ -85,6 +86,7 @@ struct option { }; #define OPT_END() { OPTION_END } +#define OPT_ARGUMENT(l, h) { OPTION_ARGUMENT, 0, (l), NULL, NULL, (h) } #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), 0, NULL, (b) } #define OPT_BOOLEAN(s, l, v, h) { OPTION_BOOLEAN, (s), (l), (v), NULL, (h) } diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh index 0e2933a..c23f0ac 100755 --- a/t/t0040-parse-options.sh +++ b/t/t0040-parse-options.sh @@ -21,6 +21,9 @@ string options --st <st> get another string (pervert ordering) -o <str> get another string +magic arguments + --quux means --quux + EOF test_expect_success 'test help' ' @@ -114,4 +117,17 @@ test_expect_success 'detect possible typos' ' git diff expect.err output.err ' +cat > expect <<EOF +boolean: 0 +integer: 0 +string: (not set) +arg 00: --quux +EOF + +test_expect_success 'keep some options as arguments' ' + test-parse-options --quux > output 2> output.err && + test ! -s output.err && + git diff expect output +' + test_done diff --git a/test-parse-options.c b/test-parse-options.c index eed8a02..73360d7 100644 --- a/test-parse-options.c +++ b/test-parse-options.c @@ -20,6 +20,8 @@ int main(int argc, const char **argv) OPT_STRING(0, "string2", &string, "str", "get another string"), OPT_STRING(0, "st", &string, "st", "get another string (pervert ordering)"), OPT_STRING('o', NULL, &string, "str", "get another string"), + OPT_GROUP("magic arguments"), + OPT_ARGUMENT("quux", "means --quux"), OPT_END(), }; int i; -- 1.5.4.3.471.ga96e8.dirty -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html