aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2012-04-07 17:10:30 -0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2012-04-07 17:37:22 -0300
commitd3d1f61acf62204bb7b2b4509329247bffaedd7c (patch)
treef7befbf4b661b4266a22e83ab1d7cd15095a7d1b
parentcc68628096b813010f30f69fcf7d1832d18fa767 (diff)
perf annotate browser: string search: /?n
Using the same keystrokes as vim: / = search forward n = search next forward/backwards ? = search backwards Still needs to continue from start/end when not found, use HOME + / or END + ? for now. At some point we need a keybindings file to support ones favourite mode, erm, like EMACS, etc. Also we now need a 'h' window with all these keybindings. Requested-by: Andi Kleen <andi@firstfloor.org> Cc: Andi Kleen <andi@firstfloor.org> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-rv30xj2i258n0gwkzlu0c0bc@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/util/ui/browsers/annotate.c149
1 files changed, 148 insertions, 1 deletions
diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c
index 752d8d0e480..c2cfeed3af1 100644
--- a/tools/perf/util/ui/browsers/annotate.c
+++ b/tools/perf/util/ui/browsers/annotate.c
@@ -21,6 +21,8 @@ struct annotate_browser {
int nr_entries;
bool hide_src_code;
bool use_offset;
+ bool searching_backwards;
+ char search_bf[128];
};
struct objdump_line_rb_node {
@@ -176,6 +178,7 @@ static void annotate_browser__set_top(struct annotate_browser *self,
}
self->b.top = pos;
+ self->b.navkeypressed = true;
}
static void annotate_browser__set_rb_top(struct annotate_browser *browser,
@@ -354,6 +357,132 @@ static bool annotate_browser__jump(struct annotate_browser *browser)
return true;
}
+static struct objdump_line *
+ annotate_browser__find_string(struct annotate_browser *browser,
+ char *s, s64 *idx)
+{
+ struct map_symbol *ms = browser->b.priv;
+ struct symbol *sym = ms->sym;
+ struct annotation *notes = symbol__annotation(sym);
+ struct objdump_line *pos = browser->selection;
+
+ *idx = browser->b.index;
+ list_for_each_entry_continue(pos, &notes->src->source, node) {
+ if (objdump_line__filter(&browser->b, &pos->node))
+ continue;
+
+ ++*idx;
+
+ if (pos->line && strstr(pos->line, s) != NULL)
+ return pos;
+ }
+
+ return NULL;
+}
+
+static bool __annotate_browser__search(struct annotate_browser *browser)
+{
+ struct objdump_line *line;
+ s64 idx;
+
+ line = annotate_browser__find_string(browser, browser->search_bf, &idx);
+ if (line == NULL) {
+ ui_helpline__puts("String not found!");
+ return false;
+ }
+
+ annotate_browser__set_top(browser, line, idx);
+ browser->searching_backwards = false;
+ return true;
+}
+
+static struct objdump_line *
+ annotate_browser__find_string_reverse(struct annotate_browser *browser,
+ char *s, s64 *idx)
+{
+ struct map_symbol *ms = browser->b.priv;
+ struct symbol *sym = ms->sym;
+ struct annotation *notes = symbol__annotation(sym);
+ struct objdump_line *pos = browser->selection;
+
+ *idx = browser->b.index;
+ list_for_each_entry_continue_reverse(pos, &notes->src->source, node) {
+ if (objdump_line__filter(&browser->b, &pos->node))
+ continue;
+
+ --*idx;
+
+ if (pos->line && strstr(pos->line, s) != NULL)
+ return pos;
+ }
+
+ return NULL;
+}
+
+static bool __annotate_browser__search_reverse(struct annotate_browser *browser)
+{
+ struct objdump_line *line;
+ s64 idx;
+
+ line = annotate_browser__find_string_reverse(browser, browser->search_bf, &idx);
+ if (line == NULL) {
+ ui_helpline__puts("String not found!");
+ return false;
+ }
+
+ annotate_browser__set_top(browser, line, idx);
+ browser->searching_backwards = true;
+ return true;
+}
+
+static bool annotate_browser__search_window(struct annotate_browser *browser,
+ int delay_secs)
+{
+ if (ui_browser__input_window("Search", "String: ", browser->search_bf,
+ "ENTER: OK, ESC: Cancel",
+ delay_secs * 2) != K_ENTER ||
+ !*browser->search_bf)
+ return false;
+
+ return true;
+}
+
+static bool annotate_browser__search(struct annotate_browser *browser, int delay_secs)
+{
+ if (annotate_browser__search_window(browser, delay_secs))
+ return __annotate_browser__search(browser);
+
+ return false;
+}
+
+static bool annotate_browser__continue_search(struct annotate_browser *browser,
+ int delay_secs)
+{
+ if (!*browser->search_bf)
+ return annotate_browser__search(browser, delay_secs);
+
+ return __annotate_browser__search(browser);
+}
+
+static bool annotate_browser__search_reverse(struct annotate_browser *browser,
+ int delay_secs)
+{
+ if (annotate_browser__search_window(browser, delay_secs))
+ return __annotate_browser__search_reverse(browser);
+
+ return false;
+}
+
+static
+bool annotate_browser__continue_search_reverse(struct annotate_browser *browser,
+ int delay_secs)
+{
+ if (!*browser->search_bf)
+ return annotate_browser__search_reverse(browser, delay_secs);
+
+ return __annotate_browser__search_reverse(browser);
+}
+
static int annotate_browser__run(struct annotate_browser *self, int evidx,
void(*timer)(void *arg),
void *arg, int delay_secs)
@@ -372,8 +501,10 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx,
annotate_browser__calc_percent(self, evidx);
- if (self->curr_hot)
+ if (self->curr_hot) {
annotate_browser__set_rb_top(self, self->curr_hot);
+ self->b.navkeypressed = false;
+ }
nd = self->curr_hot;
@@ -428,6 +559,22 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx,
case 'o':
self->use_offset = !self->use_offset;
continue;
+ case '/':
+ if (annotate_browser__search(self, delay_secs)) {
+show_help:
+ ui_helpline__puts(help);
+ }
+ continue;
+ case 'n':
+ if (self->searching_backwards ?
+ annotate_browser__continue_search_reverse(self, delay_secs) :
+ annotate_browser__continue_search(self, delay_secs))
+ goto show_help;
+ continue;
+ case '?':
+ if (annotate_browser__search_reverse(self, delay_secs))
+ goto show_help;
+ continue;
case K_ENTER:
case K_RIGHT:
if (self->selection == NULL)