[PATCH] perf script: Fix missing fields in help for "script -F"

From: OGAWA Hirofumi
Date: Thu Mar 17 2016 - 00:17:22 EST


Now, help text for "script -F" is missing 2 fields (break and srcline).
So, this seems to happen repeatedly.

To fix, this introduces a bit unreadable macros to prevent missing in future.

Signed-off-by: OGAWA Hirofumi <hirofumi@xxxxxxxxxxxxxxxxxx>
---

tools/perf/builtin-script.c | 97 +++++++++++++++++++++++++++----------------
1 file changed, 63 insertions(+), 34 deletions(-)

diff -puN tools/perf/builtin-script.c~perf-srcline-fix tools/perf/builtin-script.c
--- linux/tools/perf/builtin-script.c~perf-srcline-fix 2016-03-17 12:28:36.372398795 +0900
+++ linux-hirofumi/tools/perf/builtin-script.c 2016-03-17 13:09:12.680398713 +0900
@@ -60,29 +60,62 @@ enum perf_output_field {
PERF_OUTPUT_BRSTACKSYM = 1U << 16,
};

-struct output_option {
+#define ALL_OUTPUT_OPTS_LIST \
+ OPT_FIRST("comm", PERF_OUTPUT_COMM) \
+ OPT("tid", PERF_OUTPUT_TID) \
+ OPT("pid", PERF_OUTPUT_PID) \
+ OPT("time", PERF_OUTPUT_TIME) \
+ OPT("cpu", PERF_OUTPUT_CPU) \
+ OPT("event", PERF_OUTPUT_EVNAME) \
+ OPT("trace", PERF_OUTPUT_TRACE) \
+ OPT("ip", PERF_OUTPUT_IP) \
+ OPT("sym", PERF_OUTPUT_SYM) \
+ OPT("dso", PERF_OUTPUT_DSO) \
+ OPT("addr", PERF_OUTPUT_ADDR) \
+ OPT("symoff", PERF_OUTPUT_SYMOFFSET) \
+ OPT("srcline", PERF_OUTPUT_SRCLINE) \
+ OPT("period", PERF_OUTPUT_PERIOD) \
+ OPT("iregs", PERF_OUTPUT_IREGS) \
+ OPT("brstack", PERF_OUTPUT_BRSTACK) \
+ OPT("brstacksym", PERF_OUTPUT_BRSTACKSYM)
+
+#define OPT_FIRST(s, f) {.str = s, .field = f},
+#define OPT(s, f) OPT_FIRST(s, f)
+
+static const struct output_option {
const char *str;
enum perf_output_field field;
} all_output_options[] = {
- {.str = "comm", .field = PERF_OUTPUT_COMM},
- {.str = "tid", .field = PERF_OUTPUT_TID},
- {.str = "pid", .field = PERF_OUTPUT_PID},
- {.str = "time", .field = PERF_OUTPUT_TIME},
- {.str = "cpu", .field = PERF_OUTPUT_CPU},
- {.str = "event", .field = PERF_OUTPUT_EVNAME},
- {.str = "trace", .field = PERF_OUTPUT_TRACE},
- {.str = "ip", .field = PERF_OUTPUT_IP},
- {.str = "sym", .field = PERF_OUTPUT_SYM},
- {.str = "dso", .field = PERF_OUTPUT_DSO},
- {.str = "addr", .field = PERF_OUTPUT_ADDR},
- {.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET},
- {.str = "srcline", .field = PERF_OUTPUT_SRCLINE},
- {.str = "period", .field = PERF_OUTPUT_PERIOD},
- {.str = "iregs", .field = PERF_OUTPUT_IREGS},
- {.str = "brstack", .field = PERF_OUTPUT_BRSTACK},
- {.str = "brstacksym", .field = PERF_OUTPUT_BRSTACKSYM},
+ ALL_OUTPUT_OPTS_LIST
+};
+
+#define ALL_OUTPUT_TYPES_LIST \
+ OPT_FIRST("hw", PERF_TYPE_HARDWARE) \
+ OPT("sw", PERF_TYPE_SOFTWARE) \
+ OPT("trace", PERF_TYPE_TRACEPOINT) \
+ OPT("raw", PERF_TYPE_RAW) \
+ OPT("break", PERF_TYPE_BREAKPOINT)
+
+static const struct output_type {
+ const char *str;
+ enum perf_type_id field;
+} all_output_types[] = {
+ ALL_OUTPUT_TYPES_LIST
};

+#undef OPT_FIRST
+#undef OPT
+
+#define OPT_FIRST(s, f) s
+#define OPT(s, f) "," s
+static const char *help_fields =
+ "comma separated output fields prepend with 'type:'. "
+ "Valid types: " ALL_OUTPUT_TYPES_LIST ". "
+ "Fields: " ALL_OUTPUT_OPTS_LIST ",flags";
+#undef OPT_FIRST
+#undef OPT
+
+
/* default set to maintain compatibility with current format */
static struct {
bool user_set;
@@ -1195,7 +1228,7 @@ static int parse_output_fields(const str
const char *arg, int unset __maybe_unused)
{
char *tok;
- int i, imax = ARRAY_SIZE(all_output_options);
+ int i, imax;
int j;
int rc = 0;
char *str = strdup(arg);
@@ -1212,17 +1245,15 @@ static int parse_output_fields(const str
if (tok) {
*tok = '\0';
tok++;
- if (!strcmp(str, "hw"))
- type = PERF_TYPE_HARDWARE;
- else if (!strcmp(str, "sw"))
- type = PERF_TYPE_SOFTWARE;
- else if (!strcmp(str, "trace"))
- type = PERF_TYPE_TRACEPOINT;
- else if (!strcmp(str, "raw"))
- type = PERF_TYPE_RAW;
- else if (!strcmp(str, "break"))
- type = PERF_TYPE_BREAKPOINT;
- else {
+
+ imax = ARRAY_SIZE(all_output_types);
+ for (i = 0; i < imax; ++i) {
+ if (strcmp(str, all_output_types[i].str) == 0) {
+ type = all_output_types[i].field;
+ break;
+ }
+ }
+ if (i == imax) {
fprintf(stderr, "Invalid event type in field string.\n");
rc = -EINVAL;
goto out;
@@ -1255,6 +1286,7 @@ static int parse_output_fields(const str
}
}

+ imax = ARRAY_SIZE(all_output_options);
for (tok = strtok(tok, ","); tok; tok = strtok(NULL, ",")) {
for (i = 0; i < imax; ++i) {
if (strcmp(tok, all_output_options[i].str) == 0)
@@ -1910,10 +1942,7 @@ int cmd_script(int argc, const char **ar
OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
"Look for files with symbols relative to this directory"),
OPT_CALLBACK('F', "fields", NULL, "str",
- "comma separated output fields prepend with 'type:'. "
- "Valid types: hw,sw,trace,raw. "
- "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
- "addr,symoff,period,iregs,brstack,brstacksym,flags", parse_output_fields),
+ help_fields, parse_output_fields),
OPT_BOOLEAN('a', "all-cpus", &system_wide,
"system-wide collection from all CPUs"),
OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
_

--
OGAWA Hirofumi <hirofumi@xxxxxxxxxxxxxxxxxx>