summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Gundersen <teg@jklm.no>2013-10-29 13:03:13 +0100
committerTom Gundersen <teg@jklm.no>2013-10-29 14:17:57 +0100
commit916484f54d084e11a11458716b2e0bbdf4822d40 (patch)
tree8fe0ef431c20c8a3807c9ed69e651890d276b1f8
parent0b99c9f8f0cbfe9ab3de443cb6f94ecd7d21eae3 (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.h61
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; \
+ }