diff options
author | Tom Gundersen <teg@jklm.no> | 2013-10-29 13:03:13 +0100 |
---|---|---|
committer | Tom Gundersen <teg@jklm.no> | 2013-10-29 14:17:57 +0100 |
commit | 916484f54d084e11a11458716b2e0bbdf4822d40 (patch) | |
tree | 8fe0ef431c20c8a3807c9ed69e651890d276b1f8 | |
parent | 0b99c9f8f0cbfe9ab3de443cb6f94ecd7d21eae3 (diff) |
conf-parser: add macro for ENUMV
Parses a whitespace separated list of strings into a vector of enums.
-rw-r--r-- | src/shared/conf-parser.h | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h index 9435d54b11..f988e1c443 100644 --- a/src/shared/conf-parser.h +++ b/src/shared/conf-parser.h @@ -149,3 +149,64 @@ int log_syntax_internal(const char *unit, int level, *i = x; \ return 0; \ } + +#define DEFINE_CONFIG_PARSE_ENUMV(function,name,type,invalid,msg) \ + int function(const char *unit, \ + const char *filename, \ + unsigned line, \ + const char *section, \ + const char *lvalue, \ + int ltype, \ + const char *rvalue, \ + void *data, \ + void *userdata) { \ + \ + type **enums = data, *xs, x, *ys; \ + char *w, *state; \ + size_t l, i = 0; \ + \ + assert(filename); \ + assert(lvalue); \ + assert(rvalue); \ + assert(data); \ + \ + xs = new0(type, 1); \ + *xs = invalid; \ + \ + FOREACH_WORD(w, l, rvalue, state) { \ + _cleanup_free_ char *en = NULL; \ + \ + en = strndup(w, l); \ + if (!en) \ + return -ENOMEM; \ + \ + if ((x = name##_from_string(en)) < 0) { \ + log_syntax(unit, LOG_ERR, filename, line, \ + -x, msg ", ignoring: %s", en); \ + continue; \ + } \ + \ + for (ys = xs; x != invalid && *ys != invalid; ys++) { \ + if (*ys == x) { \ + log_syntax(unit, LOG_ERR, filename, \ + line, -x, \ + "Duplicate entry, ignoring: %s", \ + en); \ + x = invalid; \ + } \ + } \ + \ + if (x == invalid) \ + continue; \ + \ + *(xs + i) = x; \ + xs = realloc(xs, ++i + 1); \ + if (!xs) \ + return -ENOMEM; \ + *(xs + i) = invalid; \ + } \ + \ + free(*enums); \ + *enums = xs; \ + return 0; \ + } |