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

perf tools: Move help_unknown_cmd() to its own file

help_unknown_cmd() is quite perf-specific because it relies on some
perf_config*() functions. Move it and its supporting functions out into
a separate file so that help.c can be moved to a library.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/562d918bcaaf340c1ae3e47586b3f0ae33b9918b.1449965119.git.jpoimboe@redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Josh Poimboeuf and committed by
Arnaldo Carvalho de Melo
5feaac24 a871a775

+110 -104
+1
tools/perf/util/Build
··· 87 87 libperf-y += parse-branch-options.o 88 88 libperf-y += parse-regs-options.o 89 89 libperf-y += term.o 90 + libperf-y += help-unknown-cmd.o 90 91 91 92 libperf-$(CONFIG_LIBBPF) += bpf-loader.o 92 93 libperf-$(CONFIG_BPF_PROLOGUE) += bpf-prologue.o
+103
tools/perf/util/help-unknown-cmd.c
··· 1 + #include "cache.h" 2 + #include "help.h" 3 + #include "../builtin.h" 4 + #include "levenshtein.h" 5 + 6 + static int autocorrect; 7 + static struct cmdnames aliases; 8 + 9 + static int perf_unknown_cmd_config(const char *var, const char *value, void *cb) 10 + { 11 + if (!strcmp(var, "help.autocorrect")) 12 + autocorrect = perf_config_int(var,value); 13 + /* Also use aliases for command lookup */ 14 + if (!prefixcmp(var, "alias.")) 15 + add_cmdname(&aliases, var + 6, strlen(var + 6)); 16 + 17 + return perf_default_config(var, value, cb); 18 + } 19 + 20 + static int levenshtein_compare(const void *p1, const void *p2) 21 + { 22 + const struct cmdname *const *c1 = p1, *const *c2 = p2; 23 + const char *s1 = (*c1)->name, *s2 = (*c2)->name; 24 + int l1 = (*c1)->len; 25 + int l2 = (*c2)->len; 26 + return l1 != l2 ? l1 - l2 : strcmp(s1, s2); 27 + } 28 + 29 + static void add_cmd_list(struct cmdnames *cmds, struct cmdnames *old) 30 + { 31 + unsigned int i; 32 + 33 + ALLOC_GROW(cmds->names, cmds->cnt + old->cnt, cmds->alloc); 34 + 35 + for (i = 0; i < old->cnt; i++) 36 + cmds->names[cmds->cnt++] = old->names[i]; 37 + zfree(&old->names); 38 + old->cnt = 0; 39 + } 40 + 41 + const char *help_unknown_cmd(const char *cmd) 42 + { 43 + unsigned int i, n = 0, best_similarity = 0; 44 + struct cmdnames main_cmds, other_cmds; 45 + 46 + memset(&main_cmds, 0, sizeof(main_cmds)); 47 + memset(&other_cmds, 0, sizeof(main_cmds)); 48 + memset(&aliases, 0, sizeof(aliases)); 49 + 50 + perf_config(perf_unknown_cmd_config, NULL); 51 + 52 + load_command_list("perf-", &main_cmds, &other_cmds); 53 + 54 + add_cmd_list(&main_cmds, &aliases); 55 + add_cmd_list(&main_cmds, &other_cmds); 56 + qsort(main_cmds.names, main_cmds.cnt, 57 + sizeof(main_cmds.names), cmdname_compare); 58 + uniq(&main_cmds); 59 + 60 + if (main_cmds.cnt) { 61 + /* This reuses cmdname->len for similarity index */ 62 + for (i = 0; i < main_cmds.cnt; ++i) 63 + main_cmds.names[i]->len = 64 + levenshtein(cmd, main_cmds.names[i]->name, 0, 2, 1, 4); 65 + 66 + qsort(main_cmds.names, main_cmds.cnt, 67 + sizeof(*main_cmds.names), levenshtein_compare); 68 + 69 + best_similarity = main_cmds.names[0]->len; 70 + n = 1; 71 + while (n < main_cmds.cnt && best_similarity == main_cmds.names[n]->len) 72 + ++n; 73 + } 74 + 75 + if (autocorrect && n == 1) { 76 + const char *assumed = main_cmds.names[0]->name; 77 + 78 + main_cmds.names[0] = NULL; 79 + clean_cmdnames(&main_cmds); 80 + fprintf(stderr, "WARNING: You called a perf program named '%s', " 81 + "which does not exist.\n" 82 + "Continuing under the assumption that you meant '%s'\n", 83 + cmd, assumed); 84 + if (autocorrect > 0) { 85 + fprintf(stderr, "in %0.1f seconds automatically...\n", 86 + (float)autocorrect/10.0); 87 + poll(NULL, 0, autocorrect * 100); 88 + } 89 + return assumed; 90 + } 91 + 92 + fprintf(stderr, "perf: '%s' is not a perf-command. See 'perf --help'.\n", cmd); 93 + 94 + if (main_cmds.cnt && best_similarity < 6) { 95 + fprintf(stderr, "\nDid you mean %s?\n", 96 + n < 2 ? "this": "one of these"); 97 + 98 + for (i = 0; i < n; i++) 99 + fprintf(stderr, "\t%s\n", main_cmds.names[i]->name); 100 + } 101 + 102 + exit(1); 103 + }
tools/perf/util/help-unknown-cmd.h
+3 -104
tools/perf/util/help.c
··· 1 1 #include "cache.h" 2 2 #include "../builtin.h" 3 3 #include "exec_cmd.h" 4 - #include "levenshtein.h" 5 4 #include "help.h" 6 - #include <termios.h> 7 5 8 6 void add_cmdname(struct cmdnames *cmds, const char *name, size_t len) 9 7 { ··· 15 17 cmds->names[cmds->cnt++] = ent; 16 18 } 17 19 18 - static void clean_cmdnames(struct cmdnames *cmds) 20 + void clean_cmdnames(struct cmdnames *cmds) 19 21 { 20 22 unsigned int i; 21 23 ··· 26 28 cmds->alloc = 0; 27 29 } 28 30 29 - static int cmdname_compare(const void *a_, const void *b_) 31 + int cmdname_compare(const void *a_, const void *b_) 30 32 { 31 33 struct cmdname *a = *(struct cmdname **)a_; 32 34 struct cmdname *b = *(struct cmdname **)b_; 33 35 return strcmp(a->name, b->name); 34 36 } 35 37 36 - static void uniq(struct cmdnames *cmds) 38 + void uniq(struct cmdnames *cmds) 37 39 { 38 40 unsigned int i, j; 39 41 ··· 230 232 if (!strcmp(s, c->names[i]->name)) 231 233 return 1; 232 234 return 0; 233 - } 234 - 235 - static int autocorrect; 236 - static struct cmdnames aliases; 237 - 238 - static int perf_unknown_cmd_config(const char *var, const char *value, void *cb) 239 - { 240 - if (!strcmp(var, "help.autocorrect")) 241 - autocorrect = perf_config_int(var,value); 242 - /* Also use aliases for command lookup */ 243 - if (!prefixcmp(var, "alias.")) 244 - add_cmdname(&aliases, var + 6, strlen(var + 6)); 245 - 246 - return perf_default_config(var, value, cb); 247 - } 248 - 249 - static int levenshtein_compare(const void *p1, const void *p2) 250 - { 251 - const struct cmdname *const *c1 = p1, *const *c2 = p2; 252 - const char *s1 = (*c1)->name, *s2 = (*c2)->name; 253 - int l1 = (*c1)->len; 254 - int l2 = (*c2)->len; 255 - return l1 != l2 ? l1 - l2 : strcmp(s1, s2); 256 - } 257 - 258 - static void add_cmd_list(struct cmdnames *cmds, struct cmdnames *old) 259 - { 260 - unsigned int i; 261 - 262 - ALLOC_GROW(cmds->names, cmds->cnt + old->cnt, cmds->alloc); 263 - 264 - for (i = 0; i < old->cnt; i++) 265 - cmds->names[cmds->cnt++] = old->names[i]; 266 - zfree(&old->names); 267 - old->cnt = 0; 268 - } 269 - 270 - const char *help_unknown_cmd(const char *cmd) 271 - { 272 - unsigned int i, n = 0, best_similarity = 0; 273 - struct cmdnames main_cmds, other_cmds; 274 - 275 - memset(&main_cmds, 0, sizeof(main_cmds)); 276 - memset(&other_cmds, 0, sizeof(main_cmds)); 277 - memset(&aliases, 0, sizeof(aliases)); 278 - 279 - perf_config(perf_unknown_cmd_config, NULL); 280 - 281 - load_command_list("perf-", &main_cmds, &other_cmds); 282 - 283 - add_cmd_list(&main_cmds, &aliases); 284 - add_cmd_list(&main_cmds, &other_cmds); 285 - qsort(main_cmds.names, main_cmds.cnt, 286 - sizeof(main_cmds.names), cmdname_compare); 287 - uniq(&main_cmds); 288 - 289 - if (main_cmds.cnt) { 290 - /* This reuses cmdname->len for similarity index */ 291 - for (i = 0; i < main_cmds.cnt; ++i) 292 - main_cmds.names[i]->len = 293 - levenshtein(cmd, main_cmds.names[i]->name, 0, 2, 1, 4); 294 - 295 - qsort(main_cmds.names, main_cmds.cnt, 296 - sizeof(*main_cmds.names), levenshtein_compare); 297 - 298 - best_similarity = main_cmds.names[0]->len; 299 - n = 1; 300 - while (n < main_cmds.cnt && best_similarity == main_cmds.names[n]->len) 301 - ++n; 302 - } 303 - 304 - if (autocorrect && n == 1) { 305 - const char *assumed = main_cmds.names[0]->name; 306 - 307 - main_cmds.names[0] = NULL; 308 - clean_cmdnames(&main_cmds); 309 - fprintf(stderr, "WARNING: You called a perf program named '%s', " 310 - "which does not exist.\n" 311 - "Continuing under the assumption that you meant '%s'\n", 312 - cmd, assumed); 313 - if (autocorrect > 0) { 314 - fprintf(stderr, "in %0.1f seconds automatically...\n", 315 - (float)autocorrect/10.0); 316 - poll(NULL, 0, autocorrect * 100); 317 - } 318 - return assumed; 319 - } 320 - 321 - fprintf(stderr, "perf: '%s' is not a perf-command. See 'perf --help'.\n", cmd); 322 - 323 - if (main_cmds.cnt && best_similarity < 6) { 324 - fprintf(stderr, "\nDid you mean %s?\n", 325 - n < 2 ? "this": "one of these"); 326 - 327 - for (i = 0; i < n; i++) 328 - fprintf(stderr, "\t%s\n", main_cmds.names[i]->name); 329 - } 330 - 331 - exit(1); 332 235 }
+3
tools/perf/util/help.h
··· 20 20 struct cmdnames *main_cmds, 21 21 struct cmdnames *other_cmds); 22 22 void add_cmdname(struct cmdnames *cmds, const char *name, size_t len); 23 + void clean_cmdnames(struct cmdnames *cmds); 24 + int cmdname_compare(const void *a, const void *b); 25 + void uniq(struct cmdnames *cmds); 23 26 /* Here we require that excludes is a sorted list. */ 24 27 void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes); 25 28 int is_in_cmdlist(struct cmdnames *c, const char *s);