diff options
-rw-r--r-- | src/memview.c | 56 |
1 files changed, 48 insertions, 8 deletions
diff --git a/src/memview.c b/src/memview.c index c05b10c..bd22305 100644 --- a/src/memview.c +++ b/src/memview.c @@ -159,6 +159,8 @@ static struct { struct key last_key; struct mem_io io; + + uint8_t native_bits; } ctx = { .hexview.octects_per_group = 1 }; static const char* @@ -250,6 +252,22 @@ bytes_fits_screen(void) return bytes_fits_row() * (ctx.term.ws.h - 3); // 3 for top and bottom bars } +union selection { + char bytes[sizeof(uint64_t)]; + uint8_t u8; uint16_t u16; uint32_t u32; uint64_t u64; +}; + +static union selection +get_selection(void) +{ + union selection v = {0}; + const struct named_region *named = named_region_for_offset(ctx.hexview.offset, false); + const size_t start = named->region.start + ctx.hexview.scroll, off = ctx.hexview.offset - start; + const size_t dsz = (off < ctx.hexview.memory[0].mapped ? ctx.hexview.memory[0].mapped - off : 0); + memcpy(v.bytes, ctx.hexview.memory[0].data + off, (dsz > sizeof(v.bytes) ? sizeof(v.bytes) : dsz)); + return v; +} + static void screen_vnprintf(const size_t len, const char *fmt, va_list ap) { @@ -487,14 +505,7 @@ repaint_dynamic_areas(const bool full_repaint) screen_nprintf(ctx.term.ws.w, "%zx", ctx.hexview.offset); { - union { - char bytes[sizeof(uint64_t)]; - uint8_t u8; uint16_t u16; uint32_t u32; uint64_t u64; - } v = {0}; - - const size_t start = named->region.start + ctx.hexview.scroll, off = ctx.hexview.offset - start; - const size_t dsz = (off < ctx.hexview.memory[0].mapped ? ctx.hexview.memory[0].mapped - off : 0); - memcpy(v.bytes, ctx.hexview.memory[0].data + off, (dsz > sizeof(v.bytes) ? sizeof(v.bytes) : dsz)); + const union selection v = get_selection(); size_t strlen = snprintf(NULL, 0, "[%u] [%u] [%u] [%lu]", v.u8, v.u16, v.u32, v.u64); strlen = (strlen > ctx.term.ws.w ? ctx.term.ws.w : strlen); screen_cursor(ctx.term.ws.w / 2 - strlen / 2, ctx.term.cur.y); @@ -736,6 +747,19 @@ goto_offset(void *arg) } static void +follow(void *arg) +{ + (void)arg; + const union selection v = get_selection(); + switch (ctx.native_bits) { + case 64: ctx.hexview.offset = v.u64; break; + case 32: ctx.hexview.offset = v.u32; break; + case 16: ctx.hexview.offset = v.u16; break; + case 8: ctx.hexview.offset = v.u8; break; + } +} + +static void write_bytes(void *arg) { (void)arg; @@ -812,6 +836,18 @@ init(void) ); } +static uint8_t +bits_for_region(const struct region *region) +{ + if (region->end > (uint32_t)~0) + return 64; + else if (region->end > (uint16_t)~0) + return 32; + else if (region->end > (uint8_t)~0) + return 16; + return 8; +} + static void region_cb(const char *line, void *data) { @@ -825,6 +861,9 @@ region_cb(const char *line, void *data) if (!region_parse(&ctx.named[ctx.num_regions].region, line)) return; + if (bits_for_region(&ctx.named[ctx.num_regions].region) > ctx.native_bits) + ctx.native_bits = bits_for_region(&ctx.named[ctx.num_regions].region); + int region_len_without_name = strlen(line); sscanf(line, "%*s %*s %*s %*s %*s%n", ®ion_len_without_name); const char *base = basename(skip_ws(line + region_len_without_name)); @@ -878,6 +917,7 @@ main(int argc, char *argv[]) { .seq = { 0x1b, '[', 'C', 0 }, .fun = navigate, .arg = MOVE_RIGHT }, { .seq = { 0x1b, '[', 'D', 0 }, .fun = navigate, .arg = MOVE_LEFT }, { .seq = { 'o', 0 }, .fun = goto_offset }, + { .seq = { 'f', 0 }, .fun = follow }, { .seq = { 'w', 0 }, .fun = write_bytes }, }; |