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

perf tools: Fix the bash completion problem of 'perf --*'

The perf-completion.sh uses a predefined string '--help --version
--exec-path --html-path --paginate --no-pager --perf-dir --work-tree
--debugfs-dir' for the bash completion of 'perf --*', which has two
problems:

Problem 1: If the options of perf are changed (see handle_options() in
perf.c), the perf-completion.sh has to be changed at the same time. If
not, the bash completion of 'perf --*' and the options which perf
really supports will be inconsistent.

Problem 2: When typing another single character after 'perf --', e.g.
'h', and hit TAB key to get the bash completion of 'perf --h', the
character 'h' disappears at once. This is not what we want, we wish the
bash completion can return '--help --html-path' and then we can
continue to choose one.

To solve this problem, we add '--list-opts' to perf, which now supports
'perf --list-opts' directly, and its result can be used in bash
completion now.

Example:

Before this patch:

$ perf --h <-- hit TAB key after character 'h'
$ perf -- <-- 'h' disappears and no required result

After this patch:

$ perf --h <-- hit TAB key after character 'h'
--help --html-path <-- the required result

Signed-off-by: Yunlong Song <yunlong.song@huawei.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1425032491-20224-8-git-send-email-yunlong.song@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Yunlong Song and committed by
Arnaldo Carvalho de Melo
7335399a 5ef803ee

+29 -4
+2 -4
tools/perf/perf-completion.sh
··· 110 110 # List perf subcommands or long options 111 111 if [ $cword -eq 1 ]; then 112 112 if [[ $cur == --* ]]; then 113 - __perfcomp '--help --version \ 114 - --exec-path --html-path --paginate --no-pager \ 115 - --perf-dir --work-tree --debugfs-dir' -- "$cur" 113 + cmds=$($cmd --list-opts) 116 114 else 117 115 cmds=$($cmd --list-cmds) 118 - __perfcomp "$cmds" "$cur" 119 116 fi 117 + __perfcomp "$cmds" "$cur" 120 118 # List possible events for -e option 121 119 elif [[ $prev == "-e" && "${words[1]}" == @(record|stat|top) ]]; then 122 120 evts=$($cmd list --raw-dump)
+27
tools/perf/perf.c
··· 13 13 #include "util/quote.h" 14 14 #include "util/run-command.h" 15 15 #include "util/parse-events.h" 16 + #include "util/parse-options.h" 16 17 #include "util/debug.h" 17 18 #include <api/fs/debugfs.h> 18 19 #include <pthread.h> ··· 126 125 } 127 126 } 128 127 128 + struct option options[] = { 129 + OPT_ARGUMENT("help", "help"), 130 + OPT_ARGUMENT("version", "version"), 131 + OPT_ARGUMENT("exec-path", "exec-path"), 132 + OPT_ARGUMENT("html-path", "html-path"), 133 + OPT_ARGUMENT("paginate", "paginate"), 134 + OPT_ARGUMENT("no-pager", "no-pager"), 135 + OPT_ARGUMENT("perf-dir", "perf-dir"), 136 + OPT_ARGUMENT("work-tree", "work-tree"), 137 + OPT_ARGUMENT("debugfs-dir", "debugfs-dir"), 138 + OPT_ARGUMENT("buildid-dir", "buildid-dir"), 139 + OPT_ARGUMENT("list-cmds", "list-cmds"), 140 + OPT_ARGUMENT("list-opts", "list-opts"), 141 + OPT_ARGUMENT("debug", "debug"), 142 + OPT_END() 143 + }; 144 + 129 145 static int handle_options(const char ***argv, int *argc, int *envchanged) 130 146 { 131 147 int handled = 0; ··· 240 222 for (i = 0; i < ARRAY_SIZE(commands); i++) { 241 223 struct cmd_struct *p = commands+i; 242 224 printf("%s ", p->cmd); 225 + } 226 + putchar('\n'); 227 + exit(0); 228 + } else if (!strcmp(cmd, "--list-opts")) { 229 + unsigned int i; 230 + 231 + for (i = 0; i < ARRAY_SIZE(options)-1; i++) { 232 + struct option *p = options+i; 233 + printf("--%s ", p->long_name); 243 234 } 244 235 putchar('\n'); 245 236 exit(0);