Ticket #8211: debugger_completion.diff

File debugger_completion.diff, 6.4 KB (added by wjp, 18 years ago)

debugger_completion.diff

  • gui/console.cpp

    RCS file: /cvsroot/scummvm/scummvm/gui/console.cpp,v
    retrieving revision 1.24
    diff -u -r1.24 console.cpp
     
    159159                                // comply to the C++ standard, so we can't use a dynamic sized stack array.
    160160                                char *str = new char[len + 1];
    161161       
    162                                 // Copy the user intput to str
     162                                // Copy the user input to str
    163163                                for (i = 0; i < len; i++)
    164164                                        str[i] = _buffer[(_promptStartPos + i) % kBufferSize];
    165165                                str[len] = '\0';
     
    197197                        scrollToCurrent();
    198198                        draw(); // FIXME - not nice to redraw the full console just for one char!
    199199                        break;
     200                case 9: // tab
     201                {
     202                        if (_completionCallbackProc) {
     203                                int len = _currentPos - _promptStartPos;
     204                                assert(len >= 0);
     205                                char *str = new char[len + 1];
     206       
     207                                // Copy the user input to str
     208                                for (i = 0; i < len; i++)
     209                                        str[i] = _buffer[(_promptStartPos + i) % kBufferSize];
     210                                str[len] = '\0';
     211
     212                                char *completion = 0;
     213                                if ((*_completionCallbackProc)(this, str, completion,
     214                                                                                           _callbackRefCon))
     215                                {
     216                                        if (_caretVisible)
     217                                                drawCaret(true);
     218                                        insertIntoPrompt(completion);
     219                                        scrollToCurrent();
     220                                        draw();
     221                                        delete[] completion;
     222                                }
     223                                delete[] str;
     224                        }
     225                        break;
     226                }
    200227                case 127:
    201228                        killChar();
    202229                        draw();
     
    252279                                putchar((char)ascii);
    253280                                scrollToCurrent();
    254281                        }
     282        }
     283}
     284
     285void ConsoleDialog::insertIntoPrompt(const char* str)
     286{
     287        unsigned int l = strlen(str);
     288        for (int i = _promptEndPos-1; i >= _currentPos; i--)
     289                _buffer[(i + l) % kBufferSize] =
     290                        _buffer[i % kBufferSize];
     291        for (unsigned int j = 0; j < l; ++j) {
     292                _promptEndPos++;
     293                putcharIntern(str[j]);
    255294        }
    256295}
    257296
  • gui/console.h

    RCS file: /cvsroot/scummvm/scummvm/gui/console.h,v
    retrieving revision 1.15
    diff -u -r1.15 console.h
     
    3939class ConsoleDialog : public Dialog {
    4040public:
    4141        typedef bool (*InputCallbackProc)(ConsoleDialog *console, const char *input, void *refCon);
     42        typedef bool (*CompletionCallbackProc)(ConsoleDialog* console, const char *input, char*& completion, void *refCon);
    4243
    4344protected:
    4445        char    _buffer[kBufferSize];
     
    6364        InputCallbackProc _callbackProc;
    6465        void *_callbackRefCon;
    6566
     67        // _completionCallbackProc is called when tab is pressed
     68        CompletionCallbackProc _completionCallbackProc;
     69        void *_completionCallbackRefCon;
     70
    6671        char _history[kHistorySize][kLineBufferSize];
    6772        int _historySize;
    6873        int _historyIndex;
     
    8893                _callbackProc = proc;
    8994                _callbackRefCon = refCon;
    9095        }
     96        void setCompletionCallback(CompletionCallbackProc proc, void *refCon) {
     97                _completionCallbackProc = proc;
     98                _completionCallbackRefCon = refCon;
     99        }
    91100
    92101protected:
    93102        void drawCaret(bool erase);
    94103        void putcharIntern(int c);
     104        void insertIntoPrompt(const char *str);
    95105        void print(const char *str);
    96106        void nextLine();
    97107        void updateScrollBar();
  • scumm/debugger.cpp

    RCS file: /cvsroot/scummvm/scummvm/scumm/debugger.cpp,v
    retrieving revision 1.29
    diff -u -r1.29 debugger.cpp
     
    107107
    108108void ScummDebugger::detach() {
    109109#ifdef USE_CONSOLE
    110         if (_s->_debuggerDialog)
     110        if (_s->_debuggerDialog) {
    111111                _s->_debuggerDialog->setInputeCallback(0, 0);
     112                _s->_debuggerDialog->setCompletionCallback(0, 0);
     113        }
    112114#endif
    113115       
    114116        _s->_debugger = NULL;
     
    144146       
    145147        return debugger->RunCommand((char*)input);
    146148}
     149
     150
     151bool ScummDebugger::debuggerCompletionCallback(ConsoleDialog *console, const char *input, char*& completion, void *refCon) {
     152        ScummDebugger *debugger = (ScummDebugger *)refCon;
     153
     154        return debugger->TabComplete(input, completion);
     155}
     156
    147157#endif
    148158
    149159///////////////////////////////////////////////////
     
    184194        }
    185195       
    186196        _s->_debuggerDialog->setInputeCallback(debuggerInputCallback, this);
     197        _s->_debuggerDialog->setCompletionCallback(debuggerCompletionCallback,
     198                                                                                           this);
    187199        _s->_debuggerDialog->runModal();
    188200#else
    189201        printf("Debugger entered, please switch to this console for input.\n");
     
    783795
    784796        return true;
    785797}
     798
     799// returns true if something has been completed
     800// completion has to be delete[]-ed then
     801bool ScummDebugger::TabComplete(const char *input, char*& completion) {
     802        // very basic tab completion
     803        // for now it just supports command completions
     804
     805        // adding completions of command parameters would be nice (but hard) :-)
     806        // maybe also give a list of possible command completions?
     807        //   (but this will require changes to console)
     808
     809        if (strchr(input, ' '))
     810                return false; // already finished the first word
     811
     812        unsigned int inputlen = strlen(input);
     813
     814        unsigned int matchlen = 0;
     815        char match[30]; // the max. command name is 30 chars
     816
     817        for(int i=0; i < _dcmd_count; i++) {
     818                if (!strncmp(_dcmds[i].name, input, inputlen)) {
     819                        unsigned int commandlen = strlen(_dcmds[i].name);
     820                        if (commandlen == inputlen) { // perfect match
     821                                return false;
     822                        }
     823                        if (commandlen > inputlen) { // possible match
     824                                // no previous match
     825                                if (matchlen == 0) {
     826                                        strcpy(match, _dcmds[i].name + inputlen);
     827                                        matchlen = commandlen - inputlen;
     828                                } else {
     829                                        // take common prefix of previous match and this command
     830                                        unsigned int j;
     831                                        for (j = 0; j < matchlen; j++) {
     832                                                if (match[j] != _dcmds[i].name[inputlen + j]) break;
     833                                        }
     834                                        matchlen = j;
     835                                }
     836                        }
     837                }
     838        }
     839        if (matchlen == 0)
     840                return false;
     841
     842        completion = new char[matchlen+1];
     843        memcpy(completion, match, matchlen);
     844        completion[matchlen+1] = 0;
     845        return true;
     846}
     847
  • scumm/debugger.h

    RCS file: /cvsroot/scummvm/scummvm/scumm/debugger.h,v
    retrieving revision 1.18
    diff -u -r1.18 debugger.h
     
    9696
    9797#ifdef USE_CONSOLE
    9898        static bool debuggerInputCallback(ConsoleDialog *console, const char *input, void *refCon);
     99        static bool debuggerCompletionCallback(ConsoleDialog *console, const char *input, char*& completion, void *refCon);
    99100#endif
     101
     102        bool TabComplete(const char *input, char*& completion);
     103
    100104};
    101105
    102106#endif