Support double-quoted arguments in CLI

When a quoted command argument is seen, it will take all characters
until the next double-quote (no supported escape sequence here for
simplicity).
All white spaces (space, tab, etc.) are then removed from the argument.

This means that the following command should behave the same:
```
pm3> wiegand encode --fc 101 --cn 1337
pm3> wiegand encode --fc "1 0 1" --cn "1    3    3   7"
```

Or a more useful example, when copy/pasting hex formatted values:
```
pm3> hf iclass calcnewkey --old 1122334455667788 --new 2233445566778899
pm3> hf iclass calcnewkey --old "11 22 33 44 55 66 77 88" --new "22 33 44 55 66 77 88 99"
```
This commit is contained in:
Jean-Michel Picod 2023-10-18 10:27:12 +02:00
commit 3b7cec365a

View file

@ -147,6 +147,7 @@ enum ParserState {
PS_FIRST,
PS_ARGUMENT,
PS_OPTION,
PS_QUOTE,
};
#define isSpace(c)(c == ' ' || c == '\t')
@ -195,6 +196,10 @@ int CLIParserParseStringEx(CLIParserContext *ctx, const char *str, void *vargtab
case PS_ARGUMENT:
if (state == PS_FIRST)
state = PS_ARGUMENT;
if (str[i] == '"') {
state = PS_QUOTE;
break;
}
if (isSpace(str[i])) {
spaceptr = bufptr;
state = PS_FIRST;
@ -215,6 +220,35 @@ int CLIParserParseStringEx(CLIParserContext *ctx, const char *str, void *vargtab
*bufptr = str[i];
bufptr++;
break;
case PS_QUOTE:
if (str[i] == '"') {
// Now let's compact the argument by removing spaces
if (spaceptr != NULL) {
// We've seen at least 1 space
char *cur_ptr = spaceptr;
while (spaceptr < bufptr) {
if (isSpace(*spaceptr) == false) {
*cur_ptr = *spaceptr;
cur_ptr++;
}
spaceptr++;
}
*cur_ptr = 0;
// Rollback bufptr
bufptr = cur_ptr;
spaceptr = NULL;
}
*bufptr = 0x00;
state = PS_FIRST;
} else {
if (isSpace(str[i]) && spaceptr == NULL) {
// Store first encountered space for later
spaceptr = bufptr;
}
*bufptr = str[i];
}
bufptr++;
break;
}
if (bufptr > bufptrend) {
PrintAndLogEx(ERR, "ERROR: Line too long\n");