diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/basic/extract-word.c | 141 | ||||
-rw-r--r-- | src/core/load-fragment.c | 22 | ||||
-rw-r--r-- | src/core/manager.c | 1 |
3 files changed, 85 insertions, 79 deletions
diff --git a/src/basic/extract-word.c b/src/basic/extract-word.c index 6721b85c0a..ff6d211ef4 100644 --- a/src/basic/extract-word.c +++ b/src/basic/extract-word.c @@ -29,54 +29,51 @@ 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: diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 28b90eccc1..79cabd26e7 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -111,22 +111,28 @@ int config_parse_unit_deps(const char *unit, UnitDependency d = ltype; Unit *u = userdata; - const char *word, *state; - size_t l; + const char *p; assert(filename); assert(lvalue); assert(rvalue); - FOREACH_WORD_QUOTED(word, l, rvalue, state) { - _cleanup_free_ char *t = NULL, *k = NULL; + p = rvalue; + for(;;) { + _cleanup_free_ char *word = NULL, *k = NULL; int r; - t = strndup(word, l); - if (!t) + r = extract_first_word(&p, &word, NULL, 0); + if (r == 0) + break; + if (r == -ENOMEM) return log_oom(); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Invalid syntax, ignoring: %s", rvalue); + break; + } - r = unit_name_printf(u, t, &k); + r = unit_name_printf(u, word, &k); if (r < 0) { log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m"); continue; @@ -136,8 +142,6 @@ int config_parse_unit_deps(const char *unit, if (r < 0) log_syntax(unit, LOG_ERR, filename, line, r, "Failed to add dependency on %s, ignoring: %m", k); } - if (!isempty(state)) - log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid syntax, ignoring."); return 0; } diff --git a/src/core/manager.c b/src/core/manager.c index b13663e702..7c3a020c4a 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -2024,7 +2024,6 @@ int manager_loop(Manager *m) { /* Yay, something is going seriously wrong, pause a little */ log_warning("Looping too fast. Throttling execution a little."); sleep(1); - continue; } if (manager_dispatch_load_queue(m) > 0) |