From 19cac400d9cf7dcc274c583bb3e942b2682c3663 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Sat, 26 Oct 2019 17:46:16 -0400 Subject: Macros for declaring configuration structs and variable-tables In our old design, we had to declare configuration structures (like or_options_t) and variable tables (like option_vars_) separately, and we used some magic to enforce their consistency (see conftesting.h). With this design, we write a single definition for the configuration object and its fields, and use C macros to expand it either into a structure, or a variable table. Since they are both made from the same source, they can't become inconsistent. The two designs can coexist happily, and we can migrate from one to the other at our convenience. --- src/lib/conf/confdecl.h | 166 ++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/conf/include.am | 1 + 2 files changed, 167 insertions(+) create mode 100644 src/lib/conf/confdecl.h (limited to 'src/lib/conf') diff --git a/src/lib/conf/confdecl.h b/src/lib/conf/confdecl.h new file mode 100644 index 0000000000..22812f046e --- /dev/null +++ b/src/lib/conf/confdecl.h @@ -0,0 +1,166 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file confdecl.h + * @brief Macros for generating a configuration struct from a list + * of its individual fields. + * + * This header defines three important macros: BEGIN_CONF_STRUCT(), + * END_CONF_STRUCT(), and CONF_VAR(). They're meant to be used together to + * define a configuration structure and the means for encoding and decoding + * it. + * + * To use them, make a new header with a name like `MOD_options.inc`. Start + * it with a BEGIN_CONF_STRUCT(), then define your variables with CONF_VAR(), + * then end the header with END_CONF_STRUCT(), as in: + * + * BEGIN_CONF_STRUCT(module_options_t) + * CONF_VAR(ModuleIsActive, BOOLEAN, 0, "1") + * END_CONF_STRUCT(module_options_t) + * + * Once you've done that, you can use that header to define a configuration + * structure by saying: + * + * typedef struct module_options_t module_options_t; + * #define CONF_CONTEXT STRUCT + * #include "MOD_options.inc" + * #undef CONF_CONTEXT + * + * And you can define your field definition table by saying: + * + * #define CONF_CONTEXT TABLE + * #include "MOD_options.inc" + * #undef CONF_CONTEXT + * + * The two above snippets will define a structure called `module_options_t` + * with appropriate members, and a table of config_var_t objects called + * `module_options_t_vars[]`. + **/ + +#ifndef TOR_LIB_CONF_CONFDECL_H +#define TOR_LIB_CONF_CONFDECL_H + +#undef CONF_CONTEXT +#include "lib/cc/tokpaste.h" + +/** + * Begin the definition of a configuration object called `name`. + **/ +#define BEGIN_CONF_STRUCT(name) \ + PASTE(BEGIN_CONF_STRUCT__, CONF_CONTEXT)(name) +/** + * End the definition of a configuration object called `name`. + **/ +#define END_CONF_STRUCT(name) \ + PASTE(END_CONF_STRUCT__, CONF_CONTEXT)(name) +/** + * Declare a single configuration field with name `varname`, type `vartype`, + * flags `varflags`, and initial value `initval`. + **/ +#define CONF_VAR(varname, vartype, varflags, initval) \ + PASTE(CONF_VAR__, CONF_CONTEXT)(varname, vartype, varflags, initval) + +#ifndef COCCI +/** + * @defgroup STRUCT_MACROS Internal macros: struct definitions. + * Implementation helpers: the regular confdecl macros expand to these + * when CONF_CONTEXT is defined to STRUCT. Don't use them directly. + * @{*/ +#define BEGIN_CONF_STRUCT__STRUCT(name) \ + struct name { \ + uint32_t magic; +#define END_CONF_STRUCT__STRUCT(name) \ + }; +#define CONF_VAR__STRUCT(varname, vartype, varflags, initval) \ + config_decl_ ## vartype varname; +/** @} */ + +/** + * @defgroup TABLE_MACROS Internal macros: table definitions. + * Implementation helpers: the regular confdecl macros expand to these + * when CONF_CONTEXT is defined to TABLE. Don't use them directly. + * @{*/ +#define BEGIN_CONF_STRUCT__TABLE(structname) \ + /* We use this typedef so we can refer to the config type */ \ + /* without having its name as a macro argument to CONF_VAR. */ \ + typedef struct structname config_var_reference__obj; \ + static const config_var_t structname##_vars[] = { +#define END_CONF_STRUCT__TABLE(structname) \ + { .member = { .name = NULL } } \ + }; +#define CONF_VAR__TABLE(varname, vartype, varflags, initval) \ + { \ + .member = \ + { .name = #varname, \ + .type = CONFIG_TYPE_EXTENDED, \ + .type_def = &vartype ## _type_defn, \ + .offset=offsetof(config_var_reference__obj, varname), \ + }, \ + .flags = varflags, \ + .initvalue = initval \ + }, +/**@}*/ +#endif + +/** Type aliases for the "commonly used" configuration types. + * + * Defining them in this way allows our CONF_VAR__STRUCT() macro to declare + * structure members corresponding to the configuration types. For example, + * when the macro sees us declare a configuration option "foo" of type STRING, + * it can emit `config_decl_STRING foo;`, which is an alias for `char *foo`. + */ +/**{*/ +typedef char *config_decl_STRING; +typedef char *config_decl_FILENAME; +/* Yes, "POSINT" is really an int, and not an unsigned int. For + * historical reasons, many configuration values are restricted + * to the range [0,INT_MAX], and stored in signed ints. + */ +typedef int config_decl_POSINT; +typedef uint64_t config_decl_UINT64; +typedef int config_decl_INT; +typedef int config_decl_INTERVAL; +typedef int config_decl_MSEC_INTERVAL; +typedef uint64_t config_decl_MEMUNIT; +typedef double config_decl_DOUBLE; +typedef int config_decl_BOOL; +typedef int config_decl_AUTOBOOL; +typedef time_t config_decl_ISOTIME; +typedef struct smartlist_t config_decl_CSV; +typedef int config_decl_CSV_INTERVAL; +typedef struct config_line_t *config_decl_LINELIST; +typedef struct config_line_t *config_decl_LINELIST_V; +typedef struct nonexistent_struct *config_decl_LINELIST_S; +/**@}*/ + +struct var_type_def_t; + +/* Forward declarations for configuration type definitions. These are used by + * the CONF_VAR__TABLE macro to set the definition of each variable type + * correctly. + */ +/**@{*/ +extern const struct var_type_def_t STRING_type_defn; +extern const struct var_type_def_t FILENAME_type_defn; +extern const struct var_type_def_t POSINT_type_defn; +extern const struct var_type_def_t UINT64_type_defn; +extern const struct var_type_def_t INT_type_defn; +extern const struct var_type_def_t INTERVAL_type_defn; +extern const struct var_type_def_t MSEC_INTERVAL_type_defn; +extern const struct var_type_def_t MEMUNIT_type_defn; +extern const struct var_type_def_t DOUBLE_type_defn; +extern const struct var_type_def_t BOOL_type_defn; +extern const struct var_type_def_t AUTOBOOL_type_defn; +extern const struct var_type_def_t ISOTIME_type_defn; +extern const struct var_type_def_t CSV_type_defn; +extern const struct var_type_def_t CSV_INTERVAL_type_defn; +extern const struct var_type_def_t LINELIST_type_defn; +extern const struct var_type_def_t LINELIST_V_type_defn; +extern const struct var_type_def_t LINELIST_S_type_defn; +/**@}*/ + +#endif /* !defined(TOR_LIB_CONF_CONFDECL_H) */ diff --git a/src/lib/conf/include.am b/src/lib/conf/include.am index cb7126184d..cb0b83fa64 100644 --- a/src/lib/conf/include.am +++ b/src/lib/conf/include.am @@ -1,6 +1,7 @@ # ADD_C_FILE: INSERT HEADERS HERE. noinst_HEADERS += \ + src/lib/conf/confdecl.h \ src/lib/conf/conftesting.h \ src/lib/conf/conftypes.h \ src/lib/conf/confmacros.h -- cgit v1.2.3-54-g00ecf From 683d4c2bc8379084062dfd79d679e89c2713ff50 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 30 Oct 2019 15:58:14 -0400 Subject: Add FOO_type_defn globals so that confdecl.h can refer to them. --- src/lib/conf/confdecl.h | 1 + src/lib/confmgt/type_defs.c | 121 +++++++++++++++++++++++++++++--------------- 2 files changed, 80 insertions(+), 42 deletions(-) (limited to 'src/lib/conf') diff --git a/src/lib/conf/confdecl.h b/src/lib/conf/confdecl.h index 22812f046e..f6f9dc527b 100644 --- a/src/lib/conf/confdecl.h +++ b/src/lib/conf/confdecl.h @@ -161,6 +161,7 @@ extern const struct var_type_def_t CSV_INTERVAL_type_defn; extern const struct var_type_def_t LINELIST_type_defn; extern const struct var_type_def_t LINELIST_V_type_defn; extern const struct var_type_def_t LINELIST_S_type_defn; +extern const struct var_type_def_t OBSOLETE_type_defn; /**@}*/ #endif /* !defined(TOR_LIB_CONF_CONFDECL_H) */ diff --git a/src/lib/confmgt/type_defs.c b/src/lib/confmgt/type_defs.c index f39f1c3d8d..0bf82ee934 100644 --- a/src/lib/confmgt/type_defs.c +++ b/src/lib/confmgt/type_defs.c @@ -17,6 +17,7 @@ #include "orconfig.h" #include "lib/conf/conftypes.h" +#include "lib/conf/confdecl.h" #include "lib/confmgt/typedvar.h" #include "lib/confmgt/type_defs.h" #include "lib/confmgt/unitparse.h" @@ -720,50 +721,86 @@ static const var_type_fns_t ignore_fns = { .encode = ignore_encode, }; +const var_type_def_t STRING_type_defn = { + .name="String", .fns=&string_fns }; +const var_type_def_t FILENAME_type_defn = { + .name="Filename", .fns=&string_fns }; +const var_type_def_t INT_type_defn = { + .name="SignedInteger", .fns=&int_fns, + .params=&INT_PARSE_UNRESTRICTED }; +const var_type_def_t POSINT_type_defn = { + .name="Integer", .fns=&int_fns, + .params=&INT_PARSE_POSINT }; +const var_type_def_t UINT64_type_defn = { + .name="Integer", .fns=&uint64_fns, }; +const var_type_def_t MEMUNIT_type_defn = { + .name="DataSize", .fns=&memunit_fns, + .params=&memory_units }; +const var_type_def_t INTERVAL_type_defn = { + .name="TimeInterval", .fns=&interval_fns, + .params=&time_units }; +const var_type_def_t MSEC_INTERVAL_type_defn = { + .name="TimeMsecInterval", + .fns=&interval_fns, + .params=&time_msec_units }; +const var_type_def_t DOUBLE_type_defn = { + .name="Float", .fns=&double_fns, }; +const var_type_def_t BOOL_type_defn = { + .name="Boolean", .fns=&enum_fns, + .params=&enum_table_bool }; +const var_type_def_t AUTOBOOL_type_defn = { + .name="Boolean+Auto", .fns=&enum_fns, + .params=&enum_table_autobool }; +const var_type_def_t ISOTIME_type_defn = { + .name="Time", .fns=&time_fns, }; +const var_type_def_t CSV_type_defn = { + .name="CommaList", .fns=&csv_fns, }; +const var_type_def_t CSV_INTERVAL_type_defn = { + .name="TimeInterval", + .fns=&legacy_csv_interval_fns, }; +const var_type_def_t LINELIST_type_defn = { + .name="LineList", .fns=&linelist_fns, + .flags=CFLG_NOREPLACE }; +/* + * A "linelist_s" is a derived view of a linelist_v: inspecting + * it gets part of a linelist_v, and setting it adds to the linelist_v. + */ +const var_type_def_t LINELIST_S_type_defn = { + .name="Dependent", .fns=&linelist_s_fns, + .flags=CFLG_NOREPLACE| + /* The operations we disable here are + * handled by the linelist_v. */ + CFLG_NOCOPY|CFLG_NOCMP|CFLG_NODUMP }; +const var_type_def_t LINELIST_V_type_defn = { + .name="Virtual", .fns=&linelist_v_fns, + .flags=CFLG_NOREPLACE|CFLG_NOSET }; +const var_type_def_t OBSOLETE_type_defn = { + .name="Obsolete", .fns=&ignore_fns, + .flags=CFLG_GROUP_OBSOLETE, +}; + /** * Table mapping conf_type_t values to var_type_def_t objects. **/ -static const var_type_def_t type_definitions_table[] = { - [CONFIG_TYPE_STRING] = { .name="String", .fns=&string_fns }, - [CONFIG_TYPE_FILENAME] = { .name="Filename", .fns=&string_fns }, - [CONFIG_TYPE_INT] = { .name="SignedInteger", .fns=&int_fns, - .params=&INT_PARSE_UNRESTRICTED }, - [CONFIG_TYPE_POSINT] = { .name="Integer", .fns=&int_fns, - .params=&INT_PARSE_POSINT }, - [CONFIG_TYPE_UINT64] = { .name="Integer", .fns=&uint64_fns, }, - [CONFIG_TYPE_MEMUNIT] = { .name="DataSize", .fns=&memunit_fns, - .params=&memory_units }, - [CONFIG_TYPE_INTERVAL] = { .name="TimeInterval", .fns=&interval_fns, - .params=&time_units }, - [CONFIG_TYPE_MSEC_INTERVAL] = { .name="TimeMsecInterval", - .fns=&interval_fns, - .params=&time_msec_units }, - [CONFIG_TYPE_DOUBLE] = { .name="Float", .fns=&double_fns, }, - [CONFIG_TYPE_BOOL] = { .name="Boolean", .fns=&enum_fns, - .params=&enum_table_bool }, - [CONFIG_TYPE_AUTOBOOL] = { .name="Boolean+Auto", .fns=&enum_fns, - .params=&enum_table_autobool }, - [CONFIG_TYPE_ISOTIME] = { .name="Time", .fns=&time_fns, }, - [CONFIG_TYPE_CSV] = { .name="CommaList", .fns=&csv_fns, }, - [CONFIG_TYPE_CSV_INTERVAL] = { .name="TimeInterval", - .fns=&legacy_csv_interval_fns, }, - [CONFIG_TYPE_LINELIST] = { .name="LineList", .fns=&linelist_fns, - .flags=CFLG_NOREPLACE }, - /* - * A "linelist_s" is a derived view of a linelist_v: inspecting - * it gets part of a linelist_v, and setting it adds to the linelist_v. - */ - [CONFIG_TYPE_LINELIST_S] = { .name="Dependent", .fns=&linelist_s_fns, - .flags=CFLG_NOREPLACE| - /* The operations we disable here are - * handled by the linelist_v. */ - CFLG_NOCOPY|CFLG_NOCMP|CFLG_NODUMP }, - [CONFIG_TYPE_LINELIST_V] = { .name="Virtual", .fns=&linelist_v_fns, - .flags=CFLG_NOREPLACE|CFLG_NOSET }, - [CONFIG_TYPE_OBSOLETE] = { - .name="Obsolete", .fns=&ignore_fns, - .flags=CFLG_GROUP_OBSOLETE, - } +static const var_type_def_t *type_definitions_table[] = { + [CONFIG_TYPE_STRING] = &STRING_type_defn, + [CONFIG_TYPE_FILENAME] = &FILENAME_type_defn, + [CONFIG_TYPE_INT] = &INT_type_defn, + [CONFIG_TYPE_POSINT] = &POSINT_type_defn, + [CONFIG_TYPE_UINT64] = &UINT64_type_defn, + [CONFIG_TYPE_MEMUNIT] = &MEMUNIT_type_defn, + [CONFIG_TYPE_INTERVAL] = &INTERVAL_type_defn, + [CONFIG_TYPE_MSEC_INTERVAL] = &MSEC_INTERVAL_type_defn, + [CONFIG_TYPE_DOUBLE] = &DOUBLE_type_defn, + [CONFIG_TYPE_BOOL] = &BOOL_type_defn, + [CONFIG_TYPE_AUTOBOOL] = &AUTOBOOL_type_defn, + [CONFIG_TYPE_ISOTIME] = &ISOTIME_type_defn, + [CONFIG_TYPE_CSV] = &CSV_type_defn, + [CONFIG_TYPE_CSV_INTERVAL] = &CSV_INTERVAL_type_defn, + [CONFIG_TYPE_LINELIST] = &LINELIST_type_defn, + [CONFIG_TYPE_LINELIST_S] = &LINELIST_S_type_defn, + [CONFIG_TYPE_LINELIST_V] = &LINELIST_V_type_defn, + [CONFIG_TYPE_OBSOLETE] = &OBSOLETE_type_defn, }; /** @@ -777,5 +814,5 @@ lookup_type_def(config_type_t type) tor_assert(t >= 0); if (t >= (int)ARRAY_LENGTH(type_definitions_table)) return NULL; - return &type_definitions_table[t]; + return type_definitions_table[t]; } -- cgit v1.2.3-54-g00ecf From 1d108894e7abd85d2ba0beeb69c0ee6071521a6c Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 30 Oct 2019 10:47:29 -0400 Subject: Define a low-level version of the confdecl table macros This version uses the enum rather than the type definitions, to avoid layering violations and linking problems. --- src/lib/conf/confdecl.h | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'src/lib/conf') diff --git a/src/lib/conf/confdecl.h b/src/lib/conf/confdecl.h index f6f9dc527b..19b6f85090 100644 --- a/src/lib/conf/confdecl.h +++ b/src/lib/conf/confdecl.h @@ -39,6 +39,11 @@ * The two above snippets will define a structure called `module_options_t` * with appropriate members, and a table of config_var_t objects called * `module_options_t_vars[]`. + * + * For lower-level modules, you can say `#define CONF_TABLE LL_TABLE`, and get + * a table definition suitable for use in modules that are at a lower level + * than lib/confmgt. Note that the types for these tables cannot include any + * extended types. **/ #ifndef TOR_LIB_CONF_CONFDECL_H @@ -104,6 +109,31 @@ .initvalue = initval \ }, /**@}*/ + +/** + * @defgroup LL_TABLE_MACROS Internal macros: low-level table definitions. + * Implementation helpers: the regular confdecl macros expand to these + * when CONF_CONTEXT is defined to LL_TABLE. Don't use them directly. + * @{*/ +#define BEGIN_CONF_STRUCT__LL_TABLE(structname) \ + /* We use this typedef so we can refer to the config type */ \ + /* without having its name as a macro argument to CONF_VAR. */ \ + typedef struct structname config_var_reference__obj; \ + static const config_var_t structname##_vars[] = { +#define END_CONF_STRUCT__LL_TABLE(structname) \ + { .member = { .name = NULL } } \ + }; +#define CONF_VAR__LL_TABLE(varname, vartype, varflags, initval) \ + { \ + .member = \ + { .name = #varname, \ + .type = CONFIG_TYPE_ ## vartype, \ + .offset=offsetof(config_var_reference__obj, varname), \ + }, \ + .flags = varflags, \ + .initvalue = initval \ + }, +/**@}*/ #endif /** Type aliases for the "commonly used" configuration types. -- cgit v1.2.3-54-g00ecf From 0f0a9bdf332002bb0542dae6bb00e922af5dcf63 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 5 Nov 2019 10:18:47 -0500 Subject: Stop using "config_suite_offset=-1" to indicate "no config suite." Instead, create a separate "has_config_suite" boolean, so that only top-level formats with config_suites need to declare an offset at all. --- src/app/config/config.c | 1 + src/app/config/statefile.c | 1 + src/feature/dirauth/shared_random_state.c | 1 - src/lib/conf/conftypes.h | 10 ++++++++-- src/lib/confmgt/confmgt.c | 9 +++++++-- src/lib/crypt_ops/crypto_init.c | 1 - src/test/test_confmgr.c | 3 +-- src/test/test_confparse.c | 2 -- 8 files changed, 18 insertions(+), 10 deletions(-) (limited to 'src/lib/conf') diff --git a/src/app/config/config.c b/src/app/config/config.c index 480d225e92..c121775c04 100644 --- a/src/app/config/config.c +++ b/src/app/config/config.c @@ -880,6 +880,7 @@ static const config_format_t options_format = { .legacy_validate_fn = options_validate_cb, .check_transition_fn = options_check_transition_cb, .clear_fn = options_clear_cb, + .has_config_suite = true, .config_suite_offset = offsetof(or_options_t, subconfigs_), }; diff --git a/src/app/config/statefile.c b/src/app/config/statefile.c index 5fdb15ace1..3e793ff402 100644 --- a/src/app/config/statefile.c +++ b/src/app/config/statefile.c @@ -169,6 +169,7 @@ static const config_format_t state_format = { .vars = state_vars_, .legacy_validate_fn = or_state_validate_cb, .extra = &state_extra_var, + .has_config_suite = true, .config_suite_offset = offsetof(or_state_t, substates_), }; diff --git a/src/feature/dirauth/shared_random_state.c b/src/feature/dirauth/shared_random_state.c index 759b3b8104..bf4302f168 100644 --- a/src/feature/dirauth/shared_random_state.c +++ b/src/feature/dirauth/shared_random_state.c @@ -92,7 +92,6 @@ static const config_format_t state_format = { }, .vars = state_vars, .extra = &state_extra_var, - .config_suite_offset = -1, }; /** Global configuration manager for the shared-random state file */ diff --git a/src/lib/conf/conftypes.h b/src/lib/conf/conftypes.h index d4e2ea218a..dfe51cfba1 100644 --- a/src/lib/conf/conftypes.h +++ b/src/lib/conf/conftypes.h @@ -335,8 +335,14 @@ typedef struct config_format_t { /** If present, extra denotes a LINELIST variable for unrecognized * lines. Otherwise, unrecognized lines are an error. */ const struct_member_t *extra; - /** The position of a config_suite_t pointer within the toplevel object, - * or -1 if there is no such pointer. */ + /** + * If true, this format describes a top-level configuration, with + * a suite containing multiple sub-configuration objects. + */ + bool has_config_suite; + /** The position of a config_suite_t pointer within the toplevel object. + * Ignored unless have_config_suite is true. + */ ptrdiff_t config_suite_offset; } config_format_t; diff --git a/src/lib/confmgt/confmgt.c b/src/lib/confmgt/confmgt.c index 1c1a1595ec..a96c7f96bf 100644 --- a/src/lib/confmgt/confmgt.c +++ b/src/lib/confmgt/confmgt.c @@ -169,9 +169,14 @@ config_mgr_register_fmt(config_mgr_t *mgr, "it had been frozen."); if (object_idx != IDX_TOPLEVEL) { - tor_assertf(fmt->config_suite_offset < 0, + tor_assertf(! fmt->has_config_suite, "Tried to register a toplevel format in a non-toplevel position"); } + if (fmt->config_suite_offset) { + tor_assertf(fmt->has_config_suite, + "config_suite_offset was set, but has_config_suite was not."); + } + tor_assertf(fmt != mgr->toplevel && ! smartlist_contains(mgr->subconfigs, fmt), "Tried to register an already-registered format."); @@ -223,7 +228,7 @@ config_mgr_add_format(config_mgr_t *mgr, static inline config_suite_t ** config_mgr_get_suite_ptr(const config_mgr_t *mgr, void *toplevel) { - if (mgr->toplevel->config_suite_offset < 0) + if (! mgr->toplevel->has_config_suite) return NULL; return STRUCT_VAR_P(toplevel, mgr->toplevel->config_suite_offset); } diff --git a/src/lib/crypt_ops/crypto_init.c b/src/lib/crypt_ops/crypto_init.c index 4b08456197..fbd4da4704 100644 --- a/src/lib/crypt_ops/crypto_init.c +++ b/src/lib/crypt_ops/crypto_init.c @@ -293,7 +293,6 @@ static const config_format_t crypto_options_fmt = { offsetof(crypto_options_t, magic) }, .vars = crypto_options_t_vars, .validate_fn = crypto_options_validate, - .config_suite_offset = -1, }; /** diff --git a/src/test/test_confmgr.c b/src/test/test_confmgr.c index 375a513c07..b59bd8c6a0 100644 --- a/src/test/test_confmgr.c +++ b/src/test/test_confmgr.c @@ -193,6 +193,7 @@ static const config_format_t pasture_fmt = { offsetof(pasture_cfg_t, magic) }, .vars = pasture_vars, + .has_config_suite = true, .config_suite_offset = offsetof(pasture_cfg_t, subobjs), .legacy_validate_fn = legacy_validate_pasture, }; @@ -205,7 +206,6 @@ static const config_format_t llama_fmt = { offsetof(llama_cfg_t, magic) }, .vars = llama_vars, - .config_suite_offset = -1, .deprecations = llama_deprecations, .abbrevs = llama_abbrevs, .clear_fn = clear_llama_cfg, @@ -221,7 +221,6 @@ static const config_format_t alpaca_fmt = { offsetof(alpaca_cfg_t, magic) }, .vars = alpaca_vars, - .config_suite_offset = -1, .deprecations = alpaca_deprecations, .pre_normalize_fn = pre_normalize_alpaca, .check_transition_fn = check_transition_alpaca, diff --git a/src/test/test_confparse.c b/src/test/test_confparse.c index 39e2de866c..3e122a5129 100644 --- a/src/test/test_confparse.c +++ b/src/test/test_confparse.c @@ -129,7 +129,6 @@ static const config_format_t test_fmt = { .deprecations = test_deprecation_notes, .vars = test_vars, .legacy_validate_fn = test_validate_cb, - .config_suite_offset = -1, }; /* Make sure that config_init sets everything to the right defaults. */ @@ -824,7 +823,6 @@ static config_format_t etest_fmt = { .vars = test_vars, .legacy_validate_fn = test_validate_cb, .extra = &extra, - .config_suite_offset = -1, }; /* Try out the feature where we can store unrecognized lines and dump them -- cgit v1.2.3-54-g00ecf