aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobia Tesan2016-02-29 15:48:59 +0100
committerTobia Tesan2016-03-01 20:40:45 +0100
commitd5d25b0e89faebe4b1c5961d7b1ab872339e4a03 (patch)
tree1495571d94a38311e70f125ac9d561e3a09b58b4
parentdae732814c7c368f74f09174080e9bdd610982d2 (diff)
downloadscummvm-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.cpp36
-rw-r--r--engines/wintermute/debugger.h4
-rw-r--r--engines/wintermute/debugger/debugger_controller.cpp65
-rw-r--r--engines/wintermute/debugger/debugger_controller.h8
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);