123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- #define _GNU_SOURCE
- #include <stdio.h>
- #undef _GNU_SOURCE
- #include <stdlib.h>
- #include <newt.h>
- #include <sys/ttydefaults.h>
- #include "cache.h"
- #include "hist.h"
- #include "session.h"
- #include "sort.h"
- #include "symbol.h"
- static void newt_form__set_exit_keys(newtComponent self)
- {
- newtFormAddHotKey(self, NEWT_KEY_ESCAPE);
- newtFormAddHotKey(self, 'Q');
- newtFormAddHotKey(self, 'q');
- newtFormAddHotKey(self, CTRL('c'));
- }
- static newtComponent newt_form__new(void)
- {
- newtComponent self = newtForm(NULL, NULL, 0);
- if (self)
- newt_form__set_exit_keys(self);
- return self;
- }
- static size_t hist_entry__append_browser(struct hist_entry *self,
- newtComponent listbox, u64 total)
- {
- char bf[1024];
- size_t len;
- FILE *fp;
- if (symbol_conf.exclude_other && !self->parent)
- return 0;
- fp = fmemopen(bf, sizeof(bf), "w");
- if (fp == NULL)
- return 0;
- len = hist_entry__fprintf(self, NULL, false, 0, fp, total);
- fclose(fp);
- newtListboxAppendEntry(listbox, bf, self);
- return len;
- }
- static void hist_entry__annotate_browser(struct hist_entry *self)
- {
- FILE *fp;
- int cols, rows;
- newtComponent form, listbox;
- struct newtExitStruct es;
- char *str;
- size_t line_len, max_line_len = 0;
- size_t max_usable_width;
- char *line = NULL;
- if (self->sym == NULL)
- return;
- if (asprintf(&str, "perf annotate %s 2>&1 | expand", self->sym->name) < 0)
- return;
- fp = popen(str, "r");
- if (fp == NULL)
- goto out_free_str;
- newtPushHelpLine("Press ESC to exit");
- newtGetScreenSize(&cols, &rows);
- listbox = newtListbox(0, 0, rows - 5, NEWT_FLAG_SCROLL);
- while (!feof(fp)) {
- if (getline(&line, &line_len, fp) < 0 || !line_len)
- break;
- while (line_len != 0 && isspace(line[line_len - 1]))
- line[--line_len] = '\0';
- if (line_len > max_line_len)
- max_line_len = line_len;
- newtListboxAppendEntry(listbox, line, NULL);
- }
- fclose(fp);
- free(line);
- max_usable_width = cols - 22;
- if (max_line_len > max_usable_width)
- max_line_len = max_usable_width;
- newtListboxSetWidth(listbox, max_line_len);
- newtCenteredWindow(max_line_len + 2, rows - 5, self->sym->name);
- form = newt_form__new();
- newtFormAddComponents(form, listbox, NULL);
- newtFormRun(form, &es);
- newtFormDestroy(form);
- newtPopWindow();
- newtPopHelpLine();
- out_free_str:
- free(str);
- }
- void perf_session__browse_hists(struct rb_root *hists, u64 session_total,
- const char *helpline)
- {
- struct sort_entry *se;
- struct rb_node *nd;
- unsigned int width;
- char *col_width = symbol_conf.col_width_list_str;
- int rows;
- size_t max_len = 0;
- char str[1024];
- newtComponent form, listbox;
- struct newtExitStruct es;
- snprintf(str, sizeof(str), "Samples: %Ld", session_total);
- newtDrawRootText(0, 0, str);
- newtPushHelpLine(helpline);
- newtGetScreenSize(NULL, &rows);
- form = newt_form__new();
- listbox = newtListbox(1, 1, rows - 2, (NEWT_FLAG_SCROLL |
- NEWT_FLAG_BORDER |
- NEWT_FLAG_RETURNEXIT));
- list_for_each_entry(se, &hist_entry__sort_list, list) {
- if (se->elide)
- continue;
- width = strlen(se->header);
- if (se->width) {
- if (symbol_conf.col_width_list_str) {
- if (col_width) {
- *se->width = atoi(col_width);
- col_width = strchr(col_width, ',');
- if (col_width)
- ++col_width;
- }
- }
- *se->width = max(*se->width, width);
- }
- }
- for (nd = rb_first(hists); nd; nd = rb_next(nd)) {
- struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
- size_t len = hist_entry__append_browser(h, listbox, session_total);
- if (len > max_len)
- max_len = len;
- }
- newtListboxSetWidth(listbox, max_len);
- newtFormAddComponents(form, listbox, NULL);
- while (1) {
- struct hist_entry *selection;
- newtFormRun(form, &es);
- if (es.reason == NEWT_EXIT_HOTKEY)
- break;
- selection = newtListboxGetCurrent(listbox);
- hist_entry__annotate_browser(selection);
- }
- newtFormDestroy(form);
- }
- int browser__show_help(const char *format, va_list ap)
- {
- int ret;
- static int backlog;
- static char msg[1024];
- ret = vsnprintf(msg + backlog, sizeof(msg) - backlog, format, ap);
- backlog += ret;
- if (msg[backlog - 1] == '\n') {
- newtPopHelpLine();
- newtPushHelpLine(msg);
- newtRefresh();
- backlog = 0;
- }
- return ret;
- }
- void setup_browser(void)
- {
- if (!isatty(1))
- return;
- use_browser = true;
- newtInit();
- newtCls();
- newtPushHelpLine(" ");
- }
- void exit_browser(void)
- {
- if (use_browser)
- newtFinished();
- }
|