#ifndef _SDB_SDB_HEADER_FILE_ #define _SDB_SDB_HEADER_FILE_ #include <components.hpp> #include <console.hpp> #include <memory> #include <stdexcept> #include <string> #include <trm_interface.hpp> #include <types.h> namespace cr = CppReadline; using ret = cr::Console::ReturnCode; namespace SDB { enum SDBStatus { SDB_SUCCESS, SDB_EBREAK = 2, SDB_WRONG_ARGUMENT, SDB_DIFFTEST_FAILED }; class SDBHandlers; struct Handler { const std::vector<const char *> names; // cr::Console::CommandFunction f; std::function<int(SDBHandlers *, const cr::Console::Arguments &)> f; }; class SDBHandlers { private: const TrmInterface &funcs; std::vector<Handler> all_handlers = { Handler{{"c", "continue"}, &SDBHandlers::cmd_continue}, Handler{{"si", "step-instruction"}, &SDBHandlers::cmd_step}, Handler{{"info-r"}, &SDBHandlers::cmd_info_registers}, Handler{{"p", "print"}, &SDBHandlers::cmd_print}, Handler{{"disas", "disassemble"}, &SDBHandlers::cmd_disassemble}, }; int cmd_continue(const cr::Console::Arguments &input); int cmd_step(const std::vector<std::string> &input); int cmd_info_registers(const std::vector<std::string> &input); int cmd_print(const std::vector<std::string> &input); int cmd_disassemble(const std::vector<std::string> &input); int exec_catch(uint64_t); public: SDBHandlers(const TrmInterface &funcs) : funcs(funcs){}; void register_handlers(cr::Console *c); }; class SDB { private: std::unique_ptr<CppReadline::Console> c; const TrmInterface &funcs; SDBHandlers handlers; public: SDB(const TrmInterface &funcs, std::string const &greeting = "\033[1;34m(npc)\033[0m ") : handlers(SDBHandlers{funcs}), funcs(funcs) { c = std::make_unique<CppReadline::Console>(greeting); handlers.register_handlers(c.get()); }; int main_loop() { int ret_code; funcs.init(0); std::vector<std::string> step_commands{"c", "continue", "si", "step-instruction"}; do { ret_code = c->readLine(); // We can also change the prompt based on last return value: if (ret_code == SDB_SUCCESS || ret_code == SDB_EBREAK) c->setGreeting("\033[1;34m(npc)\033[0m "); else c->setGreeting("\033[1;31m(npc)\033[0m "); switch (ret_code) { case SDB_EBREAK: { std::cout << "\033[1;31m=== ebreak ===\033[0m" << std::endl; c->removeCommands(step_commands); break; } case SDB_WRONG_ARGUMENT: { std::cout << "Wrong argument(s) is given to command handler\n"; break; } } } while (ret_code != ret::Quit); return 0; } }; } // namespace SDB #endif