Skip to content

Commit

Permalink
WINTERMUTE: Add print and set commands to debugger
Browse files Browse the repository at this point in the history
  • Loading branch information
tobiatesan committed Mar 1, 2016
1 parent dae7328 commit d5d25b0
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 0 deletions.
36 changes: 36 additions & 0 deletions engines/wintermute/debugger.cpp
Expand Up @@ -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));
Expand Down Expand Up @@ -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") {
Expand Down
4 changes: 4 additions & 0 deletions engines/wintermute/debugger.h
Expand Up @@ -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"

Expand Down Expand Up @@ -78,6 +80,8 @@ class Console : public GUI::Debugger {
* (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);
Expand Down
65 changes: 65 additions & 0 deletions engines/wintermute/debugger/debugger_controller.cpp
Expand Up @@ -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);
}
Expand Down
8 changes: 8 additions & 0 deletions engines/wintermute/debugger/debugger_controller.h
Expand Up @@ -83,6 +83,14 @@ class DebuggerController : public ScriptMonitor {
* @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);
Expand Down

0 comments on commit d5d25b0

Please sign in to comment.