chiark / gitweb /
log: move log_syntax() into src/shared/log.c, and make it more similar to the other...
[elogind.git] / src / shared / conf-parser.h
index d37029f083f1644fb60d388266b2158d29bc8b5b..6152ee33b93af8bb28113c84bef6850c8e32e24b 100644 (file)
@@ -1,7 +1,6 @@
 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
 
-#ifndef fooconfparserhfoo
-#define fooconfparserhfoo
+#pragma once
 
 /***
   This file is part of systemd.
 #include <stdio.h>
 #include <stdbool.h>
 
+#include "macro.h"
+
 /* An abstract parser for simple, line based, shallow configuration
  * files consisting of variable assignments only. */
 
 /* Prototype for a parser for a specific configuration setting */
-typedef int (*ConfigParserCallback)(
-                const char *filename,
-                unsigned line,
-                const char *section,
-                const char *lvalue,
-                int ltype,
-                const char *rvalue,
-                void *data,
-                void *userdata);
+typedef int (*ConfigParserCallback)(const char *unit,
+                                    const char *filename,
+                                    unsigned line,
+                                    const char *section,
+                                    unsigned section_line,
+                                    const char *lvalue,
+                                    int ltype,
+                                    const char *rvalue,
+                                    void *data,
+                                    void *userdata);
 
 /* Wraps information for parsing a specific configuration variable, to
  * be stored in a simple array */
