Commit-ID:  7335399a6a4bead9ef8b59ce7d811fc4e99ca98c
Gitweb:     http://git.kernel.org/tip/7335399a6a4bead9ef8b59ce7d811fc4e99ca98c
Author:     Yunlong Song <yunlong.s...@huawei.com>
AuthorDate: Fri, 27 Feb 2015 18:21:31 +0800
Committer:  Arnaldo Carvalho de Melo <a...@redhat.com>
CommitDate: Fri, 27 Feb 2015 15:52:28 -0300

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.s...@huawei.com>
Tested-by: Arnaldo Carvalho de Melo <a...@redhat.com>
Cc: Ingo Molnar <mi...@redhat.com>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Wang Nan <wangn...@huawei.com>
Link: 
http://lkml.kernel.org/r/1425032491-20224-8-git-send-email-yunlong.s...@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <a...@redhat.com>
---
 tools/perf/perf-completion.sh |  6 ++----
 tools/perf/perf.c             | 27 +++++++++++++++++++++++++++
 2 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/tools/perf/perf-completion.sh b/tools/perf/perf-completion.sh
index 3356984..c2595e9 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 3df2665..b857fcb 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");
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to