X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=src%2Fshared%2Fconf-parser.h;h=17b4bdf1a26fca91110dcc405ff3cc192414bda2;hb=7b61ce3c44ef5908e817009ce4f9d2a7a37722be;hp=094b9cbc447467d2126edb387fb94fbcb108a52e;hpb=9fc03455519878d54bfd8098eeb49972ade3ee29;p=thirdparty%2Fsystemd.git diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h index 094b9cbc447..17b4bdf1a26 100644 --- a/src/shared/conf-parser.h +++ b/src/shared/conf-parser.h @@ -1,12 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once -/*** - This file is part of systemd. - - Copyright 2010 Lennart Poettering -***/ - #include #include #include @@ -20,23 +14,32 @@ /* An abstract parser for simple, line based, shallow configuration files consisting of variable assignments only. */ typedef enum ConfigParseFlags { - CONFIG_PARSE_RELAXED = 1U << 0, - CONFIG_PARSE_ALLOW_INCLUDE = 1U << 1, - CONFIG_PARSE_WARN = 1U << 2, - CONFIG_PARSE_REFUSE_BOM = 1U << 3, + CONFIG_PARSE_RELAXED = 1 << 0, + CONFIG_PARSE_ALLOW_INCLUDE = 1 << 1, + CONFIG_PARSE_WARN = 1 << 2, + CONFIG_PARSE_REFUSE_BOM = 1 << 3, } ConfigParseFlags; +/* Argument list for parsers of specific configuration settings. */ +#define CONFIG_PARSER_ARGUMENTS \ + 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 + /* Prototype for a parser for a specific configuration setting */ -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); +typedef int (*ConfigParserCallback)(CONFIG_PARSER_ARGUMENTS); + +/* A macro declaring the a function prototype, following the typedef above, simply because it's so cumbersomely long + * otherwise. (And current emacs gets irritatingly slow when editing files that contain lots of very long function + * prototypes on the same screen…) */ +#define CONFIG_PARSER_PROTOTYPE(name) int name(CONFIG_PARSER_ARGUMENTS) /* Wraps information for parsing a specific configuration variable, to * be stored in a simple array */ @@ -107,46 +110,36 @@ int config_parse_many( ConfigParseFlags flags, void *userdata); -/* Generic parsers */ -#define GENERIC_PARSER_ARGS \ - 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_int(GENERIC_PARSER_ARGS); -int config_parse_unsigned(GENERIC_PARSER_ARGS); -int config_parse_long(GENERIC_PARSER_ARGS); -int config_parse_uint8(GENERIC_PARSER_ARGS); -int config_parse_uint16(GENERIC_PARSER_ARGS); -int config_parse_uint32(GENERIC_PARSER_ARGS); -int config_parse_uint64(GENERIC_PARSER_ARGS); -int config_parse_double(GENERIC_PARSER_ARGS); -int config_parse_iec_size(GENERIC_PARSER_ARGS); -int config_parse_si_size(GENERIC_PARSER_ARGS); -int config_parse_iec_uint64(GENERIC_PARSER_ARGS); -int config_parse_bool(GENERIC_PARSER_ARGS); -int config_parse_tristate(GENERIC_PARSER_ARGS); -int config_parse_string(GENERIC_PARSER_ARGS); -int config_parse_path(GENERIC_PARSER_ARGS); -int config_parse_strv(GENERIC_PARSER_ARGS); -int config_parse_sec(GENERIC_PARSER_ARGS); -int config_parse_nsec(GENERIC_PARSER_ARGS); -int config_parse_mode(GENERIC_PARSER_ARGS); -int config_parse_warn_compat(GENERIC_PARSER_ARGS); -int config_parse_log_facility(GENERIC_PARSER_ARGS); -int config_parse_log_level(GENERIC_PARSER_ARGS); -int config_parse_signal(GENERIC_PARSER_ARGS); -int config_parse_personality(GENERIC_PARSER_ARGS); -int config_parse_ifname(GENERIC_PARSER_ARGS); -int config_parse_ip_port(GENERIC_PARSER_ARGS); -int config_parse_join_controllers(GENERIC_PARSER_ARGS); -int config_parse_mtu(GENERIC_PARSER_ARGS); +CONFIG_PARSER_PROTOTYPE(config_parse_int); +CONFIG_PARSER_PROTOTYPE(config_parse_unsigned); +CONFIG_PARSER_PROTOTYPE(config_parse_long); +CONFIG_PARSER_PROTOTYPE(config_parse_uint8); +CONFIG_PARSER_PROTOTYPE(config_parse_uint16); +CONFIG_PARSER_PROTOTYPE(config_parse_uint32); +CONFIG_PARSER_PROTOTYPE(config_parse_uint64); +CONFIG_PARSER_PROTOTYPE(config_parse_double); +CONFIG_PARSER_PROTOTYPE(config_parse_iec_size); +CONFIG_PARSER_PROTOTYPE(config_parse_si_size); +CONFIG_PARSER_PROTOTYPE(config_parse_iec_uint64); +CONFIG_PARSER_PROTOTYPE(config_parse_bool); +CONFIG_PARSER_PROTOTYPE(config_parse_tristate); +CONFIG_PARSER_PROTOTYPE(config_parse_string); +CONFIG_PARSER_PROTOTYPE(config_parse_path); +CONFIG_PARSER_PROTOTYPE(config_parse_strv); +CONFIG_PARSER_PROTOTYPE(config_parse_sec); +CONFIG_PARSER_PROTOTYPE(config_parse_sec_def_infinity); +CONFIG_PARSER_PROTOTYPE(config_parse_nsec); +CONFIG_PARSER_PROTOTYPE(config_parse_mode); +CONFIG_PARSER_PROTOTYPE(config_parse_warn_compat); +CONFIG_PARSER_PROTOTYPE(config_parse_log_facility); +CONFIG_PARSER_PROTOTYPE(config_parse_log_level); +CONFIG_PARSER_PROTOTYPE(config_parse_signal); +CONFIG_PARSER_PROTOTYPE(config_parse_personality); +CONFIG_PARSER_PROTOTYPE(config_parse_permille); +CONFIG_PARSER_PROTOTYPE(config_parse_ifname); +CONFIG_PARSER_PROTOTYPE(config_parse_ip_port); +CONFIG_PARSER_PROTOTYPE(config_parse_mtu); +CONFIG_PARSER_PROTOTYPE(config_parse_rlimit); typedef enum Disabled { DISABLED_CONFIGURATION, @@ -154,8 +147,46 @@ typedef enum Disabled { DISABLED_EXPERIMENTAL, } Disabled; -#define DEFINE_CONFIG_PARSE_ENUM(function,name,type,msg) \ - int function(GENERIC_PARSER_ARGS) { \ +#define DEFINE_CONFIG_PARSE(function, parser, msg) \ + CONFIG_PARSER_PROTOTYPE(function) { \ + int *i = data, r; \ + \ + assert(filename); \ + assert(lvalue); \ + assert(rvalue); \ + assert(data); \ + \ + r = parser(rvalue); \ + if (r < 0) { \ + log_syntax(unit, LOG_ERR, filename, line, r, \ + msg ", ignoring: %s", rvalue); \ + return 0; \ + } \ + \ + *i = r; \ + return 0; \ + } + +#define DEFINE_CONFIG_PARSE_PTR(function, parser, type, msg) \ + CONFIG_PARSER_PROTOTYPE(function) { \ + type *i = data; \ + int r; \ + \ + assert(filename); \ + assert(lvalue); \ + assert(rvalue); \ + assert(data); \ + \ + r = parser(rvalue, i); \ + if (r < 0) \ + log_syntax(unit, LOG_ERR, filename, line, r, \ + msg ", ignoring: %s", rvalue); \ + \ + return 0; \ + } + +#define DEFINE_CONFIG_PARSE_ENUM(function, name, type, msg) \ + CONFIG_PARSER_PROTOTYPE(function) { \ type *i = data, x; \ \ assert(filename); \ @@ -163,8 +194,9 @@ typedef enum Disabled { assert(rvalue); \ assert(data); \ \ - if ((x = name##_from_string(rvalue)) < 0) { \ - log_syntax(unit, LOG_ERR, filename, line, -x, \ + x = name##_from_string(rvalue); \ + if (x < 0) { \ + log_syntax(unit, LOG_ERR, filename, line, 0, \ msg ", ignoring: %s", rvalue); \ return 0; \ } \ @@ -173,8 +205,33 @@ typedef enum Disabled { return 0; \ } -#define DEFINE_CONFIG_PARSE_ENUMV(function,name,type,invalid,msg) \ - int function(GENERIC_PARSER_ARGS) { \ +#define DEFINE_CONFIG_PARSE_ENUM_WITH_DEFAULT(function, name, type, default_value, msg) \ + CONFIG_PARSER_PROTOTYPE(function) { \ + type *i = data, x; \ + \ + assert(filename); \ + assert(lvalue); \ + assert(rvalue); \ + assert(data); \ + \ + if (isempty(rvalue)) { \ + *i = default_value; \ + return 0; \ + } \ + \ + x = name##_from_string(rvalue); \ + if (x < 0) { \ + log_syntax(unit, LOG_ERR, filename, line, 0, \ + msg ", ignoring: %s", rvalue); \ + return 0; \ + } \ + \ + *i = x; \ + return 0; \ + } + +#define DEFINE_CONFIG_PARSE_ENUMV(function, name, type, invalid, msg) \ + CONFIG_PARSER_PROTOTYPE(function) { \ type **enums = data, x, *ys; \ _cleanup_free_ type *xs = NULL; \ const char *word, *state; \ @@ -200,17 +257,17 @@ typedef enum Disabled { return -ENOMEM; \ \ if ((x = name##_from_string(en)) < 0) { \ - log_syntax(unit, LOG_ERR, filename, line, \ - -x, msg ", ignoring: %s", en); \ + log_syntax(unit, LOG_ERR, filename, line, 0, \ + 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); \ + log_syntax(unit, LOG_NOTICE, filename, \ + line, 0, \ + "Duplicate entry, ignoring: %s", \ + en); \ x = invalid; \ } \ } \ @@ -228,9 +285,6 @@ typedef enum Disabled { *(xs + i) = invalid; \ } \ \ - free(*enums); \ - *enums = xs; \ - xs = NULL; \ - \ + free_and_replace(*enums, xs); \ return 0; \ }