@@ -50,7 +52,7 @@ typedef struct ConfigTableItem {
 } ConfigTableItem;
 
 /* Wraps information for parsing a specific configuration variable, to
- * ve srored in a gperf perfect hashtable */
+ * be stored in a gperf perfect hashtable */
 typedef struct ConfigPerfItem {
         const char *section_and_lvalue; /* Section + "." + name of the variable */
         ConfigParserCallback parse;     /* Function that is called to parse the variable's value */
@@ -63,7 +65,7 @@ typedef const ConfigPerfItem* (*ConfigPerfItemLookup)(const char *section_and_lv
 
 /* Prototype for a generic high-level lookup function */
 typedef int (*ConfigItemLookup)(
-                void *table,
+                const void *table,
                 const char *section,
                 const char *lvalue,
                 ConfigParserCallback *func,
@@ -73,47 +75,68 @@ typedef int (*ConfigItemLookup)(
 
 /* Linear table search implementation of ConfigItemLookup, based on
  * ConfigTableItem arrays */
-int config_item_table_lookup(void *table, const char *section, const char *lvalue, ConfigParserCallback *func, int *ltype, void **data, void *userdata);
+int config_item_table_lookup(const void *table, const char *section, const char *lvalue, ConfigParserCallback *func, int *ltype, void **data, void *userdata);
 
 /* gperf implementation of ConfigItemLookup, based on gperf
  * ConfigPerfItem tables */
-int config_item_perf_lookup(void *table, const char *section, const char *lvalue, ConfigParserCallback *func, int *ltype, void **data, void *userdata);
-
-int config_parse(
-                const char *filename,
-                FILE *f,
-                const char *sections,  /* nulstr */
-                ConfigItemLookup lookup,
-                void *table,
-                bool relaxed,
-                void *userdata);
+int config_item_perf_lookup(const void *table, const char *section, const char *lvalue, ConfigParserCallback *func, int *ltype, void **data, void *userdata);
+
+int config_parse(const char *unit,
+                 const char *filename,
+                 FILE *f,
+                 const char *sections,  /* nulstr */
+                 ConfigItemLookup lookup,
+                 const void *table,
+                 bool relaxed,
+                 bool allow_include,
+                 bool warn,
+                 void *userdata);
+
+int config_parse_many(const char *conf_file,      /* possibly NULL */
+                      const char *conf_file_dirs, /* nulstr */
+                      const char *sections,       /* nulstr */
+                      ConfigItemLookup lookup,
+                      const void *table,
+                      bool relaxed,
+                      void *userdata);
 
 /* Generic parsers */
-int config_parse_int(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_unsigned(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_long(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_uint64(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_bytes_size(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_bytes_off(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_bool(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_tristate(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_string(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_path(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_strv(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_path_strv(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_usec(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_mode(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_int(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_unsigned(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_long(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_uint64(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_double(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line,  const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_iec_size(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_si_size(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_iec_off(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_bool(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_string(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_path(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_strv(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_sec(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_nsec(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_log_facility(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_log_level(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+
+#define log_invalid_utf8(unit, level, config_file, config_line, error, rvalue) \
+        do {                                                            \
+                _cleanup_free_ char *_p = utf8_escape_invalid(rvalue);  \
+                log_syntax(unit, level, config_file, config_line, error, \
+                           "String is not UTF-8 clean, ignoring assignment: %s", strna(_p)); \
+        } while(false)
 
 #define DEFINE_CONFIG_PARSE_ENUM(function,name,type,msg)                \
-        int function(                                                   \
-                        const char *filename,                           \
-                        unsigned line,                                  \
-                        const char *section,                            \
-                        const char *lvalue,                             \
-                        int ltype,                                      \
-                        const char *rvalue,                             \
-                        void *data,                                     \
-                        void *userdata) {                               \
+        int function(const char *unit,                                  \
+                     const char *filename,                              \
+                     unsigned line,                                     \
+                     const char *section,                               \
+                     unsigned section_line,                             \
+                     const char *lvalue,                                \
+                     int ltype,                                         \
+                     const char *rvalue,                                \
+                     void *data,                                        \
+                     void *userdata) {                                  \
                                                                         \
                 type *i = data, x;                                      \
                                                                         \
@@ -123,13 +146,83 @@ int config_parse_mode(const char *filename, unsigned line, const char *section,
                 assert(data);                                           \
                                                                         \
                 if ((x = name##_from_string(rvalue)) < 0) {             \
-                        log_error("[%s:%u] " msg ", ignoring: %s", filename, line, rvalue); \
+                        log_syntax(unit, LOG_ERR, filename, line, -x,   \
+                                   msg ", ignoring: %s", rvalue);       \
                         return 0;                                       \
                 }                                                       \
                                                                         \
                 *i = x;                                                 \
-                                                                        \
                 return 0;                                               \
         }
 
-#endif
+#define DEFINE_CONFIG_PARSE_ENUMV(function,name,type,invalid,msg)              \
+        int function(const char *unit,                                         \
+                     const char *filename,                                     \
+                     unsigned line,                                            \
+                     const char *section,                                      \
+                     unsigned section_line,                                    \
+                     const char *lvalue,                                       \
+                     int ltype,                                                \
+                     const char *rvalue,                                       \
+                     void *data,                                               \
+                     void *userdata) {                                         \
+                                                                               \
+                type **enums = data, x, *ys;                                   \
+                _cleanup_free_ type *xs = NULL;                                \
+                const char *word, *state;                                      \
+                size_t l, i = 0;                                               \
+                                                                               \
+                assert(filename);                                              \
+                assert(lvalue);                                                \
+                assert(rvalue);                                                \
+                assert(data);                                                  \
+                                                                               \
+                xs = new0(type, 1);                                            \
+                if(!xs)                                                        \
+                        return -ENOMEM;                                        \
+                                                                               \
+                *xs = invalid;                                                 \
+                                                                               \
+                FOREACH_WORD(word, l, rvalue, state) {                         \
+                        _cleanup_free_ char *en = NULL;                        \
+                        type *new_xs;                                          \
+                                                                               \
+                        en = strndup(word, 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;                                         \
+                        new_xs = realloc(xs, (++i + 1) * sizeof(type));        \
+                        if (new_xs)                                            \
+                                xs = new_xs;                                   \
+                        else                                                   \
+                                return -ENOMEM;                                \
+                                                                               \
+                        *(xs + i) = invalid;                                   \
+                }                                                              \
+                                                                               \
+                free(*enums);                                                  \
+                *enums = xs;                                                   \
+                xs = NULL;                                                     \
+                                                                               \
+                return 0;                                                      \
+        }