Commit 7335399a authored by Yunlong Song's avatar Yunlong Song Committed by Arnaldo Carvalho de Melo

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: default avatarYunlong Song <yunlong.song@huawei.com>
Tested-by: default avatarArnaldo 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.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 5ef803ee
...@@ -110,13 +110,11 @@ __perf_main () ...@@ -110,13 +110,11 @@ __perf_main ()
# List perf subcommands or long options # List perf subcommands or long options
if [ $cword -eq 1 ]; then if [ $cword -eq 1 ]; then
if [[ $cur == --* ]]; then if [[ $cur == --* ]]; then
__perfcomp '--help --version \ cmds=$($cmd --list-opts)
--exec-path --html-path --paginate --no-pager \
--perf-dir --work-tree --debugfs-dir' -- "$cur"
else else
cmds=$($cmd --list-cmds) cmds=$($cmd --list-cmds)
__perfcomp "$cmds" "$cur"
fi fi
__perfcomp "$cmds" "$cur"
# List possible events for -e option # List possible events for -e option
elif [[ $prev == "-e" && "${words[1]}" == @(record|stat|top) ]]; then elif [[ $prev == "-e" && "${words[1]}" == @(record|stat|top) ]]; then
evts=$($cmd list --raw-dump) evts=$($cmd list --raw-dump)
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "util/quote.h" #include "util/quote.h"
#include "util/run-command.h" #include "util/run-command.h"
#include "util/parse-events.h" #include "util/parse-events.h"
#include "util/parse-options.h"
#include "util/debug.h" #include "util/debug.h"
#include <api/fs/debugfs.h> #include <api/fs/debugfs.h>
#include <pthread.h> #include <pthread.h>
...@@ -125,6 +126,23 @@ static void commit_pager_choice(void) ...@@ -125,6 +126,23 @@ static void commit_pager_choice(void)
} }
} }
struct option options[] = {
OPT_ARGUMENT("help", "help"),
OPT_ARGUMENT("version", "version"),
OPT_ARGUMENT("exec-path", "exec-path"),
OPT_ARGUMENT("html-path", "html-path"),
OPT_ARGUMENT("paginate", "paginate"),
OPT_ARGUMENT("no-pager", "no-pager"),
OPT_ARGUMENT("perf-dir", "perf-dir"),
OPT_ARGUMENT("work-tree", "work-tree"),
OPT_ARGUMENT("debugfs-dir", "debugfs-dir"),
OPT_ARGUMENT("buildid-dir", "buildid-dir"),
OPT_ARGUMENT("list-cmds", "list-cmds"),
OPT_ARGUMENT("list-opts", "list-opts"),
OPT_ARGUMENT("debug", "debug"),
OPT_END()
};
static int handle_options(const char ***argv, int *argc, int *envchanged) static int handle_options(const char ***argv, int *argc, int *envchanged)
{ {
int handled = 0; int handled = 0;
...@@ -225,6 +243,15 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) ...@@ -225,6 +243,15 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
} }
putchar('\n'); putchar('\n');
exit(0); exit(0);
} else if (!strcmp(cmd, "--list-opts")) {
unsigned int i;
for (i = 0; i < ARRAY_SIZE(options)-1; i++) {
struct option *p = options+i;
printf("--%s ", p->long_name);
}
putchar('\n');
exit(0);
} else if (!strcmp(cmd, "--debug")) { } else if (!strcmp(cmd, "--debug")) {
if (*argc < 2) { if (*argc < 2) {
fprintf(stderr, "No variable specified for --debug.\n"); fprintf(stderr, "No variable specified for --debug.\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment