From 27fc921b658adc5baa988c4c213888b016a60b18 Mon Sep 17 00:00:00 2001 From: Filipe Brandenburger Date: Thu, 5 Nov 2015 21:51:24 -0800 Subject: [PATCH] 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. --- src/basic/extract-word.c | 75 +++++++++++++++++++++++----------------- 1 file 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; + } } } }