diff options
author | Filipe Brandenburger <filbranden@google.com> | 2015-11-05 21:51:24 -0800 |
---|---|---|
committer | Filipe Brandenburger <filbranden@google.com> | 2015-11-05 21:51:24 -0800 |
commit | 27fc921b658adc5baa988c4c213888b016a60b18 (patch) | |
tree | 426b33d9cad99e3f33104b5a5e1d6bffaf3ef446 /src | |
parent | 93de9eb76d628cf731120d97332e03600c167271 (diff) |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/basic/extract-word.c | 75 |
1 files changed, 43 insertions, 32 deletions
diff --git a/src/basic/extract-word.c b/src/basic/extract-word.c index b0056a8485..67511a32e1 100644 --- a/src/basic/extract-word.c +++ b/src/basic/extract-word.c @@ -121,45 +121,56 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra backslash = false; } else if (quote) { /* inside either single or double quotes */ - if (c == 0) { - if (flags & EXTRACT_RELAX) - goto finish_force_terminate; - return -EINVAL; - } else if (c == quote) /* found the end quote */ - quote = 0; - else if (c == '\\') - backslash = true; - else { - if (!GREEDY_REALLOC(s, allocated, sz+2)) - return -ENOMEM; + for (;; (*p) ++, c = **p) { + if (c == 0) { + if (flags & EXTRACT_RELAX) + goto finish_force_terminate; + return -EINVAL; + } else if (c == quote) { /* found the end quote */ + quote = 0; + break; + } else if (c == '\\') { + backslash = true; + break; + } else { + if (!GREEDY_REALLOC(s, allocated, sz+2)) + return -ENOMEM; - s[sz++] = c; + s[sz++] = c; + } } } else if (separator) { - if (c == 0) - goto finish_force_terminate; - if (!strchr(separators, c)) - goto finish; + for (;; (*p) ++, c = **p) { + if (c == 0) + goto finish_force_terminate; + if (!strchr(separators, c)) + goto finish; + } } else { - if (c == 0) - goto finish_force_terminate; - else if ((c == '\'' || c == '"') && (flags & EXTRACT_QUOTES)) - quote = c; - else if (c == '\\') - backslash = true; - else if (strchr(separators, c)) { - if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) { - (*p) ++; - goto finish_force_next; - } - separator = true; - } else { - if (!GREEDY_REALLOC(s, allocated, sz+2)) - return -ENOMEM; + for (;; (*p) ++, c = **p) { + if (c == 0) + goto finish_force_terminate; + else if ((c == '\'' || c == '"') && (flags & EXTRACT_QUOTES)) { + quote = c; + break; + } else if (c == '\\') { + backslash = true; + break; + } else if (strchr(separators, c)) { + if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) { + (*p) ++; + goto finish_force_next; + } + separator = true; + break; + } else { + if (!GREEDY_REALLOC(s, allocated, sz+2)) + return -ENOMEM; - s[sz++] = c; + s[sz++] = c; + } } } } |