aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/builtin-report.c2
-rw-r--r--tools/perf/util/parse-options.c21
-rw-r--r--tools/perf/util/parse-options.h2
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
45struct option; 46struct 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) \