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

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

perf stat: Enhance option parse error message



Print related option help messages only when it failed to process
options.  While at it, modify parse_options_usage() to skip usage part
so that it can be used for showing multiple option help messages
naturally like below:

  $ perf stat -Bx, ls
  -B option not supported with -x

   usage: perf stat [<options>] [<command>]

      -B, --big-num         print large numbers with thousands' separators
      -x, --field-separator <separator>
                            print counts with custom separator

Signed-off-by: default avatarNamhyung Kim <namhyung@kernel.org>
Acked-by: default avatarIngo Molnar <mingo@kernel.org>
Reviewed-by: default avatarIngo Molnar <mingo@kernel.org>
Enthusiastically-Supported-by: default avatarIngo Molnar <mingo@kernel.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1383291195-24386-6-git-send-email-namhyung@kernel.org


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent d37a92dc
Loading
Loading
Loading
Loading
+27 −15
Original line number Original line Diff line number Diff line
@@ -1596,7 +1596,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
		"perf stat [<options>] [<command>]",
		"perf stat [<options>] [<command>]",
		NULL
		NULL
	};
	};
	int status = -ENOMEM, run_idx;
	int status = -EINVAL, run_idx;
	const char *mode;
	const char *mode;


	setlocale(LC_ALL, "");
	setlocale(LC_ALL, "");
@@ -1614,12 +1614,15 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)


	if (output_name && output_fd) {
	if (output_name && output_fd) {
		fprintf(stderr, "cannot use both --output and --log-fd\n");
		fprintf(stderr, "cannot use both --output and --log-fd\n");
		usage_with_options(stat_usage, options);
		parse_options_usage(stat_usage, options, "o", 1);
		parse_options_usage(NULL, options, "log-fd", 0);
		goto out;
	}
	}


	if (output_fd < 0) {
	if (output_fd < 0) {
		fprintf(stderr, "argument to --log-fd must be a > 0\n");
		fprintf(stderr, "argument to --log-fd must be a > 0\n");
		usage_with_options(stat_usage, options);
		parse_options_usage(stat_usage, options, "log-fd", 0);
		goto out;
	}
	}


	if (!output) {
	if (!output) {
@@ -1656,7 +1659,9 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
		/* User explicitly passed -B? */
		/* User explicitly passed -B? */
		if (big_num_opt == 1) {
		if (big_num_opt == 1) {
			fprintf(stderr, "-B option not supported with -x\n");
			fprintf(stderr, "-B option not supported with -x\n");
			usage_with_options(stat_usage, options);
			parse_options_usage(stat_usage, options, "B", 1);
			parse_options_usage(NULL, options, "x", 1);
			goto out;
		} else /* Nope, so disable big number formatting */
		} else /* Nope, so disable big number formatting */
			big_num = false;
			big_num = false;
	} else if (big_num_opt == 0) /* User passed --no-big-num */
	} else if (big_num_opt == 0) /* User passed --no-big-num */
@@ -1666,7 +1671,9 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
		usage_with_options(stat_usage, options);
		usage_with_options(stat_usage, options);


	if (run_count < 0) {
	if (run_count < 0) {
		usage_with_options(stat_usage, options);
		pr_err("Run count must be a positive number\n");
		parse_options_usage(stat_usage, options, "r", 1);
		goto out;
	} else if (run_count == 0) {
	} else if (run_count == 0) {
		forever = true;
		forever = true;
		run_count = 1;
		run_count = 1;
@@ -1678,8 +1685,10 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
		fprintf(stderr, "both cgroup and no-aggregation "
		fprintf(stderr, "both cgroup and no-aggregation "
			"modes only available in system-wide mode\n");
			"modes only available in system-wide mode\n");


		usage_with_options(stat_usage, options);
		parse_options_usage(stat_usage, options, "G", 1);
		return -1;
		parse_options_usage(NULL, options, "A", 1);
		parse_options_usage(NULL, options, "a", 1);
		goto out;
	}
	}


	if (add_default_attributes())
	if (add_default_attributes())
@@ -1688,25 +1697,28 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
	perf_target__validate(&target);
	perf_target__validate(&target);


	if (perf_evlist__create_maps(evsel_list, &target) < 0) {
	if (perf_evlist__create_maps(evsel_list, &target) < 0) {
		if (perf_target__has_task(&target))
		if (perf_target__has_task(&target)) {
			pr_err("Problems finding threads of monitor\n");
			pr_err("Problems finding threads of monitor\n");
		if (perf_target__has_cpu(&target))
			parse_options_usage(stat_usage, options, "p", 1);
			parse_options_usage(NULL, options, "t", 1);
		} else if (perf_target__has_cpu(&target)) {
			perror("failed to parse CPUs map");
			perror("failed to parse CPUs map");

			parse_options_usage(stat_usage, options, "C", 1);
		usage_with_options(stat_usage, options);
			parse_options_usage(NULL, options, "a", 1);
		return -1;
		}
		goto out;
	}
	}
	if (interval && interval < 100) {
	if (interval && interval < 100) {
		pr_err("print interval must be >= 100ms\n");
		pr_err("print interval must be >= 100ms\n");
		usage_with_options(stat_usage, options);
		parse_options_usage(stat_usage, options, "I", 1);
		return -1;
		goto out_free_maps;
	}
	}


	if (perf_evlist__alloc_stats(evsel_list, interval))
	if (perf_evlist__alloc_stats(evsel_list, interval))
		goto out_free_maps;
		goto out_free_maps;


	if (perf_stat_init_aggr_mode())
	if (perf_stat_init_aggr_mode())
		goto out;
		goto out_free_maps;


	/*
	/*
	 * We dont want to block the signals - that would cause
	 * We dont want to block the signals - that would cause
+2 −1
Original line number Original line Diff line number Diff line
@@ -569,7 +569,7 @@ int parse_options_usage(const char * const *usagestr,
			const char *optstr, bool short_opt)
			const char *optstr, bool short_opt)
{
{
	if (!usagestr)
	if (!usagestr)
		return PARSE_OPT_HELP;
		goto opt;


	fprintf(stderr, "\n usage: %s\n", *usagestr++);
	fprintf(stderr, "\n usage: %s\n", *usagestr++);
	while (*usagestr && **usagestr)
	while (*usagestr && **usagestr)
@@ -582,6 +582,7 @@ int parse_options_usage(const char * const *usagestr,
	}
	}
	fputc('\n', stderr);
	fputc('\n', stderr);


opt:
	for (  ; opts->type != OPTION_END; opts++) {
	for (  ; opts->type != OPTION_END; opts++) {
		if (short_opt) {
		if (short_opt) {
			if (opts->short_name == *optstr)
			if (opts->short_name == *optstr)