diff options
-rw-r--r-- | tools/perf/util/ui/browsers/annotate.c | 149 |
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, ¬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) |