#ifndef _SDB_SDB_HEADER_FILE_ #define _SDB_SDB_HEADER_FILE_ #include #include #include #include #include #include namespace cr = CppReadline; using ret = cr::Console::ReturnCode; namespace SDB { enum SDBStatus { SDB_SUCCESS, SDB_WRONG_ARGUMENT, }; struct Handler { const std::vector names; cr::Console::CommandFunction f; }; template class _SDBHandlers { using CPUState = CPUStateBase; private: std::vector all_handlers; public: static CPUState cpu; private: static _SDBHandlers *instance; static int cmd_continue(const cr::Console::Arguments &input); static int cmd_step(const std::vector &input); static int cmd_info_registers(const std::vector &input); static int cmd_print(const std::vector &input); _SDBHandlers(std::vector all_handlers) : all_handlers(all_handlers){}; public: _SDBHandlers(const _SDBHandlers &) = delete; _SDBHandlers operator=(const _SDBHandlers &) = delete; static _SDBHandlers *getInstance() { if (instance == nullptr) { std::vector all_handlers{ Handler{{"c", "continue"}, &_SDBHandlers::cmd_continue}, Handler{{"si", "step-instruction"}, &_SDBHandlers::cmd_step}, }; instance = new _SDBHandlers(all_handlers); } return instance; } void registerHandlers(cr::Console *c); }; template _SDBHandlers *_SDBHandlers::instance = nullptr; template CPUState _SDBHandlers::cpu = CPUState(); template int _SDBHandlers::cmd_continue(const cr::Console::Arguments &input) { if (input.size() > 1) return SDB_WRONG_ARGUMENT; funcs.exec(-1); return SDB_SUCCESS; } template int _SDBHandlers::cmd_step(const std::vector &input) { if (input.size() > 2) { return SDB_WRONG_ARGUMENT; } uint64_t step_count = input.size() == 2 ? std::stoull(input[1]) : 1; funcs.exec(step_count); return SDB_SUCCESS; } template int _SDBHandlers::cmd_info_registers( const std::vector &input) { if (input.size() > 1) return SDB_WRONG_ARGUMENT; std::cout << _SDBHandlers::getInstance()->cpu << std::endl; return SDB_SUCCESS; } template int _SDBHandlers::cmd_print(const std::vector &input) { exit(1); } template void _SDBHandlers::registerHandlers(cr::Console *c) { for (auto &h : this->all_handlers) { for (auto &name : h.names) { c->registerCommand(name, h.f); } } } template class SDB { private: std::unique_ptr c; using SDBHandlers = _SDBHandlers; public: SDB(std::string const &greeting = "\033[1;34m(npc)\033[0m ") { c = std::make_unique(greeting); SDBHandlers::getInstance()->registerHandlers(c.get()); }; word_t reg_str2val(const char *name, bool *success) { try { *success = true; return SDBHandlers::getInstance()->cpu.at(name); } catch (std::runtime_error) { *success = false; return 0; } } int main_loop() { int retCode; do { retCode = c->readLine(); // We can also change the prompt based on last return value: if (retCode == ret::Ok) c->setGreeting("\033[1;34m(npc)\033[0m "); else c->setGreeting("\033[1;31m(npc)\033[0m "); if (retCode == SDB_WRONG_ARGUMENT) { std::cout << "Wrong argument give to command\n"; } } while (retCode != ret::Quit); return 0; } }; } // namespace SDB #endif