From 369a2478973a416a2c42a37a8cf7031872a6d926 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 24 Oct 2016 12:00:02 +0900 Subject: 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 Acked-by: Jiri Olsa Cc: Andi Kleen Cc: David Ahern Cc: Josh Poimboeuf Cc: Peter Zijlstra Cc: Wang Nan Link: http://lkml.kernel.org/r/20161024030003.28534-1-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/subcmd/parse-options.c | 14 ++++++++++++++ tools/lib/subcmd/parse-options.h | 2 ++ 2 files changed, 16 insertions(+) (limited to 'tools/lib') 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) } -- cgit v1.2.3