1 /* Copyright (c) 2001 Matej Pfajfar.
2  * Copyright (c) 2001-2004, Roger Dingledine.
3  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4  * Copyright (c) 2007-2021, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
6 
7 /**
8  * @file confdecl.h
9  * @brief Macros for generating a configuration struct from a list
10  *   of its individual fields.
11  *
12  * This header defines three important macros: BEGIN_CONF_STRUCT(),
13  * END_CONF_STRUCT(), and CONF_VAR().  They're meant to be used together to
14  * define a configuration structure and the means for encoding and decoding
15  * it.
16  *
17  * To use them, make a new header with a name like `MOD_options.inc`.  Start
18  * it with a BEGIN_CONF_STRUCT(), then define your variables with CONF_VAR(),
19  * then end the header with END_CONF_STRUCT(), as in:
20  *
21  *     BEGIN_CONF_STRUCT(module_options_t)
22  *     CONF_VAR(ModuleIsActive, BOOLEAN, 0, "1")
23  *     END_CONF_STRUCT(module_options_t)
24  *
25  * Once you've done that, you can use that header to define a configuration
26  * structure by saying:
27  *
28  *     typedef struct module_options_t module_options_t;
29  *     #define CONF_CONTEXT STRUCT
30  *     #include "MOD_options.inc"
31  *     #undef CONF_CONTEXT
32  *
33  * And you can define your field definition table by saying:
34  *
35  *     #define CONF_CONTEXT TABLE
36  *     #include "MOD_options.inc"
37  *     #undef CONF_CONTEXT
38  *
39  * The two above snippets will define a structure called `module_options_t`
40  * with appropriate members, and a table of config_var_t objects called
41  * `module_options_t_vars[]`.
42  *
43  * For lower-level modules, you can say <tt>\#define CONF_TABLE LL_TABLE</tt>,
44  * and get a table definition suitable for use in modules that are at a lower
45  * level than lib/confmgt.  Note that the types for these tables cannot
46  * include any extended types.
47  **/
48 
49 #ifndef TOR_LIB_CONF_CONFDECL_H
50 #define TOR_LIB_CONF_CONFDECL_H
51 
52 #undef CONF_CONTEXT
53 #include "lib/cc/tokpaste.h"
54 #include "lib/cc/torint.h"
55 
56 /**
57  * Begin the definition of a configuration object called `name`.
58  **/
59 #define BEGIN_CONF_STRUCT(name) \
60   PASTE(BEGIN_CONF_STRUCT__, CONF_CONTEXT)(name)
61 /**
62  * End the definition of a configuration object called `name`.
63  **/
64 #define END_CONF_STRUCT(name) \
65   PASTE(END_CONF_STRUCT__, CONF_CONTEXT)(name)
66 /**
67  * Declare a single configuration field with name `varname`, type `vartype`,
68  * flags `varflags`, and initial value `initval`.
69  **/
70 #define CONF_VAR(varname, vartype, varflags, initval)   \
71   PASTE(CONF_VAR__, CONF_CONTEXT)(varname, vartype, varflags, initval)
72 
73 #ifndef COCCI
74 /**
75  * @defgroup STRUCT_MACROS Internal macros: struct definitions.
76  * Implementation helpers: the regular confdecl macros expand to these
77  * when CONF_CONTEXT is defined to STRUCT.  Don't use them directly.
78  * @{*/
79 #define BEGIN_CONF_STRUCT__STRUCT(name)         \
80   struct name {                                 \
81   uint32_t magic;
82 #define END_CONF_STRUCT__STRUCT(name)           \
83   };
84 #define CONF_VAR__STRUCT(varname, vartype, varflags, initval)   \
85   config_decl_ ## vartype varname;
86 /** @} */
87 
88 /**
89  * @defgroup TABLE_MACROS Internal macros: table definitions.
90  * Implementation helpers: the regular confdecl macros expand to these
91  * when CONF_CONTEXT is defined to TABLE.  Don't use them directly.
92  * @{*/
93 #define BEGIN_CONF_STRUCT__TABLE(structname)                            \
94   /* We use this typedef so we can refer to the config type */          \
95   /* without having its name as a macro argument to CONF_VAR. */        \
96   typedef struct structname config_var_reference__obj;  \
97   static const config_var_t structname##_vars[] = {
98 #define END_CONF_STRUCT__TABLE(structname)      \
99   { .member = { .name = NULL } }                \
100     };
101 #define CONF_VAR__TABLE(varname, vartype, varflags, initval)    \
102   {                                                             \
103    .member =                                                    \
104    { .name = #varname,                                          \
105      .type = CONFIG_TYPE_EXTENDED,                              \
106      .type_def = &vartype ## _type_defn,                        \
107      .offset=offsetof(config_var_reference__obj, varname),      \
108    },                                                           \
109    .flags = varflags,                                           \
110    .initvalue = initval                                         \
111   },
112 /**@}*/
113 
114 /**
115  * @defgroup LL_TABLE_MACROS Internal macros: low-level table definitions.
116  * Implementation helpers: the regular confdecl macros expand to these
117  * when CONF_CONTEXT is defined to LL_TABLE.  Don't use them directly.
118  * @{*/
119 #define BEGIN_CONF_STRUCT__LL_TABLE(structname)                         \
120   /* We use this typedef so we can refer to the config type */          \
121   /* without having its name as a macro argument to CONF_VAR. */        \
122   typedef struct structname config_var_reference__obj;  \
123   static const config_var_t structname##_vars[] = {
124 #define END_CONF_STRUCT__LL_TABLE(structname)   \
125   { .member = { .name = NULL } }                \
126     };
127 #define CONF_VAR__LL_TABLE(varname, vartype, varflags, initval) \
128   {                                                             \
129    .member =                                                    \
130    { .name = #varname,                                          \
131      .type = CONFIG_TYPE_ ## vartype,                           \
132      .offset=offsetof(config_var_reference__obj, varname),      \
133    },                                                           \
134    .flags = varflags,                                           \
135    .initvalue = initval                                         \
136   },
137 /**@}*/
138 
139 /** @defgroup STUB_TABLE_MACROS Internal macros: stub table declarations,
140  * for use when a module is disabled.
141  * Implementation helpers: the regular confdecl macros expand to these
142  * when CONF_CONTEXT is defined to LL_TABLE.  Don't use them directly.
143  * @{ */
144 #define BEGIN_CONF_STRUCT__STUB_TABLE(structname)                       \
145   static const config_var_t structname##_vars[] = {
146 #define END_CONF_STRUCT__STUB_TABLE(structname)   \
147   { .member = { .name = NULL } }                \
148     };
149 #define CONF_VAR__STUB_TABLE(varname, vartype, varflags, initval)       \
150   {                                                             \
151    .member =                                                    \
152    { .name = #varname,                                          \
153      .type = CONFIG_TYPE_IGNORE,                                \
154      .offset = -1,                                              \
155    },                                                           \
156    .flags = CFLG_GROUP_DISABLED,                                \
157   },
158 /**@}*/
159 
160 #endif /* !defined(COCCI) */
161 
162 /** Type aliases for the "commonly used" configuration types.
163  *
164  * Defining them in this way allows our CONF_VAR__STRUCT() macro to declare
165  * structure members corresponding to the configuration types.  For example,
166  * when the macro sees us declare a configuration option "foo" of type STRING,
167  * it can emit `config_decl_STRING foo;`, which is an alias for `char *foo`.
168  */
169 /**@{*/
170 typedef char *config_decl_STRING;
171 typedef char *config_decl_FILENAME;
172 /* Yes, "POSINT" is really an int, and not an unsigned int.  For
173  * historical reasons, many configuration values are restricted
174  * to the range [0,INT_MAX], and stored in signed ints.
175  */
176 typedef int config_decl_POSINT;
177 typedef uint64_t config_decl_UINT64;
178 typedef int config_decl_INT;
179 typedef int config_decl_INTERVAL;
180 typedef int config_decl_MSEC_INTERVAL;
181 typedef uint64_t config_decl_MEMUNIT;
182 typedef double config_decl_DOUBLE;
183 typedef int config_decl_BOOL;
184 typedef int config_decl_AUTOBOOL;
185 typedef time_t config_decl_ISOTIME;
186 typedef struct smartlist_t config_decl_CSV;
187 typedef int config_decl_CSV_INTERVAL;
188 typedef struct config_line_t *config_decl_LINELIST;
189 typedef struct config_line_t *config_decl_LINELIST_V;
190 typedef struct nonexistent_struct *config_decl_LINELIST_S;
191 /**@}*/
192 
193 struct var_type_def_t;
194 
195 /* Forward declarations for configuration type definitions. These are used by
196  * the CONF_VAR__TABLE macro to set the definition of each variable type
197  * correctly.
198  */
199 /**@{*/
200 extern const struct var_type_def_t STRING_type_defn;
201 extern const struct var_type_def_t FILENAME_type_defn;
202 extern const struct var_type_def_t POSINT_type_defn;
203 extern const struct var_type_def_t UINT64_type_defn;
204 extern const struct var_type_def_t INT_type_defn;
205 extern const struct var_type_def_t INTERVAL_type_defn;
206 extern const struct var_type_def_t MSEC_INTERVAL_type_defn;
207 extern const struct var_type_def_t MEMUNIT_type_defn;
208 extern const struct var_type_def_t DOUBLE_type_defn;
209 extern const struct var_type_def_t BOOL_type_defn;
210 extern const struct var_type_def_t AUTOBOOL_type_defn;
211 extern const struct var_type_def_t ISOTIME_type_defn;
212 extern const struct var_type_def_t CSV_type_defn;
213 extern const struct var_type_def_t CSV_INTERVAL_type_defn;
214 extern const struct var_type_def_t LINELIST_type_defn;
215 extern const struct var_type_def_t LINELIST_V_type_defn;
216 extern const struct var_type_def_t LINELIST_S_type_defn;
217 extern const struct var_type_def_t IGNORE_type_defn;
218 extern const struct var_type_def_t OBSOLETE_type_defn;
219 /**@}*/
220 
221 #endif /* !defined(TOR_LIB_CONF_CONFDECL_H) */
222