Fix some memory leak complaints from Valgrind
[lsnes.git] / src / core / disassemble.cpp
blobb3c695cd6d318c1d4c1b5ac825b47b68dc1e23e9
1 #include "core/command.hpp"
2 #include "interface/disassembler.hpp"
3 #include "library/hex.hpp"
4 #include "library/minmax.hpp"
5 #include "core/memorymanip.hpp"
6 #include "core/window.hpp"
7 #include "library/string.hpp"
8 #include <iomanip>
9 #include <fstream>
10 #include <iostream>
12 namespace
14 struct dres
16 uint64_t addr;
17 uint64_t len;
18 std::string disasm;
21 command::fnptr<const std::string&> disassemble(lsnes_cmd, "disassemble", "Disassemble code",
22 "Syntax: disassemble <kind> <addr> [<count>] [to <filename>]\nDisassemble code\n",
23 [](const std::string& t) throw(std::bad_alloc, std::runtime_error) {
24 regex_results r = regex("([^ \t]+)[ \t]+([0-9]+|0x[0-9A-Fa-f]+)([ \t]+([0-9]+))?"
25 "([ \t]+to[ \t]+(.+))?", t);
26 if(!r) {
27 messages << "Syntax: disassemble <kind> <addr> [<count>] [to <filename>]" << std::endl;
28 return;
30 std::string kind = r[1];
31 uint64_t addr = parse_value<uint64_t>(r[2]);
32 uint64_t count = 1;
33 if(r[4] != "")
34 count = parse_value<uint64_t>(r[4]);
35 std::string file;
36 if(r[6] != "")
37 file = r[6];
38 std::list<dres> result;
39 disassembler* d;
40 try {
41 d = &disassembler::byname(kind);
42 } catch(std::exception& e) {
43 messages << "Can't find such disassembler" << std::endl;
44 return;
46 uint64_t laddr = addr;
47 uint64_t longest = 0;
48 for(uint64_t i = 1; i <= count; i++) {
49 uint64_t bytes = 0;
50 dres x;
51 x.addr = laddr;
52 x.disasm = d->disassemble(laddr, [&bytes, laddr]() -> unsigned char {
53 return lsnes_memory.read<uint8_t>(laddr + bytes++);
54 });
55 x.len = bytes;
56 result.push_back(x);
57 longest = max(longest, bytes);
58 laddr += bytes;
60 std::ostream* strm = &messages.getstream();
61 if(file != "") {
62 strm = new std::ofstream(file);
63 if(!*strm) {
64 messages << "Can't open output file" << std::endl;
65 return;
68 for(auto i : result) {
69 std::vector<unsigned char> tmp;
70 tmp.resize(i.len);
71 lsnes_memory.read_range(i.addr, &tmp[0], i.len);
72 std::string l = hex::to(i.addr) + " " + hex::b_to(&tmp[0], i.len) + " " + i.disasm;
73 (*strm) << l << std::endl;
75 if(file != "")
76 delete strm;
77 });