Getting the next word respects quoting and escaping.
Use double quotes ("). They can be interspersed with
other whitespace characters, just like shell quoting.
A backslash (\) always escapes the next character.
The end of the stream always terminates the word.
Add AutoText struct to unit test utilities, to easily
make spv_text_t values and reference them as spv_text values.
diff --git a/source/text.cpp b/source/text.cpp
index 793bb58..88f6bc8 100644
--- a/source/text.cpp
+++ b/source/text.cpp
@@ -151,20 +151,34 @@
*endPosition = *startPosition;
+ bool quoting = false;
+ bool escaping = false;
+
// NOTE: Assumes first character is not white space!
while (true) {
- switch (text->str[endPosition->index]) {
- case ' ':
- case ';':
- case '\t':
- case '\n':
- case '\0': { // NOTE: End of word found!
- word.assign(text->str + startPosition->index,
- (size_t)(endPosition->index - startPosition->index));
- return SPV_SUCCESS;
+ const char ch = text->str[endPosition->index];
+ if (ch == '\\')
+ escaping = !escaping;
+ else {
+ switch (ch) {
+ case '"':
+ if (!escaping) quoting = !quoting;
+ break;
+ case ' ':
+ case ';':
+ case '\t':
+ case '\n':
+ if (escaping || quoting) break;
+ // Fall through.
+ case '\0': { // NOTE: End of word found!
+ word.assign(text->str + startPosition->index,
+ (size_t)(endPosition->index - startPosition->index));
+ return SPV_SUCCESS;
+ }
+ default:
+ break;
}
- default:
- break;
+ escaping = false;
}
endPosition->column++;