Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf tools: Introduce usage_with_options_msg()

Now usage_with_options() setup a pager before printing message so normal
printf() or pr_err() will not be shown. The usage_with_options_msg()
can be used to print some help message before usage strings.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1445701767-12731-4-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Namhyung Kim and committed by
Arnaldo Carvalho de Melo
c7118369 01b19455

+62 -28
+2 -2
tools/perf/builtin-evlist.c
··· 61 61 usage_with_options(evlist_usage, options); 62 62 63 63 if (details.event_group && (details.verbose || details.freq)) { 64 - pr_err("--group option is not compatible with other options\n"); 65 - usage_with_options(evlist_usage, options); 64 + usage_with_options_msg(evlist_usage, options, 65 + "--group option is not compatible with other options\n"); 66 66 } 67 67 68 68 return __cmd_evlist(input_name, &details);
+12 -8
tools/perf/builtin-probe.c
··· 528 528 PARSE_OPT_STOP_AT_NON_OPTION); 529 529 if (argc > 0) { 530 530 if (strcmp(argv[0], "-") == 0) { 531 - pr_warning(" Error: '-' is not supported.\n"); 532 - usage_with_options(probe_usage, options); 531 + usage_with_options_msg(probe_usage, options, 532 + "'-' is not supported.\n"); 533 533 } 534 534 if (params.command && params.command != 'a') { 535 - pr_warning(" Error: another command except --add is set.\n"); 536 - usage_with_options(probe_usage, options); 535 + usage_with_options_msg(probe_usage, options, 536 + "another command except --add is set.\n"); 537 537 } 538 538 ret = parse_probe_event_argv(argc, argv); 539 539 if (ret < 0) { ··· 562 562 switch (params.command) { 563 563 case 'l': 564 564 if (params.uprobes) { 565 - pr_warning(" Error: Don't use --list with --exec.\n"); 566 - usage_with_options(probe_usage, options); 565 + pr_err(" Error: Don't use --list with --exec.\n"); 566 + parse_options_usage(probe_usage, options, "l", true); 567 + parse_options_usage(NULL, options, "x", true); 568 + return -EINVAL; 567 569 } 568 570 ret = show_perf_probe_events(params.filter); 569 571 if (ret < 0) ··· 605 603 case 'a': 606 604 /* Ensure the last given target is used */ 607 605 if (params.target && !params.target_used) { 608 - pr_warning(" Error: -x/-m must follow the probe definitions.\n"); 609 - usage_with_options(probe_usage, options); 606 + pr_err(" Error: -x/-m must follow the probe definitions.\n"); 607 + parse_options_usage(probe_usage, options, "m", true); 608 + parse_options_usage(NULL, options, "x", true); 609 + return -EINVAL; 610 610 } 611 611 612 612 ret = perf_add_probe_events(params.events, params.nevents);
+6 -5
tools/perf/builtin-record.c
··· 1135 1135 usage_with_options(record_usage, record_options); 1136 1136 1137 1137 if (nr_cgroups && !rec->opts.target.system_wide) { 1138 - ui__error("cgroup monitoring only available in" 1139 - " system-wide mode\n"); 1140 - usage_with_options(record_usage, record_options); 1138 + usage_with_options_msg(record_usage, record_options, 1139 + "cgroup monitoring only available in system-wide mode"); 1140 + 1141 1141 } 1142 1142 if (rec->opts.record_switch_events && 1143 1143 !perf_can_record_switch_events()) { 1144 - ui__error("kernel does not support recording context switch events (--switch-events option)\n"); 1145 - usage_with_options(record_usage, record_options); 1144 + ui__error("kernel does not support recording context switch events\n"); 1145 + parse_options_usage(record_usage, record_options, "switch-events", 0); 1146 + return -EINVAL; 1146 1147 } 1147 1148 1148 1149 if (!rec->itr) {
+2 -2
tools/perf/builtin-sched.c
··· 1728 1728 for (tok = strtok_r(str, ", ", &tmp); 1729 1729 tok; tok = strtok_r(NULL, ", ", &tmp)) { 1730 1730 if (sort_dimension__add(tok, &sched->sort_list) < 0) { 1731 - error("Unknown --sort key: `%s'", tok); 1732 - usage_with_options(usage_msg, options); 1731 + usage_with_options_msg(usage_msg, options, 1732 + "Unknown --sort key: `%s'", tok); 1733 1733 } 1734 1734 } 1735 1735
+4 -4
tools/perf/builtin-script.c
··· 1767 1767 rep_script_path = get_script_path(argv[0], REPORT_SUFFIX); 1768 1768 1769 1769 if (!rec_script_path && !rep_script_path) { 1770 - fprintf(stderr, " Couldn't find script %s\n\n See perf" 1770 + usage_with_options_msg(script_usage, options, 1771 + "Couldn't find script `%s'\n\n See perf" 1771 1772 " script -l for available scripts.\n", argv[0]); 1772 - usage_with_options(script_usage, options); 1773 1773 } 1774 1774 1775 1775 if (is_top_script(argv[0])) { ··· 1780 1780 rep_args = has_required_arg(rep_script_path); 1781 1781 rec_args = (argc - 1) - rep_args; 1782 1782 if (rec_args < 0) { 1783 - fprintf(stderr, " %s script requires options." 1783 + usage_with_options_msg(script_usage, options, 1784 + "`%s' script requires options." 1784 1785 "\n\n See perf script -l for available " 1785 1786 "scripts and options.\n", argv[0]); 1786 - usage_with_options(script_usage, options); 1787 1787 } 1788 1788 } 1789 1789
+15
tools/perf/util/parse-options.c
··· 760 760 exit(129); 761 761 } 762 762 763 + void usage_with_options_msg(const char * const *usagestr, 764 + const struct option *opts, const char *fmt, ...) 765 + { 766 + va_list ap; 767 + 768 + exit_browser(false); 769 + 770 + va_start(ap, fmt); 771 + strbuf_addv(&error_buf, fmt, ap); 772 + va_end(ap); 773 + 774 + usage_with_options_internal(usagestr, opts, 0, NULL); 775 + exit(129); 776 + } 777 + 763 778 int parse_options_usage(const char * const *usagestr, 764 779 const struct option *opts, 765 780 const char *optstr, bool short_opt)
+4
tools/perf/util/parse-options.h
··· 161 161 162 162 extern NORETURN void usage_with_options(const char * const *usagestr, 163 163 const struct option *options); 164 + extern NORETURN __attribute__((format(printf,3,4))) 165 + void usage_with_options_msg(const char * const *usagestr, 166 + const struct option *options, 167 + const char *fmt, ...); 164 168 165 169 /*----- incremantal advanced APIs -----*/ 166 170
+15 -7
tools/perf/util/strbuf.c
··· 82 82 strbuf_setlen(sb, sb->len + len); 83 83 } 84 84 85 - void strbuf_addf(struct strbuf *sb, const char *fmt, ...) 85 + void strbuf_addv(struct strbuf *sb, const char *fmt, va_list ap) 86 86 { 87 87 int len; 88 - va_list ap; 88 + va_list ap_saved; 89 89 90 90 if (!strbuf_avail(sb)) 91 91 strbuf_grow(sb, 64); 92 - va_start(ap, fmt); 92 + 93 + va_copy(ap_saved, ap); 93 94 len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); 94 - va_end(ap); 95 95 if (len < 0) 96 96 die("your vsnprintf is broken"); 97 97 if (len > strbuf_avail(sb)) { 98 98 strbuf_grow(sb, len); 99 - va_start(ap, fmt); 100 - len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); 101 - va_end(ap); 99 + len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap_saved); 100 + va_end(ap_saved); 102 101 if (len > strbuf_avail(sb)) { 103 102 die("this should not happen, your vsnprintf is broken"); 104 103 } 105 104 } 106 105 strbuf_setlen(sb, sb->len + len); 106 + } 107 + 108 + void strbuf_addf(struct strbuf *sb, const char *fmt, ...) 109 + { 110 + va_list ap; 111 + 112 + va_start(ap, fmt); 113 + strbuf_addv(sb, fmt, ap); 114 + va_end(ap); 107 115 } 108 116 109 117 ssize_t strbuf_read(struct strbuf *sb, int fd, ssize_t hint)
+2
tools/perf/util/strbuf.h
··· 39 39 */ 40 40 41 41 #include <assert.h> 42 + #include <stdarg.h> 42 43 43 44 extern char strbuf_slopbuf[]; 44 45 struct strbuf { ··· 86 85 87 86 __attribute__((format(printf,2,3))) 88 87 extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...); 88 + extern void strbuf_addv(struct strbuf *sb, const char *fmt, va_list ap); 89 89 90 90 /* XXX: if read fails, any partial read is undone */ 91 91 extern ssize_t strbuf_read(struct strbuf *, int fd, ssize_t hint);