summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYunlong Song <yunlong.song@huawei.com>2015-02-27 18:21:31 +0800
committerArnaldo Carvalho de Melo <acme@redhat.com>2015-02-27 15:52:28 -0300
commit7335399a6a4bead9ef8b59ce7d811fc4e99ca98c (patch)
tree7c42d2c153742b6ef7568015f11b3f44e656b546
parent5ef803ee02d67ad0b49f357cb7feb7d5e6b0015d (diff)
downloadlinux-7335399a6a4bead9ef8b59ce7d811fc4e99ca98c.tar.gz
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>
-rw-r--r--tools/perf/perf-completion.sh6
-rw-r--r--tools/perf/perf.c27
2 files changed, 29 insertions, 4 deletions
diff --git a/tools/perf/perf-completion.sh b/tools/perf/perf-completion.sh
index 33569847fdcc..c2595e9bd69b 100644
--- a/tools/perf/perf-completion.sh
+++ b/tools/perf/perf-completion.sh
@@ -110,13 +110,11 @@ __perf_main ()
# List perf subcommands or long options
if [ $cword -eq 1 ]; then
if [[ $cur == --* ]]; then
- __perfcomp '--help --version \
- --exec-path --html-path --paginate --no-pager \
- --perf-dir --work-tree --debugfs-dir' -- "$cur"
+ cmds=$($cmd --list-opts)
else
cmds=$($cmd --list-cmds)
- __perfcomp "$cmds" "$cur"
fi
+ __perfcomp "$cmds" "$cur"
# List possible events for -e option
elif [[ $prev == "-e" && "${words[1]}" == @(record|stat|top) ]]; then
evts=$($cmd list --raw-dump)
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 3df2665022be..b857fcbd00cf 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -13,6 +13,7 @@
#include "util/quote.h"
#include "util/run-command.h"
#include "util/parse-events.h"
+#include "util/parse-options.h"
#include "util/debug.h"
#include <api/fs/debugfs.h>
#include <pthread.h>
@@ -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)
{
int handled = 0;
@@ -225,6 +243,15 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
}
putchar('\n');
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")) {
if (*argc < 2) {
fprintf(stderr, "No variable specified for --debug.\n");