]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #1793 from filbranden/extract1
authorLennart Poettering <lennart@poettering.net>
Tue, 10 Nov 2015 18:43:09 +0000 (19:43 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 10 Nov 2015 18:43:09 +0000 (19:43 +0100)
More refactorings in extract_first_word

src/basic/extract-word.c

index 6721b85c0ad396fc77b01bb9becdce469a4bed32..ff6d211ef4c6a01fc0ca1b05e685dcd0e3dab707 100644 (file)
 int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags) {
         _cleanup_free_ char *s = NULL;
         size_t allocated = 0, sz = 0;
+        char c;
         int r;
 
         char quote = 0;                 /* 0 or ' or " */
         bool backslash = false;         /* whether we've just seen a backslash */
-        bool separator = false;         /* whether we've just seen a separator */
-        bool start = true;              /* false means we're looking at a value */
 
         assert(p);
         assert(ret);
 
-        if (!separators)
-                separators = WHITESPACE;
-
         /* Bail early if called after last value or with no input */
         if (!*p)
                 goto finish_force_terminate;
+        c = **p;
+
+        if (!separators)
+                separators = WHITESPACE;
 
         /* Parses the first word of a string, and returns it in
          * *ret. Removes all quotes in the process. When parsing fails
          * (because of an uneven number of quotes or similar), leaves
          * the pointer *p at the first invalid character. */
 
-        for (;;) {
-                char c = **p;
-
-                if (start) {
-                        if (flags & EXTRACT_DONT_COALESCE_SEPARATORS)
-                                if (!GREEDY_REALLOC(s, allocated, sz+1))
-                                        return -ENOMEM;
+        if (flags & EXTRACT_DONT_COALESCE_SEPARATORS)
+                if (!GREEDY_REALLOC(s, allocated, sz+1))
+                        return -ENOMEM;
 
-                        if (c == 0)
-                                goto finish_force_terminate;
-                        else if (strchr(separators, c)) {
+        for (;; (*p) ++, c = **p) {
+                if (c == 0)
+                        goto finish_force_terminate;
+                else if (strchr(separators, c)) {
+                        if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
                                 (*p) ++;
-                                if (flags & EXTRACT_DONT_COALESCE_SEPARATORS)
-                                        goto finish_force_next;
-                                continue;
+                                goto finish_force_next;
                         }
-
+                } else {
                         /* We found a non-blank character, so we will always
                          * want to return a string (even if it is empty),
                          * allocate it here. */
                         if (!GREEDY_REALLOC(s, allocated, sz+1))
                                 return -ENOMEM;
-
-                        start = false;
+                        break;
                 }
+        }
 
+        for (;; (*p) ++, c = **p) {
                 if (backslash) {
                         if (!GREEDY_REALLOC(s, allocated, sz+7))
                                 return -ENOMEM;
@@ -107,67 +104,73 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
                                         if (flags & EXTRACT_CUNESCAPE_RELAX) {
                                                 s[sz++] = '\\';
                                                 s[sz++] = c;
-                                                goto end_escape;
-                                        }
-                                        return -EINVAL;
+                                        } else
+                                                return -EINVAL;
+                                } else {
+                                        (*p) += r - 1;
+
+                                        if (c != 0)
+                                                s[sz++] = c; /* normal explicit char */
+                                        else
+                                                sz += utf8_encode_unichar(s + sz, u); /* unicode chars we'll encode as utf8 */
                                 }
-
-                                (*p) += r - 1;
-
-                                if (c != 0)
-                                        s[sz++] = c; /* normal explicit char */
-                                else
-                                        sz += utf8_encode_unichar(s + sz, u); /* unicode chars we'll encode as utf8 */
                         } else
                                 s[sz++] = c;
 
-end_escape:
                         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;
-
-                                s[sz++] = c;
+                        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;
+                                }
                         }
 
-                } else if (separator) {
-                        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;
+                                        }
+                                        /* Skip additional coalesced separators. */
+                                        for (;; (*p) ++, c = **p) {
+                                                if (c == 0)
+                                                        goto finish_force_terminate;
+                                                if (!strchr(separators, c))
+                                                        break;
+                                        }
+                                        goto finish;
 
-                                s[sz++] = c;
+                                } else {
+                                        if (!GREEDY_REALLOC(s, allocated, sz+2))
+                                                return -ENOMEM;
+
+                                        s[sz++] = c;
+                                }
                         }
                 }
-
-                (*p) ++;
         }
 
 finish_force_terminate: