#include "../../util/util.h"
#include "../browser.h"
#include "../helpline.h"
#include "../libslang.h"
#include "../ui.h"
#include "../util.h"
#include "../../util/annotate.h"
#include "../../util/hist.h"
#include "../../util/sort.h"
#include "../../util/symbol.h"
#include <pthread.h>
#include <newt.h>
struct browser_disasm_line {
struct rb_node rb_node;
double percent;
u32 idx;
int idx_asm;
int jump_sources;
};
static struct annotate_browser_opt {
bool hide_src_code,
use_offset,
jump_arrows,
show_nr_jumps;
} annotate_browser__opts = {
.use_offset = true,
.jump_arrows = true,
};
struct annotate_browser {
struct ui_browser b;
struct rb_root entries;
struct rb_node *curr_hot;
struct disasm_line *selection;
struct disasm_line **offsets;
u64 start;
int nr_asm_entries;
int nr_entries;
int max_jump_sources;
int nr_jumps;
bool searching_backwards;
u8 addr_width;
u8 jumps_width;
u8 target_width;
u8 min_addr_width;
u8 max_addr_width;
char search_bf[128];
};
static inline struct browser_disasm_line *disasm_line__browser(struct disasm_line *dl)
{
return (struct browser_disasm_line *)(dl + 1);
}
static bool disasm_line__filter(struct ui_browser *browser __used, void *entry)
{
if (annotate_browser__opts.hide_src_code) {
struct disasm_line *dl = list_entry(entry, struct disasm_line, node);
return dl->offset == -1;
}
return false;
}
static int annotate_browser__jumps_percent_color(struct annotate_browser *browser,
int nr, bool current)
{
if (current && (!browser->b.use_navkeypressed || browser->b.navkeypressed))
return HE_COLORSET_SELECTED;
if (nr == browser->max_jump_sources)
return HE_COLORSET_TOP;
if (nr > 1)
return HE_COLORSET_MEDIUM;
return HE_COLORSET_NORMAL;
}
static int annotate_browser__set_jumps_percent_color(struct annotate_browser *browser,
int nr, bool current)
{
int color = annotate_browser__jumps_percent_color(browser, nr, current);
return ui_browser__set_color(&browser->b, color);
}
static void annotate_browser__write(struct ui_browser *self, void *entry, int row)
{
struct annotate_browser *ab = container_of(self, struct annotate_browser, b);
struct disasm_line *dl = list_entry(entry, struct disasm_line, node);
struct browser_disasm_line *bdl = disasm_line__browser(dl);
bool current_entry = ui_browser__is_current_entry(self, row);
bool change_color = (!annotate_browser__opts.hide_src_code &&
(!current_entry || (self->use_navkeypressed &&
!self->navkeypressed)));
int width = self->width, printed;
char bf[256];
if (dl->offset != -1 && bdl->percent != 0.0) {
ui_browser__set_percent_color(self, bdl->percent, current_entry);
slsmg_printf("%6.2f ", bdl->percent);
} else {
ui_browser__set_percent_color(self, 0, current_entry);
slsmg_write_nstring(" ", 7);
}
SLsmg_write_char(' ');
/* The scroll bar isn't being used */
if (!self->navkeypressed)
width += 1;
if (!*dl->line)
slsmg_write_nstring(" ", width - 7);
else if (dl->offset == -1) {
printed = scnprintf(bf, sizeof(bf), "%*s ",
ab->addr_width, " ");
slsmg_write_nstring(bf, printed);
slsmg_write_nstring(dl->line, width - printed - 6);
} else {
u64 addr = dl->offset;
int color = -1;
if (!annotate_browser__opts.use_offset)
addr += ab->start;
if (!annotate_browser__opts.use_offset) {
printed = scnprintf(bf, sizeof(bf), "%" PRIx64 ": ", addr);
} else {
if (bdl->jump_sources) {
if (annotate_browser__opts.show_nr_jumps) {
int prev;
printed = scnprintf(bf, sizeof(bf), "%*d ",
ab->jumps_width,
bdl->jump_sources);
prev = annotate_browser__set_jumps_percent_color(ab,