8ceddf55f238937c2749baaf93ffa6efc8414d1e
[protos/libecoli.git] / lib / ecoli_config.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2018, Olivier MATZ <zer0@droids-corp.org>
3  */
4
5 #ifndef ECOLI_CONFIG_
6 #define ECOLI_CONFIG_
7
8 #include <sys/queue.h>
9 #include <stdbool.h>
10 #include <stdint.h>
11 #include <stdio.h>
12
13 #ifndef EC_COUNT_OF //XXX
14 #define EC_COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / \
15                 ((size_t)(!(sizeof(x) % sizeof(0[x])))))
16 #endif
17
18 struct ec_config;
19 struct ec_keyval;
20
21 /**
22  * The type identifier for a config value.
23  */
24 enum ec_config_type {
25         EC_CONFIG_TYPE_NONE = 0,
26         EC_CONFIG_TYPE_BOOL,
27         EC_CONFIG_TYPE_INT64,
28         EC_CONFIG_TYPE_UINT64,
29         EC_CONFIG_TYPE_STRING,
30         EC_CONFIG_TYPE_NODE,
31         EC_CONFIG_TYPE_LIST,
32         EC_CONFIG_TYPE_DICT,
33 };
34
35 /**
36  * Structure describing the format of a configuration value.
37  *
38  * This structure is used in a const array which is referenced by a
39  * struct ec_config. Each entry of the array represents a key/value
40  * storage of the configuration dictionary.
41  */
42 struct ec_config_schema {
43         const char *key;          /**< The key string (NULL for list elts). */
44         const char *desc;         /**< A description of the value. */
45         enum ec_config_type type; /**< Type of the value */
46
47         /** If type is dict or list, the schema of the dict or list
48          * elements. Else must be NULL. */
49         const struct ec_config_schema *subschema;
50 };
51
52 TAILQ_HEAD(ec_config_list, ec_config);
53
54 /**
55  * Structure storing the configuration data.
56  */
57 struct ec_config {
58         /** type of value stored in the union */
59         enum ec_config_type type;
60
61         union {
62                 bool boolean;   /** Boolean value */
63                 int64_t i64;    /** Signed integer value */
64                 uint64_t u64;   /** Unsigned integer value */
65                 char *string;   /** String value */
66                 struct ec_node *node;       /** Node value */
67                 struct ec_keyval *dict;     /** Hash table value */
68                 struct ec_config_list list; /** List value */
69         };
70
71         /**
72          * Next in list, only valid if type is list.
73          */
74         TAILQ_ENTRY(ec_config) next;
75 };
76
77 /* schema */
78
79 /**
80  * Validate a configuration schema array.
81  *
82  * @param schema
83  *   Pointer to the first element of the schema array. The array
84  *   must be terminated by a sentinel entry (type == EC_CONFIG_TYPE_NONE).
85  * @return
86  *   0 if the schema is valid, or -1 on error (errno is set).
87  */
88 int ec_config_schema_validate(const struct ec_config_schema *schema);
89
90 /**
91  * Dump a configuration schema array.
92  *
93  * @param out
94  *   Output stream on which the dump will be sent.
95  * @param schema
96  *   Pointer to the first element of the schema array. The array
97  *   must be terminated by a sentinel entry (type == EC_CONFIG_TYPE_NONE).
98  */
99 void ec_config_schema_dump(FILE *out, const struct ec_config_schema *schema);
100
101 /**
102  * Check if a key name is reserved in a config dict.
103  *
104  * Some key names are reserved and should not be used in configs.
105  *
106  * @param name
107  *   The name of the key to test.
108  * @return
109  *   True if the key name is reserved and must not be used, else false.
110  */
111 bool ec_config_key_is_reserved(const char *name);
112
113 /**
114  * Array of reserved key names.
115  */
116 extern const char *ec_config_reserved_keys[];
117
118
119 /* config */
120
121 /**
122  * Get the type of the configuration.
123  *
124  * @param config
125  *   The configuration.
126  * @return
127  *   The configuration type.
128  */
129 enum ec_config_type ec_config_get_type(const struct ec_config *config);
130
131 /**
132  * Create a boolean configuration value.
133  *
134  * @param boolean
135  *   The boolean value to be set.
136  * @return
137  *   The configuration object, or NULL on error (errno is set).
138  */
139 struct ec_config *ec_config_bool(bool boolean);
140
141 /**
142  * Create a signed integer configuration value.
143  *
144  * @param i64
145  *   The signed integer value to be set.
146  * @return
147  *   The configuration object, or NULL on error (errno is set).
148  */
149 struct ec_config *ec_config_i64(int64_t i64);
150
151 /**
152  * Create an unsigned configuration value.
153  *
154  * @param u64
155  *   The unsigned integer value to be set.
156  * @return
157  *   The configuration object, or NULL on error (errno is set).
158  */
159 struct ec_config *ec_config_u64(uint64_t u64);
160
161 /**
162  * Create a string configuration value.
163  *
164  * @param string
165  *   The string value to be set. The string is copied into the
166  *   configuration object.
167  * @return
168  *   The configuration object, or NULL on error (errno is set).
169  */
170 struct ec_config *ec_config_string(const char *string);
171
172 /**
173  * Create a node configuration value.
174  *
175  * @param node
176  *   The node pointer to be set. The node is "consumed" by
177  *   the function and should not be used by the caller, even
178  *   on error. The caller can use ec_node_clone() to keep a
179  *   reference on the node.
180  * @return
181  *   The configuration object, or NULL on error (errno is set).
182  */
183 struct ec_config *ec_config_node(struct ec_node *node);
184
185 /**
186  * Create a hash table configuration value.
187  *
188  * @return
189  *   A configuration object containing an empty hash table, or NULL on
190  *   error (errno is set).
191  */
192 struct ec_config *ec_config_dict(void);
193
194 /**
195  * Create a list configuration value.
196  *
197  * @return
198  *   The configuration object containing an empty list, or NULL on
199  *   error (errno is set).
200  */
201 struct ec_config *ec_config_list(void);
202
203 /**
204  * Add a config object into a list.
205  *
206  * @param list
207  *   The list configuration in which the value will be added.
208  * @param value
209  *   The value configuration to add in the list. The value object
210  *   will be freed when freeing the list object. On error, the
211  *   value object is also freed.
212  * @return
213  *   0 on success, else -1 (errno is set).
214  */
215 int ec_config_list_add(struct ec_config *list, struct ec_config *value);
216
217 /**
218  * Remove an element from a list.
219  *
220  * The element is freed and should not be accessed.
221  *
222  * @param list
223  *   The list configuration.
224  * @param config
225  *   The element to remove from the list.
226  * @return
227  *   0 on success, -1 on error (errno is set).
228  */
229 int ec_config_list_del(struct ec_config *list, struct ec_config *config);
230
231 /**
232  * Validate a configuration.
233  *
234  * @param dict
235  *   A hash table configuration to validate.
236  * @param schema
237  *   Pointer to the first element of the schema array. The array
238  *   must be terminated by a sentinel entry (type == EC_CONFIG_TYPE_NONE).
239  * @return
240  *   0 on success, -1 on error (errno is set).
241  */
242 int ec_config_validate(const struct ec_config *dict,
243                 const struct ec_config_schema *schema);
244
245 /**
246  * Set a value in a hash table configuration
247  *
248  * @param dict
249  *   A hash table configuration to validate.
250  * @param key
251  *   The key to update.
252  * @param value
253  *   The value to set. The value object will be freed when freeing the
254  *   dict object. On error, the value object is also freed.
255  * @return
256  *   0 on success, -1 on error (errno is set).
257  */
258 int ec_config_dict_set(struct ec_config *dict, const char *key,
259                 struct ec_config *value);
260
261 /**
262  * Remove an element from a hash table configuration.
263  *
264  * The element is freed and should not be accessed.
265  *
266  * @param dict
267  *   A hash table configuration to validate.
268  * @param key
269  *   The key of the configuration to delete.
270  * @return
271  *   0 on success, -1 on error (errno is set).
272  */
273 int ec_config_dict_del(struct ec_config *config, const char *key);
274
275 /**
276  * Compare two configurations.
277  */
278 int ec_config_cmp(const struct ec_config *config1,
279                 const struct ec_config *config2);
280
281 /**
282  * Get configuration value.
283  */
284 struct ec_config *ec_config_dict_get(const struct ec_config *config,
285                                 const char *key);
286
287 /**
288  * Get the first element of a list.
289  *
290  * Example of use:
291  * for (config = ec_config_list_iter(list);
292  *      config != NULL;
293  *      config = ec_config_list_next(list, config)) {
294  *              ...
295  * }
296  *
297  * @param list
298  *   The list configuration to iterate.
299  * @return
300  *   The first configuration element, or NULL on error (errno is set).
301  */
302 struct ec_config *ec_config_list_first(struct ec_config *list);
303
304 /**
305  * Get next element in list.
306  *
307  * @param list
308  *   The list configuration beeing iterated.
309  * @param config
310  *   The current configuration element.
311  * @return
312  *   The next configuration element, or NULL if there is no more element.
313  */
314 struct ec_config *
315 ec_config_list_next(struct ec_config *list, struct ec_config *config);
316
317 /**
318  * Free a configuration.
319  *
320  * @param config
321  *   The element to free.
322  */
323 void ec_config_free(struct ec_config *config);
324
325 /**
326  * Compare two configurations.
327  *
328  * @return
329  *   0 if the configurations are equal, else -1.
330  */
331 int ec_config_cmp(const struct ec_config *value1,
332                 const struct ec_config *value2);
333
334 /**
335  * Duplicate a configuration.
336  *
337  * @param config
338  *   The configuration to duplicate.
339  * @return
340  *   The duplicated configuration, or NULL on error (errno is set).
341  */
342 struct ec_config *
343 ec_config_dup(const struct ec_config *config);
344
345 /**
346  * Dump a configuration.
347  *
348  * @param out
349  *   Output stream on which the dump will be sent.
350  * @param config
351  *   The configuration to dump.
352  */
353 void ec_config_dump(FILE *out, const struct ec_config *config);
354
355 #endif