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

perf tools: Add general function to parse sublevel options

This factors out a general function perf_parse_sublevel_options() to
parse sublevel options. The 'sublevel' options is something like the
'--debug' options which allow more sublevel options.

Signed-off-by: Changbin Du <changbin.du@gmail.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Steven Rostedt (VMware) <rostedt@goodmis.org>
Link: http://lore.kernel.org/lkml/20200808023141.14227-8-changbin.du@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Changbin Du and committed by
Arnaldo Carvalho de Melo
a80abe2a 5b347472

+99 -44
+1
tools/perf/util/Build
··· 117 117 perf-y += parse-branch-options.o 118 118 perf-y += dump-insn.o 119 119 perf-y += parse-regs-options.o 120 + perf-y += parse-sublevel-options.o 120 121 perf-y += term.o 121 122 perf-y += help-unknown-cmd.o 122 123 perf-y += mem-events.o
+17 -44
tools/perf/util/debug.c
··· 20 20 #include "target.h" 21 21 #include "ui/helpline.h" 22 22 #include "ui/ui.h" 23 + #include "util/parse-sublevel-options.h" 23 24 24 25 #include <linux/ctype.h> 25 26 ··· 174 173 trace_event_printer, event); 175 174 } 176 175 177 - static struct debug_variable { 178 - const char *name; 179 - int *ptr; 180 - } debug_variables[] = { 181 - { .name = "verbose", .ptr = &verbose }, 182 - { .name = "ordered-events", .ptr = &debug_ordered_events}, 183 - { .name = "stderr", .ptr = &redirect_to_stderr}, 184 - { .name = "data-convert", .ptr = &debug_data_convert }, 185 - { .name = "perf-event-open", .ptr = &debug_peo_args }, 176 + static struct sublevel_option debug_opts[] = { 177 + { .name = "verbose", .value_ptr = &verbose }, 178 + { .name = "ordered-events", .value_ptr = &debug_ordered_events}, 179 + { .name = "stderr", .value_ptr = &redirect_to_stderr}, 180 + { .name = "data-convert", .value_ptr = &debug_data_convert }, 181 + { .name = "perf-event-open", .value_ptr = &debug_peo_args }, 186 182 { .name = NULL, } 187 183 }; 188 184 189 185 int perf_debug_option(const char *str) 190 186 { 191 - struct debug_variable *var = &debug_variables[0]; 192 - char *vstr, *s = strdup(str); 193 - int v = 1; 187 + int ret; 194 188 195 - vstr = strchr(s, '='); 196 - if (vstr) 197 - *vstr++ = 0; 189 + ret = perf_parse_sublevel_options(str, debug_opts); 190 + if (ret) 191 + return ret; 198 192 199 - while (var->name) { 200 - if (!strcmp(s, var->name)) 201 - break; 202 - var++; 203 - } 193 + /* Allow only verbose value in range (0, 10), otherwise set 0. */ 194 + verbose = (verbose < 0) || (verbose > 10) ? 0 : verbose; 204 195 205 - if (!var->name) { 206 - pr_err("Unknown debug variable name '%s'\n", s); 207 - free(s); 208 - return -1; 209 - } 210 - 211 - if (vstr) { 212 - v = atoi(vstr); 213 - /* 214 - * Allow only values in range (0, 10), 215 - * otherwise set 0. 216 - */ 217 - v = (v < 0) || (v > 10) ? 0 : v; 218 - } 219 - 220 - if (quiet) 221 - v = -1; 222 - 223 - *var->ptr = v; 224 - free(s); 225 196 return 0; 226 197 } 227 198 228 199 int perf_quiet_option(void) 229 200 { 230 - struct debug_variable *var = &debug_variables[0]; 201 + struct sublevel_option *opt = &debug_opts[0]; 231 202 232 203 /* disable all debug messages */ 233 - while (var->name) { 234 - *var->ptr = -1; 235 - var++; 204 + while (opt->name) { 205 + *opt->value_ptr = -1; 206 + opt++; 236 207 } 237 208 238 209 return 0;
+70
tools/perf/util/parse-sublevel-options.c
··· 1 + #include <stdlib.h> 2 + #include <stdint.h> 3 + #include <string.h> 4 + #include <stdio.h> 5 + 6 + #include "util/debug.h" 7 + #include "util/parse-sublevel-options.h" 8 + 9 + static int parse_one_sublevel_option(const char *str, 10 + struct sublevel_option *opts) 11 + { 12 + struct sublevel_option *opt = opts; 13 + char *vstr, *s = strdup(str); 14 + int v = 1; 15 + 16 + if (!s) { 17 + pr_err("no memory\n"); 18 + return -1; 19 + } 20 + 21 + vstr = strchr(s, '='); 22 + if (vstr) 23 + *vstr++ = 0; 24 + 25 + while (opt->name) { 26 + if (!strcmp(s, opt->name)) 27 + break; 28 + opt++; 29 + } 30 + 31 + if (!opt->name) { 32 + pr_err("Unknown option name '%s'\n", s); 33 + free(s); 34 + return -1; 35 + } 36 + 37 + if (vstr) 38 + v = atoi(vstr); 39 + 40 + *opt->value_ptr = v; 41 + free(s); 42 + return 0; 43 + } 44 + 45 + /* parse options like --foo a=<n>,b,c... */ 46 + int perf_parse_sublevel_options(const char *str, struct sublevel_option *opts) 47 + { 48 + char *s = strdup(str); 49 + char *p = NULL; 50 + int ret; 51 + 52 + if (!s) { 53 + pr_err("no memory\n"); 54 + return -1; 55 + } 56 + 57 + p = strtok(s, ","); 58 + while (p) { 59 + ret = parse_one_sublevel_option(p, opts); 60 + if (ret) { 61 + free(s); 62 + return ret; 63 + } 64 + 65 + p = strtok(NULL, ","); 66 + } 67 + 68 + free(s); 69 + return 0; 70 + }
+11
tools/perf/util/parse-sublevel-options.h
··· 1 + #ifndef _PERF_PARSE_SUBLEVEL_OPTIONS_H 2 + #define _PERF_PARSE_SUBLEVEL_OPTIONS_H 3 + 4 + struct sublevel_option { 5 + const char *name; 6 + int *value_ptr; 7 + }; 8 + 9 + int perf_parse_sublevel_options(const char *str, struct sublevel_option *opts); 10 + 11 + #endif