diff options
-rw-r--r-- | tools/perf/builtin-report.c | 2 | ||||
-rw-r--r-- | tools/perf/util/parse-options.c | 21 | ||||
-rw-r--r-- | tools/perf/util/parse-options.h | 2 |
3 files changed, 22 insertions, 3 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 52f74e1367e9..0ae482689e3c 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -676,7 +676,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) | |||
676 | OPT_STRING('w', "column-widths", &symbol_conf.col_width_list_str, | 676 | OPT_STRING('w', "column-widths", &symbol_conf.col_width_list_str, |
677 | "width[,width...]", | 677 | "width[,width...]", |
678 | "don't try to adjust column width, use these fixed values"), | 678 | "don't try to adjust column width, use these fixed values"), |
679 | OPT_STRING('t', "field-separator", &symbol_conf.field_sep, "separator", | 679 | OPT_STRING_NOEMPTY('t', "field-separator", &symbol_conf.field_sep, "separator", |
680 | "separator for columns, no spaces will be added between " | 680 | "separator for columns, no spaces will be added between " |
681 | "columns '.' is reserved."), | 681 | "columns '.' is reserved."), |
682 | OPT_BOOLEAN('U', "hide-unresolved", &report.hide_unresolved, | 682 | OPT_BOOLEAN('U', "hide-unresolved", &report.hide_unresolved, |
diff --git a/tools/perf/util/parse-options.c b/tools/perf/util/parse-options.c index 1457d6639b60..01626be2a8eb 100644 --- a/tools/perf/util/parse-options.c +++ b/tools/perf/util/parse-options.c | |||
@@ -37,6 +37,7 @@ static int get_value(struct parse_opt_ctx_t *p, | |||
37 | { | 37 | { |
38 | const char *s, *arg = NULL; | 38 | const char *s, *arg = NULL; |
39 | const int unset = flags & OPT_UNSET; | 39 | const int unset = flags & OPT_UNSET; |
40 | int err; | ||
40 | 41 | ||
41 | if (unset && p->opt) | 42 | if (unset && p->opt) |
42 | return opterror(opt, "takes no value", flags); | 43 | return opterror(opt, "takes no value", flags); |
@@ -114,13 +115,29 @@ static int get_value(struct parse_opt_ctx_t *p, | |||
114 | return 0; | 115 | return 0; |
115 | 116 | ||
116 | case OPTION_STRING: | 117 | case OPTION_STRING: |
118 | err = 0; | ||
117 | if (unset) | 119 | if (unset) |
118 | *(const char **)opt->value = NULL; | 120 | *(const char **)opt->value = NULL; |
119 | else if (opt->flags & PARSE_OPT_OPTARG && !p->opt) | 121 | else if (opt->flags & PARSE_OPT_OPTARG && !p->opt) |
120 | *(const char **)opt->value = (const char *)opt->defval; | 122 | *(const char **)opt->value = (const char *)opt->defval; |
121 | else | 123 | else |
122 | return get_arg(p, opt, flags, (const char **)opt->value); | 124 | err = get_arg(p, opt, flags, (const char **)opt->value); |
123 | return 0; | 125 | |
126 | /* PARSE_OPT_NOEMPTY: Allow NULL but disallow empty string. */ | ||
127 | if (opt->flags & PARSE_OPT_NOEMPTY) { | ||
128 | const char *val = *(const char **)opt->value; | ||
129 | |||
130 | if (!val) | ||
131 | return err; | ||
132 | |||
133 | /* Similar to unset if we are given an empty string. */ | ||
134 | if (val[0] == '\0') { | ||
135 | *(const char **)opt->value = NULL; | ||
136 | return 0; | ||
137 | } | ||
138 | } | ||
139 | |||
140 | return err; | ||
124 | 141 | ||
125 | case OPTION_CALLBACK: | 142 | case OPTION_CALLBACK: |
126 | if (unset) | 143 | if (unset) |
diff --git a/tools/perf/util/parse-options.h b/tools/perf/util/parse-options.h index 97b153fb4999..59561fd86278 100644 --- a/tools/perf/util/parse-options.h +++ b/tools/perf/util/parse-options.h | |||
@@ -40,6 +40,7 @@ enum parse_opt_option_flags { | |||
40 | PARSE_OPT_LASTARG_DEFAULT = 16, | 40 | PARSE_OPT_LASTARG_DEFAULT = 16, |
41 | PARSE_OPT_DISABLED = 32, | 41 | PARSE_OPT_DISABLED = 32, |
42 | PARSE_OPT_EXCLUSIVE = 64, | 42 | PARSE_OPT_EXCLUSIVE = 64, |
43 | PARSE_OPT_NOEMPTY = 128, | ||
43 | }; | 44 | }; |
44 | 45 | ||
45 | struct option; | 46 | struct option; |
@@ -122,6 +123,7 @@ struct option { | |||
122 | #define OPT_LONG(s, l, v, h) { .type = OPTION_LONG, .short_name = (s), .long_name = (l), .value = check_vtype(v, long *), .help = (h) } | 123 | #define OPT_LONG(s, l, v, h) { .type = OPTION_LONG, .short_name = (s), .long_name = (l), .value = check_vtype(v, long *), .help = (h) } |
123 | #define OPT_U64(s, l, v, h) { .type = OPTION_U64, .short_name = (s), .long_name = (l), .value = check_vtype(v, u64 *), .help = (h) } | 124 | #define OPT_U64(s, l, v, h) { .type = OPTION_U64, .short_name = (s), .long_name = (l), .value = check_vtype(v, u64 *), .help = (h) } |
124 | #define OPT_STRING(s, l, v, a, h) { .type = OPTION_STRING, .short_name = (s), .long_name = (l), .value = check_vtype(v, const char **), (a), .help = (h) } | 125 | #define OPT_STRING(s, l, v, a, h) { .type = OPTION_STRING, .short_name = (s), .long_name = (l), .value = check_vtype(v, const char **), (a), .help = (h) } |
126 | #define OPT_STRING_NOEMPTY(s, l, v, a, h) { .type = OPTION_STRING, .short_name = (s), .long_name = (l), .value = check_vtype(v, const char **), (a), .help = (h), .flags = PARSE_OPT_NOEMPTY} | ||
125 | #define OPT_DATE(s, l, v, h) \ | 127 | #define OPT_DATE(s, l, v, h) \ |
126 | { .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = "time", .help = (h), .callback = parse_opt_approxidate_cb } | 128 | { .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = "time", .help = (h), .callback = parse_opt_approxidate_cb } |
127 | #define OPT_CALLBACK(s, l, v, a, h, f) \ | 129 | #define OPT_CALLBACK(s, l, v, a, h, f) \ |