Allow quoted strings in commands.

This commit is contained in:
Daniel Beer 2010-04-10 16:33:21 +12:00
parent 7733889703
commit 48ca1a50d5
2 changed files with 89 additions and 5 deletions

View File

@ -92,6 +92,11 @@ Display a brief help message and exit.
MSPDebug can accept commands either through an interactive prompt, or MSPDebug can accept commands either through an interactive prompt, or
non-interactively when specified on the command line. The supported non-interactively when specified on the command line. The supported
commands are listed below. commands are listed below.
Commands take arguments separated by spaces. Any text string enclosed
in double-quotation marks is considered to be a single argument, even
if it contains space characters. Within a quoted string, the usual
C-style backslash substitutions can be used.
.IP "\fB=\fR \fIexpression\fR" .IP "\fB=\fR \fIexpression\fR"
Evaluate an address expression and show both its value, and the result Evaluate an address expression and show both its value, and the result
when the value is looked up in reverse in the current symbol when the value is looked up in reverse in the current symbol

89
parse.c
View File

@ -85,7 +85,10 @@ int is_interactive(void)
char *get_arg(char **text) char *get_arg(char **text)
{ {
char *start; char *start;
char *rewrite;
char *end; char *end;
int qstate = 0;
int qval = 0;
if (!text) if (!text)
return NULL; return NULL;
@ -97,14 +100,90 @@ char *get_arg(char **text)
if (!*start) if (!*start)
return NULL; return NULL;
/* We've found the start of the argument. Parse it. */
end = start; end = start;
while (*end && !isspace(*end)) rewrite = start;
while (*end) {
switch (qstate) {
case 0: /* Bare */
if (isspace(*end))
goto out;
else if (*end == '"')
qstate = 1;
else
*(rewrite++) = *end;
break;
case 1: /* In quotes */
if (*end == '"')
qstate = 0;
else if (*end == '\\')
qstate = 2;
else
*(rewrite++) = *end;
break;
case 2: /* Backslash */
if (*end == '\\')
*(rewrite++) = '\\';
else if (*end == 'n')
*(rewrite++) = '\n';
else if (*end == 'r')
*(rewrite++) = '\r';
else if (*end == 't')
*(rewrite++) = '\t';
else if (*end >= '0' && *end <= '3') {
qstate = 30;
qval = *end - '0';
} else if (*end == 'x') {
qstate = 40;
qval = 0;
} else
*(rewrite++) = *end;
if (qstate == 2)
qstate = 1;
break;
case 30: /* Octal */
case 31:
if (*end >= '0' && *end <= '7')
qval = (qval << 3) | (*end - '0');
if (qstate == 31) {
*(rewrite++) = qval;
qstate = 1;
} else {
qstate++;
}
break;
case 40: /* Hex */
case 41:
if (isdigit(*end))
qval = (qval << 4) | (*end - '0');
else if (isupper(*end))
qval = (qval << 4) | (*end - 'A' + 10);
else if (islower(*end))
qval = (qval << 4) | (*end - 'a' + 10);
if (qstate == 41) {
*(rewrite++) = qval;
qstate = 1;
} else {
qstate++;
}
break;
}
end++;
}
out:
/* Leave the text pointer at the end of the next argument */
while (*end && isspace(*end))
end++; end++;
if (*end) *rewrite = 0;
while (*end && isspace(*end))
*(end++) = 0;
*text = end; *text = end;
return start; return start;
} }