aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gui/debugger.cpp62
-rw-r--r--gui/debugger.h6
2 files changed, 59 insertions, 9 deletions
diff --git a/gui/debugger.cpp b/gui/debugger.cpp
index 7595efcfbc..ce994a4938 100644
--- a/gui/debugger.cpp
+++ b/gui/debugger.cpp
@@ -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 {
diff --git a/gui/debugger.h b/gui/debugger.h
index bc9306c1de..b12bd2761e 100644
--- a/gui/debugger.h
+++ b/gui/debugger.h
@@ -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;