diff options
author | Namhyung Kim <namhyung@kernel.org> | 2016-10-24 06:00:02 +0300 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2016-10-25 16:12:16 +0300 |
commit | 369a2478973a416a2c42a37a8cf7031872a6d926 (patch) | |
tree | 2f59cd5560b246452d6702e8caefc162c4235a69 | |
parent | 8a06b0be6507f97f3aa92ca814335b8b65fd3de2 (diff) | |
download | linux-369a2478973a416a2c42a37a8cf7031872a6d926.tar.xz |
tools lib subcmd: Suppport cascading options
Sometimes subcommand have common options and it can only handled in the
upper level command unless it duplicates the options.
This patch adds a parent field and fallback to the parent if the given
argument was not found in the current options.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/20161024030003.28534-1-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/lib/subcmd/parse-options.c | 14 | ||||
-rw-r--r-- | tools/lib/subcmd/parse-options.h | 2 |
2 files changed, 16 insertions, 0 deletions
diff --git a/tools/lib/subcmd/parse-options.c b/tools/lib/subcmd/parse-options.c index 981bb4481fd5..3284bb14ae78 100644 --- a/tools/lib/subcmd/parse-options.c +++ b/tools/lib/subcmd/parse-options.c @@ -314,12 +314,19 @@ static int get_value(struct parse_opt_ctx_t *p, static int parse_short_opt(struct parse_opt_ctx_t *p, const struct option *options) { +retry: for (; options->type != OPTION_END; options++) { if (options->short_name == *p->opt) { p->opt = p->opt[1] ? p->opt + 1 : NULL; return get_value(p, options, OPT_SHORT); } } + + if (options->parent) { + options = options->parent; + goto retry; + } + return -2; } @@ -333,6 +340,7 @@ static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg, if (!arg_end) arg_end = arg + strlen(arg); +retry: for (; options->type != OPTION_END; options++) { const char *rest; int flags = 0; @@ -426,6 +434,12 @@ match: } if (abbrev_option) return get_value(p, abbrev_option, abbrev_flags); + + if (options->parent) { + options = options->parent; + goto retry; + } + return -2; } diff --git a/tools/lib/subcmd/parse-options.h b/tools/lib/subcmd/parse-options.h index d60cab2726da..8866ac438b34 100644 --- a/tools/lib/subcmd/parse-options.h +++ b/tools/lib/subcmd/parse-options.h @@ -109,11 +109,13 @@ struct option { intptr_t defval; bool *set; void *data; + const struct option *parent; }; #define check_vtype(v, type) ( BUILD_BUG_ON_ZERO(!__builtin_types_compatible_p(typeof(v), type)) + v ) #define OPT_END() { .type = OPTION_END } +#define OPT_PARENT(p) { .type = OPTION_END, .parent = (p) } #define OPT_ARGUMENT(l, h) { .type = OPTION_ARGUMENT, .long_name = (l), .help = (h) } #define OPT_GROUP(h) { .type = OPTION_GROUP, .help = (h) } #define OPT_BIT(s, l, v, h, b) { .type = OPTION_BIT, .short_name = (s), .long_name = (l), .value = check_vtype(v, int *), .help = (h), .defval = (b) } |