Commit 42bd71d0 authored by Namhyung Kim's avatar Namhyung Kim Committed by Arnaldo Carvalho de Melo

perf tools: Add support for exclusive option

Some options cannot be used at the same time.  To handle such options
add a new PARSE_OPT_EXCLUSIVE flag and show error message if more than
one of them is used.
Signed-off-by: default avatarNamhyung Kim <namhyung@kernel.org>
Reviewed-by: default avatarMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Acked-by: default avatarHemant Kumar <hemant@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Hemant Kumar <hemant@linux.vnet.ibm.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1413990949-13953-5-git-send-email-namhyung@kernel.orgSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent f45d20ff
......@@ -45,6 +45,23 @@ static int get_value(struct parse_opt_ctx_t *p,
if (opt->flags & PARSE_OPT_DISABLED)
return opterror(opt, "is not usable", flags);
if (opt->flags & PARSE_OPT_EXCLUSIVE) {
if (p->excl_opt) {
char msg[128];
if (((flags & OPT_SHORT) && p->excl_opt->short_name) ||
p->excl_opt->long_name == NULL) {
scnprintf(msg, sizeof(msg), "cannot be used with switch `%c'",
p->excl_opt->short_name);
} else {
scnprintf(msg, sizeof(msg), "cannot be used with %s",
p->excl_opt->long_name);
}
opterror(opt, msg, flags);
return -3;
}
p->excl_opt = opt;
}
if (!(flags & OPT_SHORT) && p->opt) {
switch (opt->type) {
case OPTION_CALLBACK:
......@@ -345,13 +362,14 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
const char * const usagestr[])
{
int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP);
int excl_short_opt = 1;
const char *arg;
/* we must reset ->opt, unknown short option leave it dangling */
ctx->opt = NULL;
for (; ctx->argc; ctx->argc--, ctx->argv++) {
const char *arg = ctx->argv[0];
arg = ctx->argv[0];
if (*arg != '-' || !arg[1]) {
if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION)
break;
......@@ -360,19 +378,21 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
}
if (arg[1] != '-') {
ctx->opt = arg + 1;
ctx->opt = ++arg;
if (internal_help && *ctx->opt == 'h')
return usage_with_options_internal(usagestr, options, 0);
switch (parse_short_opt(ctx, options)) {
case -1:
return parse_options_usage(usagestr, options, arg + 1, 1);
return parse_options_usage(usagestr, options, arg, 1);
case -2:
goto unknown;
case -3:
goto exclusive;
default:
break;
}
if (ctx->opt)
check_typos(arg + 1, options);
check_typos(arg, options);
while (ctx->opt) {
if (internal_help && *ctx->opt == 'h')
return usage_with_options_internal(usagestr, options, 0);
......@@ -389,6 +409,8 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
ctx->argv[0] = strdup(ctx->opt - 1);
*(char *)ctx->argv[0] = '-';
goto unknown;
case -3:
goto exclusive;
default:
break;
}
......@@ -404,19 +426,23 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
break;
}
if (internal_help && !strcmp(arg + 2, "help-all"))
arg += 2;
if (internal_help && !strcmp(arg, "help-all"))
return usage_with_options_internal(usagestr, options, 1);
if (internal_help && !strcmp(arg + 2, "help"))
if (internal_help && !strcmp(arg, "help"))
return usage_with_options_internal(usagestr, options, 0);
if (!strcmp(arg + 2, "list-opts"))
if (!strcmp(arg, "list-opts"))
return PARSE_OPT_LIST_OPTS;
if (!strcmp(arg + 2, "list-cmds"))
if (!strcmp(arg, "list-cmds"))
return PARSE_OPT_LIST_SUBCMDS;
switch (parse_long_opt(ctx, arg + 2, options)) {
switch (parse_long_opt(ctx, arg, options)) {
case -1:
return parse_options_usage(usagestr, options, arg + 2, 0);
return parse_options_usage(usagestr, options, arg, 0);
case -2:
goto unknown;
case -3:
excl_short_opt = 0;
goto exclusive;
default:
break;
}
......@@ -428,6 +454,17 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
ctx->opt = NULL;
}
return PARSE_OPT_DONE;
exclusive:
parse_options_usage(usagestr, options, arg, excl_short_opt);
if ((excl_short_opt && ctx->excl_opt->short_name) ||
ctx->excl_opt->long_name == NULL) {
char opt = ctx->excl_opt->short_name;
parse_options_usage(NULL, options, &opt, 1);
} else {
parse_options_usage(NULL, options, ctx->excl_opt->long_name, 0);
}
return PARSE_OPT_HELP;
}
int parse_options_end(struct parse_opt_ctx_t *ctx)
......
......@@ -39,6 +39,7 @@ enum parse_opt_option_flags {
PARSE_OPT_HIDDEN = 8,
PARSE_OPT_LASTARG_DEFAULT = 16,
PARSE_OPT_DISABLED = 32,
PARSE_OPT_EXCLUSIVE = 64,
};
struct option;
......@@ -174,6 +175,7 @@ struct parse_opt_ctx_t {
const char **out;
int argc, cpidx;
const char *opt;
const struct option *excl_opt;
int flags;
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment