aboutsummaryrefslogtreecommitdiff
path: root/gui
diff options
context:
space:
mode:
authorWillem Jan Palenstijn2009-07-25 23:36:24 +0000
committerWillem Jan Palenstijn2009-07-25 23:36:24 +0000
commit45cde5f6422dcee5ffbe6d5d4c482de738c2b053 (patch)
tree418bc12033184ca1af6548a3b3f77e0df0d71224 /gui
parent037c02a1f7179bbe5e3b044e6c9a13a94cd9851c (diff)
downloadscummvm-rg350-45cde5f6422dcee5ffbe6d5d4c482de738c2b053.tar.gz
scummvm-rg350-45cde5f6422dcee5ffbe6d5d4c482de738c2b053.tar.bz2
scummvm-rg350-45cde5f6422dcee5ffbe6d5d4c482de738c2b053.zip
Add optional readline support to the text debugger console.
Make text/graphical console selectable with an option to configure. svn-id: r42787
Diffstat (limited to 'gui')
-rw-r--r--gui/debugger.cpp89
-rw-r--r--gui/debugger.h13
2 files changed, 79 insertions, 23 deletions
diff --git a/gui/debugger.cpp b/gui/debugger.cpp
index dd292a3a8a..a7dd9b2411 100644
--- a/gui/debugger.cpp
+++ b/gui/debugger.cpp
@@ -27,10 +27,14 @@
#include "common/system.h"
#include "gui/debugger.h"
-#if USE_CONSOLE
+#ifndef USE_TEXT_CONSOLE
#include "gui/console.h"
+#elif defined(USE_READLINE)
+ #include <readline/readline.h>
+ #include <readline/history.h>
#endif
+
namespace GUI {
Debugger::Debugger() {
@@ -39,7 +43,7 @@ Debugger::Debugger() {
_isAttached = false;
_errStr = NULL;
_firstTime = true;
-#if USE_CONSOLE
+#ifndef USE_TEXT_CONSOLE
_debuggerDialog = new GUI::ConsoleDialog(1.0f, 0.67f);
_debuggerDialog->setInputCallback(debuggerInputCallback, this);
_debuggerDialog->setCompletionCallback(debuggerCompletionCallback, this);
@@ -57,7 +61,7 @@ Debugger::Debugger() {
}
Debugger::~Debugger() {
-#if USE_CONSOLE
+#ifndef USE_TEXT_CONSOLE
delete _debuggerDialog;
#endif
}
@@ -69,7 +73,7 @@ int Debugger::DebugPrintf(const char *format, ...) {
va_start(argptr, format);
int count;
-#if USE_CONSOLE
+#ifndef USE_TEXT_CONSOLE
count = _debuggerDialog->vprintf(format, argptr);
#else
count = ::vprintf(format, argptr);
@@ -116,9 +120,21 @@ void Debugger::onFrame() {
}
}
+#if defined(USE_TEXT_CONSOLE) && defined(USE_READLINE)
+static Debugger* g_readline_debugger;
+
+char * readline_completionFunction (const char *text, int state)
+{
+ return g_readline_debugger->readlineComplete(text, state);
+}
+#endif
+
// Main Debugger Loop
void Debugger::enter() {
-#if USE_CONSOLE
+ // TODO: Having three I/O methods #ifdef-ed in this file is not the
+ // cleanest approach to this...
+
+#ifndef USE_TEXT_CONSOLE
if (_firstTime) {
DebugPrintf("Debugger started, type 'exit' to return to the game.\n");
DebugPrintf("Type 'help' to see a little list of commands and variables.\n");
@@ -133,18 +149,28 @@ void Debugger::enter() {
_debuggerDialog->runModal();
#else
- // TODO: compared to the console input, this here is very bare bone.
- // For example, no support for tab completion and no history. At least
- // we should re-add (optional) support for the readline library.
- // Or maybe instead of choosing between a console dialog and stdio,
- // we should move that choice into the ConsoleDialog class - that is,
- // the console dialog code could be #ifdef'ed to not print to the dialog
- // but rather to stdio. This way, we could also reuse the command history
- // and tab completion of the console. It would still require a lot of
- // work, but at least no dependency on a 3rd party library...
-
printf("Debugger entered, please switch to this console for input.\n");
+#ifdef USE_READLINE
+ // TODO: add support for saving/loading history?
+
+ g_readline_debugger = this;
+ rl_completion_entry_function = &readline_completionFunction;
+
+ char *line_read = 0;
+ do {
+ free(line_read);
+ line_read = readline("debug> ");
+
+ if (line_read && line_read[0])
+ add_history(line_read);
+
+ } while (line_read && parseCommand(line_read));
+
+ free(line_read);
+ line_read = 0;
+
+#else
int i;
char buf[256];
@@ -160,6 +186,7 @@ void Debugger::enter() {
if (i == 0)
continue;
} while (parseCommand(buf));
+#endif
#endif
}
@@ -330,6 +357,30 @@ bool Debugger::tabComplete(const char *input, Common::String &completion) const
return true;
}
+#if defined(USE_TEXT_CONSOLE) && defined(USE_READLINE)
+char* Debugger::readlineComplete(const char *input, int state)
+{
+ static CommandsMap::const_iterator iter;
+
+ // We assume that _cmds isn't changed between calls to readlineComplete,
+ // unless state is 0.
+ if (state == 0) {
+ iter = _cmds.begin();
+ } else {
+ ++iter;
+ }
+
+ for (; iter != _cmds.end(); ++iter) {
+ if (iter->_key.hasPrefix(input)) {
+ char *ret = (char *)malloc(iter->_key.size() + 1);
+ strcpy(ret, iter->_key.c_str());
+ return ret;
+ }
+ }
+ return 0;
+}
+#endif
+
// Variable registration function
void Debugger::DVar_Register(const Common::String &varname, void *pointer, int type, int optional) {
// TODO: Filter out duplicates
@@ -361,9 +412,13 @@ bool Debugger::Cmd_Exit(int argc, const char **argv) {
// Print a list of all registered commands (and variables, if any),
// nicely word-wrapped.
bool Debugger::Cmd_Help(int argc, const char **argv) {
-#if USE_CONSOLE
+#ifndef USE_TEXT_CONSOLE
const int charsPerLine = _debuggerDialog->getCharsPerLine();
+#elif defined(USE_READLINE)
+ int charsPerLine, rows;
+ rl_get_screen_size(&rows, &charsPerLine);
#else
+ // Can we do better?
const int charsPerLine = 80;
#endif
int width, size;
@@ -460,7 +515,7 @@ bool Debugger::Cmd_DebugFlagDisable(int argc, const char **argv) {
}
// Console handler
-#if USE_CONSOLE
+#ifndef USE_TEXT_CONSOLE
bool Debugger::debuggerInputCallback(GUI::ConsoleDialog *console, const char *input, void *refCon) {
Debugger *debugger = (Debugger *)refCon;
diff --git a/gui/debugger.h b/gui/debugger.h
index 1baf99faeb..81a85a7243 100644
--- a/gui/debugger.h
+++ b/gui/debugger.h
@@ -32,10 +32,7 @@
namespace GUI {
-// Choose between text console or ScummConsole
-#define USE_CONSOLE 1
-
-#if USE_CONSOLE
+#ifndef USE_TEXT_CONSOLE
class ConsoleDialog;
#endif
@@ -86,7 +83,7 @@ private:
bool _isAttached;
char *_errStr;
bool _firstTime;
-#if USE_CONSOLE
+#ifndef USE_TEXT_CONSOLE
GUI::ConsoleDialog *_debuggerDialog;
#endif
@@ -120,11 +117,15 @@ protected:
bool Cmd_DebugFlagEnable(int argc, const char **argv);
bool Cmd_DebugFlagDisable(int argc, const char **argv);
-#if USE_CONSOLE
+#ifndef USE_TEXT_CONSOLE
private:
static bool debuggerInputCallback(GUI::ConsoleDialog *console, const char *input, void *refCon);
static bool debuggerCompletionCallback(GUI::ConsoleDialog *console, const char *input, Common::String &completion, void *refCon);
+#elif defined(USE_READLINE)
+public:
+ char* readlineComplete(const char *input, int state);
#endif
+
};
} // End of namespace GUI