aboutsummaryrefslogtreecommitdiff
path: root/engines/wintermute/debugger
diff options
context:
space:
mode:
Diffstat (limited to 'engines/wintermute/debugger')
-rw-r--r--engines/wintermute/debugger/breakpoint.cpp68
-rw-r--r--engines/wintermute/debugger/breakpoint.h58
-rw-r--r--engines/wintermute/debugger/debugger_controller.cpp325
-rw-r--r--engines/wintermute/debugger/debugger_controller.h119
-rw-r--r--engines/wintermute/debugger/error.cpp137
-rw-r--r--engines/wintermute/debugger/error.h73
-rw-r--r--engines/wintermute/debugger/listing.cpp46
-rw-r--r--engines/wintermute/debugger/listing.h64
-rw-r--r--engines/wintermute/debugger/listing_provider.h42
-rw-r--r--engines/wintermute/debugger/listing_providers/basic_source_listing_provider.cpp92
-rw-r--r--engines/wintermute/debugger/listing_providers/basic_source_listing_provider.h44
-rw-r--r--engines/wintermute/debugger/listing_providers/blank_listing.cpp38
-rw-r--r--engines/wintermute/debugger/listing_providers/blank_listing.h39
-rw-r--r--engines/wintermute/debugger/listing_providers/blank_listing_provider.cpp35
-rw-r--r--engines/wintermute/debugger/listing_providers/blank_listing_provider.h38
-rw-r--r--engines/wintermute/debugger/listing_providers/cached_source_listing_provider.cpp80
-rw-r--r--engines/wintermute/debugger/listing_providers/cached_source_listing_provider.h52
-rw-r--r--engines/wintermute/debugger/listing_providers/source_listing.cpp57
-rw-r--r--engines/wintermute/debugger/listing_providers/source_listing.h37
-rw-r--r--engines/wintermute/debugger/listing_providers/source_listing_provider.h49
-rw-r--r--engines/wintermute/debugger/script_monitor.cpp26
-rw-r--r--engines/wintermute/debugger/script_monitor.h43
-rw-r--r--engines/wintermute/debugger/watch.cpp42
-rw-r--r--engines/wintermute/debugger/watch.h51
-rw-r--r--engines/wintermute/debugger/watch_instance.cpp53
-rw-r--r--engines/wintermute/debugger/watch_instance.h44
26 files changed, 1752 insertions, 0 deletions
diff --git a/engines/wintermute/debugger/breakpoint.cpp b/engines/wintermute/debugger/breakpoint.cpp
new file mode 100644
index 0000000000..7f2a02b0ea
--- /dev/null
+++ b/engines/wintermute/debugger/breakpoint.cpp
@@ -0,0 +1,68 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "breakpoint.h"
+#include "engines/wintermute/base/scriptables/debuggable/debuggable_script.h"
+#include "script_monitor.h"
+
+namespace Wintermute {
+
+Breakpoint::Breakpoint(const Common::String &filename, uint line, ScriptMonitor *monitor) :
+ _filename(filename), _line(line), _monitor(monitor), _enabled(0), _hits(0) {}
+
+void Breakpoint::hit(DebuggableScript *script) {
+ _hits++;
+ _monitor->onBreakpoint(this, script);
+}
+
+Common::String Breakpoint::getFilename() const {
+ return _filename;
+}
+int Breakpoint::getLine() const {
+ return _line;
+}
+int Breakpoint::getHits() const {
+ return _hits;
+}
+bool Breakpoint::isEnabled() const {
+ return _enabled;
+}
+void Breakpoint::enable() {
+ _enabled = true;
+}
+void Breakpoint::disable() {
+ _enabled = false;
+}
+
+void Breakpoint::evaluate(DebuggableScript *script) {
+ if (isEnabled() &&
+ getLine() == script->_currentLine &&
+ !getFilename().compareTo(script->_filename)) {
+ hit(script);
+ }
+}
+
+Breakpoint::~Breakpoint() {
+ // Nothing to take care of in here
+}
+
+} // End of namespace Wintermute
diff --git a/engines/wintermute/debugger/breakpoint.h b/engines/wintermute/debugger/breakpoint.h
new file mode 100644
index 0000000000..3757791ba3
--- /dev/null
+++ b/engines/wintermute/debugger/breakpoint.h
@@ -0,0 +1,58 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BREAKPOINT_H_
+#define BREAKPOINT_H_
+#include "common/str.h"
+
+namespace Wintermute {
+
+class ScriptMonitor;
+class DebuggableScript;
+
+class Breakpoint {
+ const Common::String _filename;
+ const uint _line;
+ uint _hits;
+ bool _enabled;
+ ScriptMonitor *_monitor;
+ void hit(DebuggableScript *script);
+public:
+ Breakpoint(const Common::String &filename, uint line, ScriptMonitor *monitor);
+ /**
+ * This should be called inside the interpreter; the breakpoint is evaluated
+ * in the context of script, and, if it is enabled and filename & line match,
+ * the attached ScriptMonitor is notified.
+ */
+ void evaluate(DebuggableScript* script);
+ Common::String getFilename() const;
+ int getLine() const;
+ int getHits() const;
+ bool isEnabled() const;
+ void enable();
+ void disable();
+ virtual ~Breakpoint();
+};
+
+} // End of namespace Wintermute
+
+#endif /* BREAKPOINT_H_ */
diff --git a/engines/wintermute/debugger/debugger_controller.cpp b/engines/wintermute/debugger/debugger_controller.cpp
new file mode 100644
index 0000000000..2e021530f8
--- /dev/null
+++ b/engines/wintermute/debugger/debugger_controller.cpp
@@ -0,0 +1,325 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/algorithm.h"
+#include "common/str.h"
+#include "common/tokenizer.h"
+#include "engines/wintermute/debugger.h"
+#include "engines/wintermute/base/base_file_manager.h"
+#include "engines/wintermute/base/base_engine.h"
+#include "engines/wintermute/base/base_game.h"
+#include "engines/wintermute/base/scriptables/script.h"
+#include "engines/wintermute/base/scriptables/script_value.h"
+#include "engines/wintermute/base/scriptables/script_stack.h"
+#include "engines/wintermute/debugger/breakpoint.h"
+#include "engines/wintermute/debugger/debugger_controller.h"
+#include "engines/wintermute/debugger/watch.h"
+#include "engines/wintermute/debugger/listing_providers/blank_listing_provider.h"
+#include "engines/wintermute/debugger/listing_providers/cached_source_listing_provider.h"
+#include "engines/wintermute/debugger/listing_providers/source_listing.h"
+#define SCENGINE _engine->_game->_scEngine
+#define DEBUGGER _engine->_debugger
+
+namespace Wintermute {
+
+DebuggerController::~DebuggerController() {
+ delete _sourceListingProvider;
+}
+
+DebuggerController::DebuggerController(WintermuteEngine *vm) : _engine(vm) {
+ _sourceListingProvider = new CachedSourceListingProvider();
+ clear();
+}
+
+bool DebuggerController::bytecodeExists(const Common::String &filename) {
+ uint32 compSize;
+ byte *compBuffer = SCENGINE->getCompiledScript(filename.c_str(), &compSize);
+ if (!compBuffer) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+Error DebuggerController::addBreakpoint(const char *filename, int line) {
+ assert(SCENGINE);
+ if (bytecodeExists(filename)) {
+ SCENGINE->_breakpoints.push_back(new Breakpoint(filename, line, this));
+ return Error(SUCCESS, OK);
+ } else {
+ return Error(ERROR, NO_SUCH_BYTECODE);
+ }
+}
+
+Error DebuggerController::removeBreakpoint(uint id) {
+ assert(SCENGINE);
+ if (SCENGINE->_breakpoints.size() > id) {
+ SCENGINE->_breakpoints.remove_at(id);
+ return Error(SUCCESS, OK);
+ } else {
+ return Error(ERROR, NO_SUCH_BREAKPOINT, id);
+ }
+}
+
+Error DebuggerController::disableBreakpoint(uint id) {
+ assert(SCENGINE);
+ if (SCENGINE->_breakpoints.size() > id) {
+ SCENGINE->_breakpoints[id]->disable();
+ return Error(SUCCESS, OK);
+ } else {
+ return Error(ERROR, NO_SUCH_BREAKPOINT, id);
+ }
+}
+
+Error DebuggerController::enableBreakpoint(uint id) {
+ assert(SCENGINE);
+ if (SCENGINE->_breakpoints.size() > id) {
+ SCENGINE->_breakpoints[id]->enable();
+ return Error(SUCCESS, OK);
+ } else {
+ return Error(ERROR, NO_SUCH_BREAKPOINT, id);
+ }
+}
+
+Error DebuggerController::removeWatchpoint(uint id) {
+ assert(SCENGINE);
+ if (SCENGINE->_watches.size() > id) {
+ SCENGINE->_watches.remove_at(id);
+ return Error(SUCCESS, OK);
+ } else {
+ return Error(ERROR, NO_SUCH_BREAKPOINT, id);
+ }
+}
+
+
+Error DebuggerController::disableWatchpoint(uint id) {
+ assert(SCENGINE);
+ if (SCENGINE->_watches.size() > id) {
+ SCENGINE->_watches[id]->disable();
+ return Error(SUCCESS, OK);
+ } else {
+ return Error(ERROR, NO_SUCH_BREAKPOINT, id);
+ }
+}
+
+Error DebuggerController::enableWatchpoint(uint id) {
+ assert(SCENGINE);
+ if (SCENGINE->_watches.size() > id) {
+ SCENGINE->_watches[id]->enable();
+ return Error(SUCCESS, OK);
+ } else {
+ return Error(ERROR, NO_SUCH_BREAKPOINT, id);
+ }
+
+}
+
+Error DebuggerController::addWatch(const char *filename, const char *symbol) {
+ assert(SCENGINE);
+ if (!bytecodeExists(filename)) {
+ return Error(ERROR, NO_SUCH_BYTECODE, filename);
+ }
+ SCENGINE->_watches.push_back(new Watch(filename, symbol, this));
+ return Error(SUCCESS, OK, "Watchpoint added");
+}
+
+void DebuggerController::onBreakpoint(const Breakpoint *breakpoint, DebuggableScript *script) {
+ _lastScript = script;
+ _lastLine = script->_currentLine;
+ DEBUGGER->notifyBreakpoint(script->dbgGetFilename().c_str(), script->_currentLine);
+}
+
+void DebuggerController::notifyStep(DebuggableScript *script) override {
+ _lastScript = script;
+ _lastLine = script->_currentLine;
+ DEBUGGER->notifyStep(script->dbgGetFilename().c_str(), script->_currentLine);
+}
+
+void DebuggerController::onWatch(const Watch *watch, DebuggableScript *script) {
+ _lastScript = script; // If script has changed do we still care?
+ _lastLine = script->_currentLine;
+ Common::String symbol = watch->getSymbol();
+ DEBUGGER->notifyWatch(script->dbgGetFilename().c_str(), symbol.c_str(), script->resolveName(symbol)->getString());
+}
+
+Error DebuggerController::step() {
+ if (!_lastScript) {
+ return Error(ERROR, NOT_ALLOWED);
+ }
+ _lastScript->step();
+ clear();
+ return Error(SUCCESS, OK);
+}
+
+Error DebuggerController::stepContinue() {
+ if (!_lastScript) {
+ return Error(ERROR, NOT_ALLOWED);
+ }
+ _lastScript->stepContinue();
+ return Error(SUCCESS, OK);
+}
+
+Error DebuggerController::stepFinish() {
+ if (!_lastScript) {
+ return Error(ERROR, NOT_ALLOWED);
+ }
+ _lastScript->stepFinish();
+ clear();
+ return Error(SUCCESS, OK);
+}
+
+void DebuggerController::clear() {
+ _lastScript = nullptr;
+ _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);
+}
+
+Common::Array<BreakpointInfo> DebuggerController::getBreakpoints() const {
+ assert(SCENGINE);
+ Common::Array<BreakpointInfo> breakpoints;
+ for (uint i = 0; i < SCENGINE->_breakpoints.size(); i++) {
+ BreakpointInfo bpInfo;
+ bpInfo._filename = SCENGINE->_breakpoints[i]->getFilename();
+ bpInfo._line = SCENGINE->_breakpoints[i]->getLine();
+ bpInfo._hits = SCENGINE->_breakpoints[i]->getHits();
+ bpInfo._enabled = SCENGINE->_breakpoints[i]->isEnabled();
+ breakpoints.push_back(bpInfo);
+ }
+ return breakpoints;
+}
+
+Common::Array<WatchInfo> DebuggerController::getWatchlist() const {
+ Common::Array<WatchInfo> watchlist;
+ for (uint i = 0; i < SCENGINE->_watches.size(); i++) {
+ WatchInfo watchInfo;
+ watchInfo._filename = SCENGINE->_watches[i]->getFilename();
+ watchInfo._symbol = SCENGINE->_watches[i]->getSymbol();
+ watchlist.push_back(watchInfo);
+ }
+ return watchlist;
+}
+
+uint32 DebuggerController::getLastLine() const {
+ return _lastLine;
+}
+
+Common::String DebuggerController::getSourcePath() const {
+ return _sourceListingProvider->getPath();
+}
+
+Error DebuggerController::setSourcePath(const Common::String &sourcePath) {
+ ErrorCode err = _sourceListingProvider->setPath(sourcePath);
+ return Error((err == OK ? SUCCESS : ERROR), err);
+}
+
+Listing* DebuggerController::getListing(Error* &error) {
+ delete (error);
+ if (_lastScript == nullptr) {
+ error = new Error(ERROR, NOT_ALLOWED);
+ return nullptr;
+ }
+ ErrorCode err;
+ Listing* res = _sourceListingProvider->getListing(SCENGINE->_currentScript->_filename, err);
+ error = new Error(err == OK ? SUCCESS : ERROR, err);
+ return res;
+}
+
+Common::Array<TopEntry> DebuggerController::getTop() const {
+ Common::Array<TopEntry> res;
+ assert(SCENGINE);
+ for (uint i = 0; i < SCENGINE->_scripts.size(); i++) {
+ TopEntry entry;
+ entry.filename = SCENGINE->_scripts[i]->_filename;
+ entry.current = (SCENGINE->_scripts[i] == SCENGINE->_currentScript);
+ res.push_back(entry);
+ }
+ return res;
+}
+
+} // end of namespace Wintermute
diff --git a/engines/wintermute/debugger/debugger_controller.h b/engines/wintermute/debugger/debugger_controller.h
new file mode 100644
index 0000000000..8c720281db
--- /dev/null
+++ b/engines/wintermute/debugger/debugger_controller.h
@@ -0,0 +1,119 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef WINTERMUTE_DEBUGGER_ADAPTER_H
+#define WINTERMUTE_DEBUGGER_ADAPTER_H
+
+#include "common/str.h"
+#include "engines/wintermute/coll_templ.h"
+#include "engines/wintermute/wintermute.h"
+#include "engines/wintermute/debugger/listing_providers/source_listing_provider.h"
+#include "script_monitor.h"
+#include "error.h"
+#include "listing.h"
+namespace Wintermute {
+
+class ScScript;
+class DebuggableScript;
+class ScValue;
+
+struct BreakpointInfo {
+ Common::String _filename;
+ int _line;
+ int _hits;
+ bool _enabled;
+};
+
+struct WatchInfo {
+ Common::String _filename;
+ Common::String _symbol;
+ int _hits;
+ bool _enabled;
+};
+
+struct TopEntry {
+ bool current;
+ Common::String filename;
+ int watches;
+ int breakpointInfo;
+};
+
+class DebuggerController : public ScriptMonitor {
+ SourceListingProvider *_sourceListingProvider;
+ const WintermuteEngine *_engine;
+ DebuggableScript *_lastScript;
+ uint32 _lastDepth;
+ uint32 _lastLine;
+ void clear();
+ bool bytecodeExists(const Common::String &filename);
+public:
+ DebuggerController(WintermuteEngine *vm);
+ ~DebuggerController();
+ Common::Array<TopEntry> getTop() const;
+ /**
+ * Get the last line # we've stopped at
+ */
+ uint32 getLastLine() const;
+ Error addBreakpoint(const char *filename, int line);
+ Error removeBreakpoint(uint id);
+ Error disableBreakpoint(uint id);
+ Error enableBreakpoint(uint id);
+ Error addWatch(const char *filename, const char *symbol);
+ Error removeWatchpoint(uint id);
+ Error disableWatchpoint(uint id);
+ Error enableWatchpoint(uint id);
+ Common::Array<BreakpointInfo> getBreakpoints() const;
+ Common::Array<WatchInfo> getWatchlist() const;
+ /**
+ * @brief step one instruction
+ */
+ Error step();
+ /**
+ * @brief continue execution and don't step until next breakpoint
+ */
+ Error stepContinue();
+ /**
+ * @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);
+ void showFps(bool show);
+ /**
+ * Inherited from ScriptMonitor
+ */
+ void onBreakpoint(const Breakpoint *breakpoint, DebuggableScript *script);
+ void onWatch(const Watch *watch, DebuggableScript *script);
+ void notifyStep(DebuggableScript *script);
+};
+}
+
+#endif // WINTERMUTE_DEBUGGER_H
diff --git a/engines/wintermute/debugger/error.cpp b/engines/wintermute/debugger/error.cpp
new file mode 100644
index 0000000000..dd6e41c7bc
--- /dev/null
+++ b/engines/wintermute/debugger/error.cpp
@@ -0,0 +1,137 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "error.h"
+#include "engines/wintermute/debugger.h"
+
+namespace Wintermute {
+
+Error::Error(ErrorLevel errorLevel,
+ ErrorCode errorCode,
+ Common::String errorExtraString,
+ int errorExtraInt) :
+ _errorLevel(errorLevel),
+ _errorCode(errorCode),
+ _errorExtraInt(errorExtraInt),
+ _errorExtraString(errorExtraString){}
+
+Error::Error(ErrorLevel errorLevel,
+ ErrorCode errorCode,
+ int errorExtraInt) :
+ _errorLevel(errorLevel),
+ _errorCode(errorCode),
+ _errorExtraInt(errorExtraInt),
+ _errorExtraString(""){}
+
+Error::Error(ErrorLevel errorLevel,
+ ErrorCode errorCode) :
+ _errorLevel(errorLevel),
+ _errorCode(errorCode),
+ _errorExtraInt(0),
+ _errorExtraString(""){}
+
+Error::Error(ErrorLevel errorLevel,
+ ErrorCode errorCode,
+ Common::String errorExtraString) :
+ _errorLevel(errorLevel),
+ _errorCode(errorCode),
+ _errorExtraInt(0),
+ _errorExtraString(errorExtraString){}
+
+ErrorLevel Error::getErrorLevel() const {
+ return _errorLevel;
+}
+
+ErrorCode Error::getErrorCode() const {
+ return _errorCode;
+}
+
+Common::String Error::getErrorLevelStr() const {
+ switch (this->_errorLevel) {
+ case SUCCESS:
+ return "SUCCESS";
+ break;
+ case NOTICE:
+ return "NOTICE";
+ break;
+ case WARNING:
+ return "WARNING";
+ break;
+ case ERROR:
+ return "ERROR";
+ break;
+ }
+ return "SUCCESS";
+}
+
+Common::String Error::getErrorDisplayStr() const {
+
+ Common::String errorStr;
+
+ switch (this->_errorLevel) {
+ case SUCCESS:
+ errorStr += "OK!";
+ break;
+ case WARNING:
+ errorStr += "WARNING: ";
+ break;
+ case ERROR:
+ errorStr += "ERROR: ";
+ break;
+ case NOTICE:
+ errorStr += "NOTICE: ";
+ break;
+ default:
+ // Um...
+ break;
+ }
+
+ switch (this->_errorCode) {
+ case OK:
+ break;
+ case NOT_ALLOWED:
+ errorStr += "Could not execute requested operation. This is allowed only after a break.";
+ break;
+ case NO_SUCH_SOURCE:
+ errorStr += Common::String::format("Can't find source for %s. Double check you source path.", this->_errorExtraString.c_str());
+ break;
+ case NO_SUCH_BYTECODE:
+ errorStr += Common::String::format("No such script: %s. Can't find bytecode; double check the script path.", this->_errorExtraString.c_str());
+ break;
+ case SOURCE_PATH_NOT_SET:
+ errorStr += Common::String("Source path not set. Source won't be displayed. Try 'help " + Common::String(SET_PATH_CMD) + "'.");
+ break;
+ case NO_SUCH_BREAKPOINT:
+ errorStr += Common::String::format("No such breakpoint %d.", this->_errorExtraInt);
+ break;
+ case WRONG_TYPE:
+ errorStr += Common::String::format("Incompatible type: %s.", this->_errorExtraString.c_str());
+ break;
+ default:
+ errorStr += Common::String::format("Unknown condition %d", this->_errorCode);
+ break;
+ }
+
+ return errorStr;
+}
+
+} // End namespace Wintermute
diff --git a/engines/wintermute/debugger/error.h b/engines/wintermute/debugger/error.h
new file mode 100644
index 0000000000..4e5b973445
--- /dev/null
+++ b/engines/wintermute/debugger/error.h
@@ -0,0 +1,73 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ERROR_H_
+#define ERROR_H_
+
+#include "common/str.h"
+
+namespace Wintermute {
+
+enum ErrorLevel {
+ SUCCESS,
+ NOTICE,
+ WARNING,
+ ERROR
+};
+
+enum ErrorCode {
+ OK,
+ NO_SUCH_SOURCE,
+ COULD_NOT_OPEN,
+ NO_SUCH_LINE,
+ NOT_ALLOWED,
+ NO_SUCH_BYTECODE,
+ DUPLICATE_BREAKPOINT,
+ NO_SUCH_BREAKPOINT,
+ WRONG_TYPE,
+ PARSE_ERROR,
+ NOT_YET_IMPLEMENTED,
+ SOURCE_PATH_NOT_SET,
+ ILLEGAL_PATH,
+ UNKNOWN_ERROR
+};
+
+
+class Error {
+ const ErrorLevel _errorLevel;
+ const ErrorCode _errorCode;
+ const int _errorExtraInt;
+ const Common::String _errorExtraString;
+public:
+ Error(ErrorLevel, ErrorCode);
+ Error(ErrorLevel, ErrorCode, int errorExtraInt);
+ Error(ErrorLevel, ErrorCode, Common::String errorExtraString);
+ Error(ErrorLevel, ErrorCode, Common::String errorExtraString, int errorExtraInt);
+ ErrorLevel getErrorLevel() const;
+ ErrorCode getErrorCode() const;
+ Common::String getErrorLevelStr() const;
+ Common::String getErrorDisplayStr() const;
+};
+
+} // End of namespace Wintermute
+
+#endif /* ERROR_H_ */
diff --git a/engines/wintermute/debugger/listing.cpp b/engines/wintermute/debugger/listing.cpp
new file mode 100644
index 0000000000..b8707fb842
--- /dev/null
+++ b/engines/wintermute/debugger/listing.cpp
@@ -0,0 +1,46 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "listing.h"
+#include "common/array.h"
+
+namespace Wintermute {
+
+Common::Array<ListingLine> Listing::getLines(uint begin, uint end) {
+ assert(begin <= end);
+ Common::Array<ListingLine> ret;
+ for (uint i = begin; i <= end; i++) {
+ ListingLine listingline;
+ listingline.number = i;
+ listingline.text = getLine(i);
+ ret.push_back(listingline);
+ }
+ return ret;
+}
+
+Common::Array<ListingLine> Listing::getLines(uint centre, uint before, uint after) {
+ uint begin = MAX(centre - before, (uint)1); // Line numbers start from 1
+ uint end = MIN(centre + after, (uint)(getLength() - 1)); // Line numbers start from 1
+ return getLines(begin, end);
+}
+
+} // End of namespace Wintermute
diff --git a/engines/wintermute/debugger/listing.h b/engines/wintermute/debugger/listing.h
new file mode 100644
index 0000000000..2ef21b702d
--- /dev/null
+++ b/engines/wintermute/debugger/listing.h
@@ -0,0 +1,64 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef LISTING_H_
+#define LISTING_H_
+
+#include "common/array.h"
+
+
+namespace Common {
+
+class String;
+
+}
+
+namespace Wintermute {
+
+struct ListingLine {
+ uint number;
+ Common::String text;
+};
+
+class Listing {
+public:
+ virtual ~Listing() {};
+ /**
+ * @brief get the listing length (in lines)
+ */
+ virtual uint getLength() const = 0;
+ /**
+ * @brief return a specific line from a listing
+ * @param n line number
+ */
+ virtual Common::String getLine(uint n) = 0;
+ /**
+ * @brief shorthand to get a lump of lines instead of calling getLine a number of times
+ * Generally you won't need to redefine these
+ */
+ virtual Common::Array<ListingLine> getLines(uint centre, uint before, uint after);
+ virtual Common::Array<ListingLine> getLines(uint beginning, uint end);
+};
+
+} // End of namespace Wintermute
+
+#endif /* LISTING_H_ */
diff --git a/engines/wintermute/debugger/listing_provider.h b/engines/wintermute/debugger/listing_provider.h
new file mode 100644
index 0000000000..b5ea23e49b
--- /dev/null
+++ b/engines/wintermute/debugger/listing_provider.h
@@ -0,0 +1,42 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef LISTING_PROVIDER_H_
+#define LISTING_PROVIDER_H_
+
+#include "listing.h"
+#include "engines/wintermute/debugger/error.h"
+
+namespace Wintermute {
+
+class ListingProvider {
+public:
+ virtual ~ListingProvider() {};
+ /**
+ * Get a listing. When implementing this, the result should be safe to delete for the caller.
+ */
+ virtual Listing *getListing(const Common::String &filename, ErrorCode &error) = 0;
+};
+
+} // End of namespace Wintermute
+
+#endif /* LISTING_PROVIDER_H_ */
diff --git a/engines/wintermute/debugger/listing_providers/basic_source_listing_provider.cpp b/engines/wintermute/debugger/listing_providers/basic_source_listing_provider.cpp
new file mode 100644
index 0000000000..30d29ee23e
--- /dev/null
+++ b/engines/wintermute/debugger/listing_providers/basic_source_listing_provider.cpp
@@ -0,0 +1,92 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "basic_source_listing_provider.h"
+#include "engines/wintermute/base/base_file_manager.h"
+
+namespace Wintermute {
+BasicSourceListingProvider::BasicSourceListingProvider() : _fsDirectory(nullptr) {
+}
+
+BasicSourceListingProvider::~BasicSourceListingProvider() {
+}
+
+SourceListing *BasicSourceListingProvider::getListing(const Common::String &filename, ErrorCode &_err) {
+ _err = OK;
+ if (!_fsDirectory) {
+ _err = SOURCE_PATH_NOT_SET;
+ return nullptr;
+ };
+
+ Common::String unixFilename;
+
+ for (uint i = 0; i < filename.size(); i++) {
+ if (filename[i] == '\\') {
+ unixFilename.insertChar('/', unixFilename.size());
+ } else {
+ unixFilename.insertChar(filename[i], unixFilename.size());
+ }
+ }
+
+ Common::SeekableReadStream *file = _fsDirectory->createReadStreamForMember(unixFilename);
+ Common::Array<Common::String> strings;
+
+ if (!file) {
+ _err = NO_SUCH_SOURCE;
+ } else {
+ if (file->err()) {
+ _err = UNKNOWN_ERROR;
+ }
+ while (!file->eos()) {
+ strings.push_back(file->readLine());
+ if (file->err()) {
+ _err = UNKNOWN_ERROR;
+ }
+ }
+ }
+
+ if (_err == OK) {
+ return new SourceListing(strings);
+ } else {
+ return nullptr;
+ }
+}
+
+ErrorCode BasicSourceListingProvider::setPath(const Common::String &path) {
+ if (path == "")
+ return ILLEGAL_PATH;
+ delete _fsDirectory;
+ Common::FSNode node(path);
+ if (node.exists() && node.isDirectory()) {
+ _fsDirectory = new Common::FSDirectory(node, 64);
+ return OK;
+ } else {
+ return COULD_NOT_OPEN;
+ }
+}
+
+Common::String BasicSourceListingProvider::getPath() const {
+ if (!_fsDirectory) return "";
+ return _fsDirectory->getFSNode().getPath();
+}
+
+}
diff --git a/engines/wintermute/debugger/listing_providers/basic_source_listing_provider.h b/engines/wintermute/debugger/listing_providers/basic_source_listing_provider.h
new file mode 100644
index 0000000000..e242205578
--- /dev/null
+++ b/engines/wintermute/debugger/listing_providers/basic_source_listing_provider.h
@@ -0,0 +1,44 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BASIC_SOURCE_LISTING_PROVIDER_H_
+#define BASIC_SOURCE_LISTING_PROVIDER_H_
+
+#include "engines/wintermute/debugger/listing_provider.h"
+#include "source_listing_provider.h"
+#include "source_listing.h"
+#include "common/fs.h"
+
+namespace Wintermute {
+
+class BasicSourceListingProvider : public SourceListingProvider {
+ Common::FSDirectory *_fsDirectory;
+public:
+ BasicSourceListingProvider();
+ virtual ~BasicSourceListingProvider();
+ SourceListing *getListing(const Common::String &filename, ErrorCode &err);
+ ErrorCode setPath(const Common::String &path);
+ Common::String getPath() const;
+};
+
+}
+#endif /* BASIC_SOURCE_LISTING_PROVIDER_H_ */
diff --git a/engines/wintermute/debugger/listing_providers/blank_listing.cpp b/engines/wintermute/debugger/listing_providers/blank_listing.cpp
new file mode 100644
index 0000000000..928c91dc7f
--- /dev/null
+++ b/engines/wintermute/debugger/listing_providers/blank_listing.cpp
@@ -0,0 +1,38 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "blank_listing.h"
+#include "limits.h"
+
+namespace Wintermute {
+
+BlankListing::BlankListing(const Common::String filename) : _filename(filename) {}
+
+uint BlankListing::getLength() const { return UINT_MAX; }
+
+Common::String BlankListing::getLine(uint n) {
+ return "<no source for " + _filename + " ~~~ line: " + Common::String::format("%d", n) + ">";
+}
+BlankListing::~BlankListing() {}
+
+}
+
diff --git a/engines/wintermute/debugger/listing_providers/blank_listing.h b/engines/wintermute/debugger/listing_providers/blank_listing.h
new file mode 100644
index 0000000000..8c5ea19aa7
--- /dev/null
+++ b/engines/wintermute/debugger/listing_providers/blank_listing.h
@@ -0,0 +1,39 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BLANK_LISTING_H_
+#define BLANK_LISTING_H_
+#include "engines/wintermute/debugger/listing.h"
+
+namespace Wintermute {
+class BlankListing : public Listing {
+ const Common::String _filename;
+public:
+ BlankListing(const Common::String filename);
+ virtual ~BlankListing();
+ virtual uint getLength() const;
+ virtual Common::String getLine(uint n);
+};
+
+} // End of namespace Wintermute
+
+#endif
diff --git a/engines/wintermute/debugger/listing_providers/blank_listing_provider.cpp b/engines/wintermute/debugger/listing_providers/blank_listing_provider.cpp
new file mode 100644
index 0000000000..58e9e7e156
--- /dev/null
+++ b/engines/wintermute/debugger/listing_providers/blank_listing_provider.cpp
@@ -0,0 +1,35 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "blank_listing_provider.h"
+#include "blank_listing.h"
+namespace Wintermute {
+BlankListingProvider::BlankListingProvider() {}
+
+BlankListingProvider::~BlankListingProvider() {}
+
+Listing *BlankListingProvider::getListing(const Common::String &filename, ErrorCode &error) {
+ Listing *l = new BlankListing(filename);
+ error = OK;
+ return l; // Delete this sometime please.
+}
+} // End of namespace Wintermute
diff --git a/engines/wintermute/debugger/listing_providers/blank_listing_provider.h b/engines/wintermute/debugger/listing_providers/blank_listing_provider.h
new file mode 100644
index 0000000000..e583455c92
--- /dev/null
+++ b/engines/wintermute/debugger/listing_providers/blank_listing_provider.h
@@ -0,0 +1,38 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BLANK_LISTING_PROVIDER_H_
+#define BLANK_LISTING_PROVIDER_H_
+
+#include "engines/wintermute/debugger/listing.h"
+#include "engines/wintermute/debugger/listing_provider.h"
+#include "engines/wintermute/debugger/error.h"
+
+namespace Wintermute {
+class BlankListingProvider : public ListingProvider {
+public:
+ BlankListingProvider();
+ ~BlankListingProvider();
+ Listing *getListing(const Common::String &filename, ErrorCode &error);
+};
+} // End of namespace Wintermute
+#endif
diff --git a/engines/wintermute/debugger/listing_providers/cached_source_listing_provider.cpp b/engines/wintermute/debugger/listing_providers/cached_source_listing_provider.cpp
new file mode 100644
index 0000000000..20fe708380
--- /dev/null
+++ b/engines/wintermute/debugger/listing_providers/cached_source_listing_provider.cpp
@@ -0,0 +1,80 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "cached_source_listing_provider.h"
+#include "basic_source_listing_provider.h"
+#include "blank_listing_provider.h"
+#include "source_listing.h"
+
+namespace Wintermute {
+
+CachedSourceListingProvider::CachedSourceListingProvider() {
+ _sourceListingProvider = new BasicSourceListingProvider();
+ _fallbackListingProvider = new BlankListingProvider();
+}
+
+CachedSourceListingProvider::~CachedSourceListingProvider() {
+ delete _sourceListingProvider;
+ delete _fallbackListingProvider;
+ for (Common::HashMap<Common::String, SourceListing*>::iterator it = _cached.begin();
+ it != _cached.end(); it++) {
+ delete (it->_value);
+ }
+}
+
+Listing *CachedSourceListingProvider::getListing(const Common::String &filename, Wintermute::ErrorCode &error) {
+ if (_cached.contains(filename)) {
+ error = OK;
+ SourceListing *copy = new SourceListing(*_cached.getVal(filename));
+ return copy;
+ } else {
+ ErrorCode inner;
+ SourceListing *res = _sourceListingProvider->getListing(filename, inner);
+ if (inner == OK) {
+ SourceListing *copy = new SourceListing(*res);
+ _cached.setVal(filename, copy); // The cached copy is deleted on destruction
+ return res;
+ } else {
+ delete res;
+ return _fallbackListingProvider->getListing(filename, error);
+ }
+ }
+}
+
+void CachedSourceListingProvider::invalidateCache() {
+ for (Common::HashMap<Common::String, SourceListing*>::iterator it = _cached.begin();
+ it != _cached.end(); it++) {
+ delete (it->_value);
+ }
+ _cached.clear();
+}
+
+ErrorCode CachedSourceListingProvider::setPath(const Common::String &path) {
+ invalidateCache();
+ return _sourceListingProvider->setPath(path);
+}
+
+Common::String CachedSourceListingProvider::getPath() const {
+ return _sourceListingProvider->getPath();
+}
+
+} // End of namespace Wintermute
diff --git a/engines/wintermute/debugger/listing_providers/cached_source_listing_provider.h b/engines/wintermute/debugger/listing_providers/cached_source_listing_provider.h
new file mode 100644
index 0000000000..6e4925f2b4
--- /dev/null
+++ b/engines/wintermute/debugger/listing_providers/cached_source_listing_provider.h
@@ -0,0 +1,52 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef CACHED_LISTING_PROVIDER_H_
+#define CACHED_LISTING_PROVIDER_H_
+
+#include "common/hashmap.h"
+#include "common/hash-str.h"
+#include "engines/wintermute/debugger/error.h"
+#include "source_listing_provider.h"
+
+namespace Wintermute {
+
+class BasicSourceListingProvider;
+class BlankListingProvider;
+class Listing;
+
+class CachedSourceListingProvider : public SourceListingProvider {
+ BasicSourceListingProvider *_sourceListingProvider;
+ BlankListingProvider *_fallbackListingProvider;
+ Common::HashMap<Common::String, SourceListing *> _cached;
+ void invalidateCache();
+public:
+ CachedSourceListingProvider();
+ virtual ~CachedSourceListingProvider();
+ ErrorCode setPath(const Common::String &path);
+ Common::String getPath() const;
+ Listing *getListing(const Common::String &filename, ErrorCode &err);
+};
+
+} // End of namespace Wintermute
+
+#endif /* CACHED_LISTING_PROVIDER_H_ */
diff --git a/engines/wintermute/debugger/listing_providers/source_listing.cpp b/engines/wintermute/debugger/listing_providers/source_listing.cpp
new file mode 100644
index 0000000000..ff81e20f02
--- /dev/null
+++ b/engines/wintermute/debugger/listing_providers/source_listing.cpp
@@ -0,0 +1,57 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "source_listing.h"
+
+namespace Wintermute {
+
+SourceListing::SourceListing(const Common::Array<Common::String> &strings) : _strings(strings) {}
+
+SourceListing::~SourceListing() {}
+
+uint SourceListing::getLength() const {
+ return _strings.size();
+}
+
+Common::String SourceListing::getLine(uint n) {
+ uint index = n - 1; // Line numbers start from 1, arrays from 0
+ /*
+ * Clients should not ask for a line number that
+ * is not in the source file.
+ * 0 is undefined, n - 1 is undefined.
+ * It is easy for the client to check that n > 0
+ * and n < getLength(), so it should just not happen.
+ * We return '^', after vim, to misbehaving clients.
+ */
+ if (n == 0) {
+ return Common::String("^");
+ }
+ if (index < getLength()) {
+ return _strings[index];
+ } else {
+ return Common::String("^");
+ }
+}
+
+} // End of namespace Wintermute
+
+
diff --git a/engines/wintermute/debugger/listing_providers/source_listing.h b/engines/wintermute/debugger/listing_providers/source_listing.h
new file mode 100644
index 0000000000..bf08578218
--- /dev/null
+++ b/engines/wintermute/debugger/listing_providers/source_listing.h
@@ -0,0 +1,37 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SOURCE_LISTING_H_
+#define SOURCE_LISTING_H_
+#include "engines/wintermute/debugger/listing.h"
+
+namespace Wintermute {
+class SourceListing : public Listing {
+ const Common::Array<Common::String> _strings;
+public:
+ SourceListing(const Common::Array<Common::String> &strings);
+ virtual ~SourceListing();
+ virtual uint getLength() const;
+ virtual Common::String getLine(uint n);
+};
+}
+#endif /* DUMMY_LISTING_H_ */
diff --git a/engines/wintermute/debugger/listing_providers/source_listing_provider.h b/engines/wintermute/debugger/listing_providers/source_listing_provider.h
new file mode 100644
index 0000000000..18f05e56ed
--- /dev/null
+++ b/engines/wintermute/debugger/listing_providers/source_listing_provider.h
@@ -0,0 +1,49 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SOURCE_LISTING_PROVIDER_H_
+#define SOURCE_LISTING_PROVIDER_H_
+
+#include "engines/wintermute/debugger/error.h"
+#include "engines/wintermute/debugger/listing_provider.h"
+#include "common/str.h"
+
+namespace Wintermute {
+
+class SourceListing;
+class Listing;
+
+class SourceListingProvider : ListingProvider {
+public:
+ virtual ~SourceListingProvider() {};
+ /**
+ * Get a listing. When implementing this, the result should be safe to delete for the caller.
+ */
+ virtual Listing *getListing(const Common::String &filename, ErrorCode &err) = 0;
+ virtual ErrorCode setPath(const Common::String &path) = 0;
+ virtual Common::String getPath() const = 0;
+
+};
+
+} // End of namespace Wintermute
+
+#endif /* SOURCE_LISTING_PROVIDER_H_ */
diff --git a/engines/wintermute/debugger/script_monitor.cpp b/engines/wintermute/debugger/script_monitor.cpp
new file mode 100644
index 0000000000..2e9370c923
--- /dev/null
+++ b/engines/wintermute/debugger/script_monitor.cpp
@@ -0,0 +1,26 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "script_monitor.h"
+
+namespace Wintermute {
+}
diff --git a/engines/wintermute/debugger/script_monitor.h b/engines/wintermute/debugger/script_monitor.h
new file mode 100644
index 0000000000..e9559e2ade
--- /dev/null
+++ b/engines/wintermute/debugger/script_monitor.h
@@ -0,0 +1,43 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SCRIPTMONITOR_H_
+#define SCRIPTMONITOR_H_
+
+namespace Wintermute {
+
+class DebuggableScript;
+class Breakpoint;
+class Watch;
+
+class ScriptMonitor {
+public:
+
+ virtual ~ScriptMonitor() {};
+ virtual void notifyStep(DebuggableScript* script) = 0;
+ virtual void onBreakpoint(const Breakpoint* breakpoint, DebuggableScript* script) = 0;
+ virtual void onWatch(const Watch* watch, DebuggableScript* script) = 0;
+};
+
+} // End of namespace Wintermute
+
+#endif /* SCRIPTMONITOR_H_ */
diff --git a/engines/wintermute/debugger/watch.cpp b/engines/wintermute/debugger/watch.cpp
new file mode 100644
index 0000000000..410756fdc8
--- /dev/null
+++ b/engines/wintermute/debugger/watch.cpp
@@ -0,0 +1,42 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "watch.h"
+#include "watch_instance.h"
+#include "script_monitor.h"
+
+namespace Wintermute {
+
+Watch::Watch(const Common::String &filename, const Common::String &symbol, ScriptMonitor* monitor) : _enabled(false), _filename(filename), _symbol(symbol), _monitor(monitor) {}
+
+Watch::~Watch() { /* Nothing to take care of in here */ }
+
+void Watch::trigger(WatchInstance* instance) {
+ _monitor->onWatch(this, instance->_script);
+}
+
+Common::String Watch::getFilename() const { return _filename; }
+Common::String Watch::getSymbol() const { return _symbol; }
+bool Watch::isEnabled() const { return _enabled; }
+void Watch::enable() { _enabled = true; }
+void Watch::disable() { _enabled = false; }
+}
diff --git a/engines/wintermute/debugger/watch.h b/engines/wintermute/debugger/watch.h
new file mode 100644
index 0000000000..cbffe43b41
--- /dev/null
+++ b/engines/wintermute/debugger/watch.h
@@ -0,0 +1,51 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef WATCH_H_
+#define WATCH_H_
+
+#include "common/str.h"
+
+namespace Wintermute {
+
+class ScValue;
+class ScScript;
+class WatchInstance;
+class ScriptMonitor;
+
+class Watch {
+ const Common::String _filename;
+ const Common::String _symbol;
+ int _enabled;
+ ScriptMonitor *_monitor;
+public:
+ Watch(const Common::String &filename, const Common::String &symbol, ScriptMonitor*);
+ Common::String getFilename() const;
+ Common::String getSymbol() const;
+ bool isEnabled() const;
+ void enable();
+ void disable();
+ void trigger(WatchInstance*);
+ virtual ~Watch();
+};
+}
+#endif /* WATCH_H_ */
diff --git a/engines/wintermute/debugger/watch_instance.cpp b/engines/wintermute/debugger/watch_instance.cpp
new file mode 100644
index 0000000000..2d31221ad4
--- /dev/null
+++ b/engines/wintermute/debugger/watch_instance.cpp
@@ -0,0 +1,53 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "watch_instance.h"
+#include "engines/wintermute/base/scriptables/script_value.h"
+#include "engines/wintermute/base/scriptables/debuggable/debuggable_script.h"
+#include "engines/wintermute/debugger/watch.h"
+
+namespace Wintermute {
+
+WatchInstance::WatchInstance(Watch* watch, DebuggableScript* script) : _watch(watch), _script(script), _lastValue(nullptr) {}
+WatchInstance::~WatchInstance() { delete _lastValue; }
+
+void WatchInstance::evaluate() {
+ if (_watch->isEnabled()) {
+ if (!_watch->getFilename().compareTo(_script->_filename)) {
+
+ if(_lastValue == nullptr) {
+ _lastValue = new ScValue(_script->_gameRef);
+ // ^^ This here is NULL by default
+ }
+ ScValue* currentValue = _script->resolveName(_watch->getSymbol());
+ if(ScValue::compare(
+ currentValue,
+ _lastValue
+ )) {
+ _lastValue->copy(currentValue);
+ _watch->trigger(this);
+ }
+ delete currentValue;
+ }
+ }
+}
+} // End of namespace Wintermute
diff --git a/engines/wintermute/debugger/watch_instance.h b/engines/wintermute/debugger/watch_instance.h
new file mode 100644
index 0000000000..84fb62968d
--- /dev/null
+++ b/engines/wintermute/debugger/watch_instance.h
@@ -0,0 +1,44 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef WATCH_INSTANCE_H_
+#define WATCH_INSTANCE_H_
+
+namespace Wintermute {
+class Watch;
+class ScValue;
+class DebuggableScript;
+
+class WatchInstance {
+ Watch* _watch;
+ ScValue *_lastValue;
+ DebuggableScript* _script;
+public:
+ WatchInstance (Watch* watch, DebuggableScript* script);
+ ~WatchInstance();
+ void evaluate();
+friend class DebuggableScript;
+friend class Watch;
+};
+} // End of namespace Wintermute
+
+#endif /* WATCH_INSTANCE_H_ */