diff options
author | Tobia Tesan | 2016-02-29 15:48:59 +0100 |
---|---|---|
committer | Tobia Tesan | 2016-03-01 20:40:45 +0100 |
commit | d5d25b0e89faebe4b1c5961d7b1ab872339e4a03 (patch) | |
tree | 1495571d94a38311e70f125ac9d561e3a09b58b4 | |
parent | dae732814c7c368f74f09174080e9bdd610982d2 (diff) | |
download | scummvm-rg350-d5d25b0e89faebe4b1c5961d7b1ab872339e4a03.tar.gz scummvm-rg350-d5d25b0e89faebe4b1c5961d7b1ab872339e4a03.tar.bz2 scummvm-rg350-d5d25b0e89faebe4b1c5961d7b1ab872339e4a03.zip |
WINTERMUTE: Add print and set commands to debugger
-rw-r--r-- | engines/wintermute/debugger.cpp | 36 | ||||
-rw-r--r-- | engines/wintermute/debugger.h | 4 | ||||
-rw-r--r-- | engines/wintermute/debugger/debugger_controller.cpp | 65 | ||||
-rw-r--r-- | engines/wintermute/debugger/debugger_controller.h | 8 |
4 files changed, 113 insertions, 0 deletions
diff --git a/engines/wintermute/debugger.cpp b/engines/wintermute/debugger.cpp index 760a852c97..6a349c070f 100644 --- a/engines/wintermute/debugger.cpp +++ b/engines/wintermute/debugger.cpp @@ -46,6 +46,8 @@ Console::Console(WintermuteEngine *vm) : GUI::Debugger(), _engineRef(vm) { registerCmd(REMOVE_BREAKPOINT_CMD, WRAP_METHOD(Console, Cmd_RemoveBreakpoint)); registerCmd(DISABLE_BREAKPOINT_CMD, WRAP_METHOD(Console, Cmd_DisableBreakpoint)); registerCmd(ENABLE_BREAKPOINT_CMD, WRAP_METHOD(Console, Cmd_EnableBreakpoint)); + registerCmd(PRINT_CMD, WRAP_METHOD(Console, Cmd_Print)); + registerCmd(SET_CMD, WRAP_METHOD(Console, Cmd_Set)); registerCmd(INFO_CMD, WRAP_METHOD(Console, Cmd_Info)); registerCmd(SET_PATH_CMD, WRAP_METHOD(Console, Cmd_SourcePath)); registerCmd(TOP_CMD, WRAP_METHOD(Console, Cmd_Top)); @@ -194,6 +196,40 @@ bool Console::Cmd_List(int argc, const char **argv) { return true; } +bool Console::Cmd_Print(int argc, const char **argv) { + if (argc == 2) { + Error error = Error(SUCCESS, OK, 0); + Common::String temp = CONTROLLER->readValue(argv[1], &error); + if (error.getErrorLevel() == SUCCESS) { + debugPrintf("%s = %s \n", argv[1], temp.c_str()); + return true; + } else { + printError(argv[0], error); + return true; + } + } else { + printUsage(argv[0]); + return true; + } +} + + +bool Console::Cmd_Set(int argc, const char **argv) { + if (argc == 4 && !strncmp("=", argv[2], 1)) { + ScValue *val = nullptr; + Error error = CONTROLLER->setValue(argv[1], argv[3], val); + if (error.getErrorLevel() == SUCCESS) { + assert(val); + debugPrintf("%s = %s\n", argv[1], val->getString()); + } else { + printError(argv[0], error); + } + } else { + printUsage(argv[0]); + } + return true; +} + bool Console::Cmd_ShowFps(int argc, const char **argv) { if (argc == 2) { if (Common::String(argv[1]) == "true") { diff --git a/engines/wintermute/debugger.h b/engines/wintermute/debugger.h index 2e427d35db..542403c6ea 100644 --- a/engines/wintermute/debugger.h +++ b/engines/wintermute/debugger.h @@ -44,6 +44,8 @@ #define DISABLE_BREAKPOINT_CMD "disable" #define ENABLE_BREAKPOINT_CMD "enable" #define INFO_CMD "info" +#define SET_CMD "set" +#define PRINT_CMD "print" #define SET_PATH_CMD "set_path" #define TOP_CMD "top" @@ -78,6 +80,8 @@ public: * (activation record is popped) */ bool Cmd_Finish(int argc, const char **argv); + bool Cmd_Print(int argc, const char **argv); + bool Cmd_Set(int argc, const char **argv); // Breakpoints bool Cmd_AddBreakpoint(int argc, const char **argv); bool Cmd_RemoveBreakpoint(int argc, const char **argv); diff --git a/engines/wintermute/debugger/debugger_controller.cpp b/engines/wintermute/debugger/debugger_controller.cpp index c7c88be034..6fe49f2af2 100644 --- a/engines/wintermute/debugger/debugger_controller.cpp +++ b/engines/wintermute/debugger/debugger_controller.cpp @@ -142,6 +142,71 @@ void DebuggerController::clear() { _lastLine = -1; } +Common::String DebuggerController::readValue(const Common::String &name, Error *error) { + if (!_lastScript) { + delete error; + error = new Error(ERROR, NOT_ALLOWED); + return Common::String(); + } + char cstr[256]; // TODO not pretty + Common::strlcpy(cstr, name.c_str(), name.size() + 1); + cstr[255] = '\0'; // We 0-terminate it just in case it's longer than 255. + return _lastScript->resolveName(cstr)->getString(); +} + +Error DebuggerController::setValue(const Common::String &name, const Common::String &value, ScValue *&var) { + if (!_lastScript) { + return Error(ERROR, NOT_ALLOWED); + } + + Common::String trimmed = value; + trimmed.trim(); + char cstr[256]; + Common::strlcpy(cstr, name.c_str(), name.size() + 1); // TODO not pretty + + var = _lastScript->getVar(cstr); + if (var->_type == VAL_INT) { + char *endptr; + int res = strtol(trimmed.c_str(), &endptr, 10); // TODO: Hex too? + if (endptr == trimmed.c_str()) { + return Error(ERROR, PARSE_ERROR); + } else if (endptr == trimmed.c_str() + trimmed.size()) { + // We've parsed all of it, have we? + var->setInt(res); + } else { + assert(false); + return Error(ERROR, PARSE_ERROR); + // Something funny happened here. + } + } else if (var->_type == VAL_FLOAT) { + char *endptr; + float res = (float)strtod(trimmed.c_str(), &endptr); + if (endptr == trimmed.c_str()) { + return Error(ERROR, PARSE_ERROR); + } else if (endptr == trimmed.c_str() + trimmed.size()) { + // We've parsed all of it, have we? + var->setFloat(res); + } else { + return Error(ERROR, PARSE_ERROR); + assert(false); + // Something funny happened here. + } + } else if (var->_type == VAL_BOOL) { + Common::String str = Common::String(trimmed); + bool valAsBool; + if (Common::parseBool(trimmed, valAsBool)) { + var->setBool(valAsBool); + } else { + return Error(ERROR, PARSE_ERROR); + } + } else if (var->_type == VAL_STRING) { + var->setString(trimmed); + } else { + return Error(ERROR, NOT_YET_IMPLEMENTED); + } + return Error(SUCCESS, OK); +} + void DebuggerController::showFps(bool show) { _engine->_game->setShowFPS(show); } diff --git a/engines/wintermute/debugger/debugger_controller.h b/engines/wintermute/debugger/debugger_controller.h index 7af2a039b1..87b4945f27 100644 --- a/engines/wintermute/debugger/debugger_controller.h +++ b/engines/wintermute/debugger/debugger_controller.h @@ -83,6 +83,14 @@ public: * @brief continue execution and don't step until the current activation record is popped */ Error stepFinish(); + /** + * @brief read value for a variable accessible from within the current scope. + */ + Common::String readValue(const Common::String &name, Error *error); + /** + * @brief set value for a variable accessible from within the current scope. + */ + Error setValue(const Common::String &name, const Common::String &value, ScValue*&var); Error setSourcePath(const Common::String &sourcePath); Common::String getSourcePath() const; Listing *getListing(Error* &err); |