From d3d1f61acf62204bb7b2b4509329247bffaedd7c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sat, 7 Apr 2012 17:10:30 -0300 Subject: 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 Cc: Andi Kleen Cc: David Ahern Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-rv30xj2i258n0gwkzlu0c0bc@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/ui/browsers/annotate.c | 149 ++++++++++++++++++++++++++++++++- 1 file changed, 148 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c index 752d8d0e480c..c2cfeed3af19 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, ¬es->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, ¬es->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) -- cgit v1.2.3