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
non-interactively when specified on the command line. The supported
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"
Evaluate an address expression and show both its value, and the result
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 *start;
char *rewrite;
char *end;
int qstate = 0;
int qval = 0;
if (!text)
return NULL;
@ -97,14 +100,90 @@ char *get_arg(char **text)
if (!*start)
return NULL;
/* We've found the start of the argument. Parse it. */
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++;
if (*end)
while (*end && isspace(*end))
*(end++) = 0;
*rewrite = 0;
*text = end;
return start;
}