GUI: Add support for double quoted parameters in debugger

This commit is contained in:
Paul Gilbert 2017-09-04 10:04:26 -04:00
parent 0b19ebe7b2
commit 67090d3cda
2 changed files with 59 additions and 9 deletions

View File

@ -288,17 +288,10 @@ bool Debugger::handleCommand(int argc, const char **argv, bool &result) {
bool Debugger::parseCommand(const char *inputOrig) {
int num_params = 0;
const char *param[256];
char *input = strdup(inputOrig); // One of the rare occasions using strdup is OK (although avoiding strtok might be more elegant here).
// Parse out any params
char *tok = strtok(input, " ");
if (tok) {
do {
param[num_params++] = tok;
} while ((tok = strtok(NULL, " ")) != NULL);
} else {
param[num_params++] = input;
}
char *input = strdup(inputOrig); // One of the rare occasions using strdup is OK (although avoiding strtok might be more elegant here).
splitCommand(input, num_params, &param[0]);
// Handle commands first
bool result;
@ -398,6 +391,57 @@ bool Debugger::parseCommand(const char *inputOrig) {
return true;
}
void Debugger::splitCommand(char *input, int &argc, const char **argv) {
byte c;
enum states { DULL, IN_WORD, IN_STRING } state = DULL;
const char *paramStart = nullptr;
argc = 0;
for (char *p = input; *p; ++p) {
c = (byte)*p;
switch (state) {
case DULL:
// not in a word, not in a double quoted string
if (isspace(c))
break;
// not a space -- if it's a double quote we go to IN_STRING, else to IN_WORD
if (c == '"') {
state = IN_STRING;
paramStart = p + 1; // word starts at *next* char, not this one
} else {
state = IN_WORD;
paramStart = p; // word starts here
}
break;
case IN_STRING:
// we're in a double quoted string, so keep going until we hit a close "
if (c == '"') {
// Add entire quoted string to parameter list
*p = '\0';
argv[argc++] = paramStart;
state = DULL; // back to "not in word, not in string" state
}
break;
case IN_WORD:
// we're in a word, so keep going until we get to a space
if (isspace(c)) {
*p = '\0';
argv[argc++] = paramStart;
state = DULL; // back to "not in word, not in string" state
}
break;
}
}
if (state != DULL)
// Add in final parameter
argv[argc++] = paramStart;
}
// returns true if something has been completed
// completion has to be delete[]-ed then
bool Debugger::tabComplete(const char *input, Common::String &completion) const {

View File

@ -204,6 +204,12 @@ protected:
private:
void enter();
/**
* Splits up the input into individual parameters
* @remarks Adapted from code provided by torek on StackOverflow
*/
void splitCommand(char *input, int &argc, const char **argv);
bool parseCommand(const char *input);
bool tabComplete(const char *input, Common::String &completion) const;