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:
Filipe Brandenburger 2015-11-05 21:51:24 -08:00
parent 93de9eb76d
commit 27fc921b65

View file

@ -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;
}
} }
} }
} }