From: Yu Watanabe Date: Sun, 1 Sep 2024 21:11:32 +0000 (+0900) Subject: conf-parser: several cleanups for DEFINE_CONFIG_PARSE_ENUMV() macro X-Git-Tag: v257-rc1~573^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3c8dc3a3e0023fe347c7b513a3fc560530bee273;p=thirdparty%2Fsystemd.git conf-parser: several cleanups for DEFINE_CONFIG_PARSE_ENUMV() macro - use GREEDY_REALLOC() and FOREACH_ARRAY(), - do not set an array with only terminating 'invalid' value. Note, this macro is only used by parsing NamePolicy= and AlternativeNamesPolicy= in .link files. and udevd correctly handles both an empty array and an array with only 'invalid'. Hence, this does not change any behavior. --- diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h index 3e00666e775..89870ccffca 100644 --- a/src/shared/conf-parser.h +++ b/src/shared/conf-parser.h @@ -384,22 +384,14 @@ typedef enum ConfigParseStringFlags { CONFIG_PARSER_PROTOTYPE(function) { \ type **enums = ASSERT_PTR(data); \ _cleanup_free_ type *xs = NULL; \ - size_t i = 0; \ + size_t n = 0; \ int r; \ \ - assert(filename); \ assert(lvalue); \ - assert(rvalue); \ - \ - xs = new0(type, 1); \ - if (!xs) \ - return -ENOMEM; \ - \ - *xs = invalid; \ \ for (const char *p = rvalue;;) { \ _cleanup_free_ char *en = NULL; \ - type x, *new_xs; \ + type x; \ \ r = extract_first_word(&p, &en, NULL, 0); \ if (r < 0) \ @@ -415,27 +407,33 @@ typedef enum ConfigParseStringFlags { continue; \ } \ \ - for (type *ys = xs; x != invalid && *ys != invalid; ys++) \ - if (*ys == x) { \ + FOREACH_ARRAY(i, xs, n) \ + if (*i == x) { \ log_syntax(unit, LOG_NOTICE, filename, line, 0, \ "Duplicate entry %s in %s=, ignoring.", \ en, lvalue); \ x = invalid; \ + break; \ } \ \ if (x == invalid) \ continue; \ \ - *(xs + i) = x; \ - new_xs = realloc(xs, (++i + 1) * sizeof(type)); \ - if (new_xs) \ - xs = new_xs; \ - else \ + /* Allocate one more for the trailing 'invalid'. */ \ + if (!GREEDY_REALLOC(xs, n + 2)) \ return log_oom(); \ \ - *(xs + i) = invalid; \ + xs[n++] = x; \ + } \ + \ + if (n <= 0) { \ + /* An empty string, or invalid values only. */ \ + *enums = mfree(*enums); \ + return 1; \ } \ \ + /* Terminate with 'invalid' */ \ + xs[n] = invalid; \ free_and_replace(*enums, xs); \ return 1; \ }