Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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.org


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent f45d20ff
Loading
Loading
Loading
Loading
+48 −11
Original line number Diff line number Diff line
@@ -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)
+2 −0
Original line number Diff line number Diff line
@@ -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;
};