#include "shell.h" #include "parser.h" #include "commands.h" #include "theme.h" #include using Selections = std::vector>; static bool is_selected(uint32_t address, Selections const &sel) { for(auto &p: sel) { if(address >= p.first && address < p.first + p.second) return true; } return false; } void _h_hexdump(Session &session, Range r, Selections sel) { if(!session.current_space) return; VirtualSpace &v = *session.current_space; uint32_t start = r.start & ~0xf; uint32_t end = (r.end + 15) & ~0xf; for(uint32_t pos = start; pos != end; pos += 16) { fmt::print(theme(3), " 0x{:08x} ", pos); /* Hexdump */ for(int offset = 0; offset < 16; offset++) { if(!(offset % 4)) fmt::print(" "); uint32_t addr = pos + offset; if(addr < r.start || addr >= r.end) { fmt::print(" "); } else if(is_selected(addr, sel)) { fmt::print(theme(13), "{:02x}", v.read_u8(addr).value); } else { fmt::print("{:02x}", v.read_u8(addr).value); } } /* ASCII */ fmt::print(" "); for(int offset = 0; offset < 16; offset++) { if(!(offset % 4)) fmt::print(" "); uint32_t addr = pos + offset; if(addr < r.start || addr >= r.end) { fmt::print(" "); } else { int c = v.read_u8(addr); fmt::print(theme(11), "{:c}", isprint(c) ? c : '.'); } } fmt::print("\n"); } } //--- // h //--- static Range parse_h(Session &session, Parser &parser) { Range r = parser.range(session.current_space, 0, 128); parser.end(); return r; } void _h(Session &session, Range r) { _h_hexdump(session, r, {}); } static ShellCommand _h_cmd( "h", [](Session &s, Parser &p) { _h(s, parse_h(s, p)); }, [](Session &s, Parser &p) { parse_h(s, p); }, "Hexdump", R"( h (
|) Dumps the specified range into hexadecimal and ASCII representations. When an address is specified, defaults to a length of 128. )");