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

perf kvm: introduce --list-cmds for use by scripts

Introduce

$ perf kvm --list-cmds

to dump a raw list of commands for use by the completion script. In
order to do this, introduce parse_options_subcommand() for handling
subcommands as a special case in the parse-options machinery.

Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
Acked-by: David Ahern <dsahern@gmail.com>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
Link: http://lkml.kernel.org/r/1393896396-10427-1-git-send-email-artagnon@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Ramkumar Ramachandra and committed by
Arnaldo Carvalho de Melo
09a71b97 94a0793d

+46 -13
+5 -7
tools/perf/builtin-kvm.c
··· 1691 1691 OPT_END() 1692 1692 }; 1693 1693 1694 - 1695 - const char * const kvm_usage[] = { 1696 - "perf kvm [<options>] {top|record|report|diff|buildid-list|stat}", 1697 - NULL 1698 - }; 1694 + const char *const kvm_subcommands[] = { "top", "record", "report", "diff", 1695 + "buildid-list", "stat", NULL }; 1696 + const char *kvm_usage[] = { NULL, NULL }; 1699 1697 1700 1698 perf_host = 0; 1701 1699 perf_guest = 1; 1702 1700 1703 - argc = parse_options(argc, argv, kvm_options, kvm_usage, 1704 - PARSE_OPT_STOP_AT_NON_OPTION); 1701 + argc = parse_options_subcommand(argc, argv, kvm_options, kvm_subcommands, kvm_usage, 1702 + PARSE_OPT_STOP_AT_NON_OPTION); 1705 1703 if (!argc) 1706 1704 usage_with_options(kvm_usage, kvm_options); 1707 1705
+1 -1
tools/perf/perf-completion.sh
··· 123 123 __perfcomp_colon "$evts" "$cur" 124 124 # List subcommands for 'perf kvm' 125 125 elif [[ $prev == "kvm" ]]; then 126 - subcmds="top record report diff buildid-list stat" 126 + subcmds=$($cmd $prev --list-cmds) 127 127 __perfcomp_colon "$subcmds" "$cur" 128 128 # List long option names 129 129 elif [[ $cur == --* ]]; then
+33 -4
tools/perf/util/parse-options.c
··· 407 407 if (internal_help && !strcmp(arg + 2, "help")) 408 408 return usage_with_options_internal(usagestr, options, 0); 409 409 if (!strcmp(arg + 2, "list-opts")) 410 - return PARSE_OPT_LIST; 410 + return PARSE_OPT_LIST_OPTS; 411 + if (!strcmp(arg + 2, "list-cmds")) 412 + return PARSE_OPT_LIST_SUBCMDS; 411 413 switch (parse_long_opt(ctx, arg + 2, options)) { 412 414 case -1: 413 415 return parse_options_usage(usagestr, options, arg + 2, 0); ··· 435 433 return ctx->cpidx + ctx->argc; 436 434 } 437 435 438 - int parse_options(int argc, const char **argv, const struct option *options, 439 - const char * const usagestr[], int flags) 436 + int parse_options_subcommand(int argc, const char **argv, const struct option *options, 437 + const char *const subcommands[], const char *usagestr[], int flags) 440 438 { 441 439 struct parse_opt_ctx_t ctx; 442 440 443 441 perf_header__set_cmdline(argc, argv); 442 + 443 + /* build usage string if it's not provided */ 444 + if (subcommands && !usagestr[0]) { 445 + struct strbuf buf = STRBUF_INIT; 446 + 447 + strbuf_addf(&buf, "perf %s [<options>] {", argv[0]); 448 + for (int i = 0; subcommands[i]; i++) { 449 + if (i) 450 + strbuf_addstr(&buf, "|"); 451 + strbuf_addstr(&buf, subcommands[i]); 452 + } 453 + strbuf_addstr(&buf, "}"); 454 + 455 + usagestr[0] = strdup(buf.buf); 456 + strbuf_release(&buf); 457 + } 444 458 445 459 parse_options_start(&ctx, argc, argv, flags); 446 460 switch (parse_options_step(&ctx, options, usagestr)) { ··· 464 446 exit(129); 465 447 case PARSE_OPT_DONE: 466 448 break; 467 - case PARSE_OPT_LIST: 449 + case PARSE_OPT_LIST_OPTS: 468 450 while (options->type != OPTION_END) { 469 451 printf("--%s ", options->long_name); 470 452 options++; 471 453 } 454 + exit(130); 455 + case PARSE_OPT_LIST_SUBCMDS: 456 + for (int i = 0; subcommands[i]; i++) 457 + printf("%s ", subcommands[i]); 472 458 exit(130); 473 459 default: /* PARSE_OPT_UNKNOWN */ 474 460 if (ctx.argv[0][1] == '-') { ··· 484 462 } 485 463 486 464 return parse_options_end(&ctx); 465 + } 466 + 467 + int parse_options(int argc, const char **argv, const struct option *options, 468 + const char * const usagestr[], int flags) 469 + { 470 + return parse_options_subcommand(argc, argv, options, NULL, 471 + (const char **) usagestr, flags); 487 472 } 488 473 489 474 #define USAGE_OPTS_WIDTH 24
+7 -1
tools/perf/util/parse-options.h
··· 140 140 const struct option *options, 141 141 const char * const usagestr[], int flags); 142 142 143 + extern int parse_options_subcommand(int argc, const char **argv, 144 + const struct option *options, 145 + const char *const subcommands[], 146 + const char *usagestr[], int flags); 147 + 143 148 extern NORETURN void usage_with_options(const char * const *usagestr, 144 149 const struct option *options); 145 150 ··· 153 148 enum { 154 149 PARSE_OPT_HELP = -1, 155 150 PARSE_OPT_DONE, 156 - PARSE_OPT_LIST, 151 + PARSE_OPT_LIST_OPTS, 152 + PARSE_OPT_LIST_SUBCMDS, 157 153 PARSE_OPT_UNKNOWN, 158 154 }; 159 155