This patch adds support for multiple debug options separated by ',' and
non-int values.
        --debug verbose=2,stderr

Signed-off-by: Changbin Du <changbin...@gmail.com>
---
 tools/perf/Documentation/perf.txt | 10 ++--
 tools/perf/util/debug.c           | 86 ++++++++++++++++---------------
 2 files changed, 50 insertions(+), 46 deletions(-)

diff --git a/tools/perf/Documentation/perf.txt 
b/tools/perf/Documentation/perf.txt
index 401f0ed67439..c05a94b2488e 100644
--- a/tools/perf/Documentation/perf.txt
+++ b/tools/perf/Documentation/perf.txt
@@ -19,11 +19,11 @@ OPTIONS
          --debug verbose=2 # sets verbose = 2
 
        List of debug variables allowed to set:
-         verbose          - general debug messages
-         ordered-events   - ordered events object debug messages
-         data-convert     - data convert command debug messages
-         stderr           - write debug output (option -v) to stderr
-                            in browser mode
+         verbose=level         - general debug messages
+         ordered-events=level  - ordered events object debug messages
+         data-convert=level    - data convert command debug messages
+         stderr                - write debug output (option -v) to stderr
+                                 in browser mode
 
 --buildid-dir::
        Setup buildid cache directory. It has higher priority than
diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c
index e55114f0336f..df82ad9cd16d 100644
--- a/tools/perf/util/debug.c
+++ b/tools/perf/util/debug.c
@@ -26,7 +26,7 @@
 int verbose;
 bool dump_trace = false, quiet = false;
 int debug_ordered_events;
-static int redirect_to_stderr;
+static bool redirect_to_stderr;
 int debug_data_convert;
 
 int veprintf(int level, int var, const char *fmt, va_list args)
@@ -172,41 +172,18 @@ void trace_event(union perf_event *event)
                     trace_event_printer, event);
 }
 
-static struct debug_variable {
-       const char *name;
-       int *ptr;
-} debug_variables[] = {
-       { .name = "verbose",            .ptr = &verbose },
-       { .name = "ordered-events",     .ptr = &debug_ordered_events},
-       { .name = "stderr",             .ptr = &redirect_to_stderr},
-       { .name = "data-convert",       .ptr = &debug_data_convert },
-       { .name = NULL, }
-};
-
-int perf_debug_option(const char *str)
+static int str2loglevel(const char *vstr)
 {
-       struct debug_variable *var = &debug_variables[0];
-       char *vstr, *s = strdup(str);
        int v = 1;
-
-       vstr = strchr(s, '=');
-       if (vstr)
-               *vstr++ = 0;
-
-       while (var->name) {
-               if (!strcmp(s, var->name))
-                       break;
-               var++;
-       }
-
-       if (!var->name) {
-               pr_err("Unknown debug variable name '%s'\n", s);
-               free(s);
-               return -1;
-       }
+       char *endptr;
 
        if (vstr) {
-               v = atoi(vstr);
+               v = strtol(vstr, &endptr,0);
+               if (vstr == endptr) {
+                       fprintf(stderr, "warning: '%s' is not a digit\n", vstr);
+                       return -1;
+               }
+
                /*
                 * Allow only values in range (0, 10),
                 * otherwise set 0.
@@ -217,20 +194,47 @@ int perf_debug_option(const char *str)
        if (quiet)
                v = -1;
 
-       *var->ptr = v;
-       free(s);
+       return v;
+}
+
+int perf_debug_option(const char *str)
+{
+       char *sep, *vstr;
+       char *dstr = strdup(str);
+       char *opt = dstr;
+
+       do {
+               if ((sep = strchr(opt, ',')) != NULL)
+                       *sep = '\0';
+
+               vstr = strchr(opt, '=');
+               if (vstr)
+                       *vstr++ = 0;
+
+               if (!strcmp(opt, "verbose"))
+                       verbose = str2loglevel(vstr);
+               else if (!strcmp(opt, "ordered-events"))
+                       debug_ordered_events = str2loglevel(vstr);
+               else if (!strcmp(opt, "data-convert"))
+                       debug_data_convert = str2loglevel(vstr);
+               else if (!strcmp(opt, "stderr"))
+                       redirect_to_stderr = true;
+               else {
+                       fprintf(stderr, "unkown debug option '%s'\n", opt);
+                       free(dstr);
+                       return -1;
+               }
+
+               opt = sep + 1;
+       } while (sep && sep[1]);
+
+       free(dstr);
        return 0;
 }
 
 int perf_quiet_option(void)
 {
-       struct debug_variable *var = &debug_variables[0];
-
-       /* disable all debug messages */
-       while (var->name) {
-               *var->ptr = -1;
-               var++;
-       }
+       verbose = debug_ordered_events = debug_data_convert = -1;
 
        return 0;
 }
-- 
2.20.1

Reply via email to