diff options
author | Willem Jan Palenstijn | 2009-07-25 23:36:24 +0000 |
---|---|---|
committer | Willem Jan Palenstijn | 2009-07-25 23:36:24 +0000 |
commit | 45cde5f6422dcee5ffbe6d5d4c482de738c2b053 (patch) | |
tree | 418bc12033184ca1af6548a3b3f77e0df0d71224 /gui | |
parent | 037c02a1f7179bbe5e3b044e6c9a13a94cd9851c (diff) | |
download | scummvm-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.cpp | 89 | ||||
-rw-r--r-- | gui/debugger.h | 13 |
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 |