extract-word: Do not re-evaluate the state on each parsed character
Use inner loops to keep processing the same state, except when there is a state change, then break back to the outer loop so that the correct branch can be selected again. Tested that no regressions were introduced in test-extract-word.
This commit is contained in:
parent
93de9eb76d
commit
27fc921b65
|
@ -121,45 +121,56 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
|
||||||
backslash = false;
|
backslash = false;
|
||||||
|
|
||||||
} else if (quote) { /* inside either single or double quotes */
|
} else if (quote) { /* inside either single or double quotes */
|
||||||
if (c == 0) {
|
for (;; (*p) ++, c = **p) {
|
||||||
if (flags & EXTRACT_RELAX)
|
if (c == 0) {
|
||||||
goto finish_force_terminate;
|
if (flags & EXTRACT_RELAX)
|
||||||
return -EINVAL;
|
goto finish_force_terminate;
|
||||||
} else if (c == quote) /* found the end quote */
|
return -EINVAL;
|
||||||
quote = 0;
|
} else if (c == quote) { /* found the end quote */
|
||||||
else if (c == '\\')
|
quote = 0;
|
||||||
backslash = true;
|
break;
|
||||||
else {
|
} else if (c == '\\') {
|
||||||
if (!GREEDY_REALLOC(s, allocated, sz+2))
|
backslash = true;
|
||||||
return -ENOMEM;
|
break;
|
||||||
|
} else {
|
||||||
|
if (!GREEDY_REALLOC(s, allocated, sz+2))
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
s[sz++] = c;
|
s[sz++] = c;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (separator) {
|
} else if (separator) {
|
||||||
if (c == 0)
|
for (;; (*p) ++, c = **p) {
|
||||||
goto finish_force_terminate;
|
if (c == 0)
|
||||||
if (!strchr(separators, c))
|
goto finish_force_terminate;
|
||||||
goto finish;
|
if (!strchr(separators, c))
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (c == 0)
|
for (;; (*p) ++, c = **p) {
|
||||||
goto finish_force_terminate;
|
if (c == 0)
|
||||||
else if ((c == '\'' || c == '"') && (flags & EXTRACT_QUOTES))
|
goto finish_force_terminate;
|
||||||
quote = c;
|
else if ((c == '\'' || c == '"') && (flags & EXTRACT_QUOTES)) {
|
||||||
else if (c == '\\')
|
quote = c;
|
||||||
backslash = true;
|
break;
|
||||||
else if (strchr(separators, c)) {
|
} else if (c == '\\') {
|
||||||
if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
|
backslash = true;
|
||||||
(*p) ++;
|
break;
|
||||||
goto finish_force_next;
|
} else if (strchr(separators, c)) {
|
||||||
}
|
if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
|
||||||
separator = true;
|
(*p) ++;
|
||||||
} else {
|
goto finish_force_next;
|
||||||
if (!GREEDY_REALLOC(s, allocated, sz+2))
|
}
|
||||||
return -ENOMEM;
|
separator = true;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
if (!GREEDY_REALLOC(s, allocated, sz+2))
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
s[sz++] = c;
|
s[sz++] = c;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue