diff options
Diffstat (limited to 'tools/perf/util/newt.c')
-rw-r--r-- | tools/perf/util/newt.c | 109 |
1 files changed, 100 insertions, 9 deletions
diff --git a/tools/perf/util/newt.c b/tools/perf/util/newt.c index f98a2406dd8..e2deae0704d 100644 --- a/tools/perf/util/newt.c +++ b/tools/perf/util/newt.c @@ -128,6 +128,39 @@ static void ui_helpline__puts(const char *msg) ui_helpline__push(msg); } +static int ui_entry__read(const char *title, char *bf, size_t size, int width) +{ + struct newtExitStruct es; + newtComponent form, entry; + const char *result; + int err = -1; + + newtCenteredWindow(width, 1, title); + form = newtForm(NULL, NULL, 0); + if (form == NULL) + return -1; + + entry = newtEntry(0, 0, "0x", width, &result, NEWT_FLAG_SCROLL); + if (entry == NULL) + goto out_free_form; + + newtFormAddComponent(form, entry); + newtFormAddHotKey(form, NEWT_KEY_ENTER); + newtFormAddHotKey(form, NEWT_KEY_ESCAPE); + newtFormAddHotKey(form, NEWT_KEY_LEFT); + newtFormAddHotKey(form, CTRL('c')); + newtFormRun(form, &es); + + if (result != NULL) { + strncpy(bf, result, size); + err = 0; + } +out_free_form: + newtPopWindow(); + newtFormDestroy(form); + return 0; +} + static char browser__last_msg[1024]; int browser__show_help(const char *format, va_list ap) @@ -670,6 +703,67 @@ static void map_browser__write(struct ui_browser *self, void *nd, int row) slsmg_write_nstring(sym->name, mb->namelen); } +/* FIXME uber-kludgy, see comment on cmd_report... */ +static u32 *symbol__browser_index(struct symbol *self) +{ + return ((void *)self) - sizeof(struct rb_node) - sizeof(u32); +} + +static int map_browser__search(struct map_browser *self) +{ + char target[512]; + struct symbol *sym; + int err = ui_entry__read("Search by name/addr", target, sizeof(target), 40); + + if (err) + return err; + + if (target[0] == '0' && tolower(target[1]) == 'x') { + u64 addr = strtoull(target, NULL, 16); + sym = map__find_symbol(self->map, addr, NULL); + } else + sym = map__find_symbol_by_name(self->map, target, NULL); + + if (sym != NULL) { + u32 *idx = symbol__browser_index(sym); + + self->b.first_visible_entry = &sym->rb_node; + self->b.index = self->b.first_visible_entry_idx = *idx; + } else + ui_helpline__fpush("%s not found!", target); + + return 0; +} + +static int map_browser__run(struct map_browser *self, struct newtExitStruct *es) +{ + if (ui_browser__show(&self->b, self->map->dso->long_name) < 0) + return -1; + + ui_helpline__fpush("Press <- or ESC to exit, %s / to search", + verbose ? "" : "restart with -v to use"); + newtFormAddHotKey(self->b.form, NEWT_KEY_LEFT); + newtFormAddHotKey(self->b.form, NEWT_KEY_ENTER); + if (verbose) + newtFormAddHotKey(self->b.form, '/'); + + while (1) { + ui_browser__run(&self->b, es); + + if (es->reason != NEWT_EXIT_HOTKEY) + break; + if (verbose && es->u.key == '/') + map_browser__search(self); + else + break; + } + + newtFormDestroy(self->b.form); + newtPopWindow(); + ui_helpline__pop(); + return 0; +} + static int map__browse(struct map *self) { struct map_browser mb = { @@ -679,14 +773,12 @@ static int map__browse(struct map *self) .seek = ui_browser__rb_tree_seek, .write = map_browser__write, }, + .map = self, }; struct newtExitStruct es; struct rb_node *nd; char tmp[BITS_PER_LONG / 4]; u64 maxaddr = 0; - int ret; - - ui_helpline__push("Press <- or ESC to exit"); for (nd = rb_first(mb.b.entries); nd; nd = rb_next(nd)) { struct symbol *pos = rb_entry(nd, struct symbol, rb_node); @@ -695,17 +787,16 @@ static int map__browse(struct map *self) mb.namelen = pos->namelen; if (maxaddr < pos->end) maxaddr = pos->end; + if (verbose) { + u32 *idx = symbol__browser_index(pos); + *idx = mb.b.nr_entries; + } ++mb.b.nr_entries; } mb.addrlen = snprintf(tmp, sizeof(tmp), "%llx", maxaddr); mb.b.width += mb.addrlen * 2 + 4 + mb.namelen; - ui_browser__show(&mb.b, self->dso->long_name); - ret = ui_browser__run(&mb.b, &es); - newtFormDestroy(mb.b.form); - newtPopWindow(); - ui_helpline__pop(); - return ret; + return map_browser__run(&mb, &es); } /* -------------------------------------------------------------------- */ |