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

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.orgSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent d37a92dc
...@@ -1596,7 +1596,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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
......
...@@ -569,7 +569,7 @@ int parse_options_usage(const char * const *usagestr, ...@@ -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, ...@@ -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)
......
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