b6d638e867fe83413d03b11f821a346022a4e2a3
[protos/libecoli.git] / include / 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_dict;
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         /* XXX flags: mandatory */
47         /* XXX default */
48
49         /** If type is dict or list, the schema of the dict or list
50          * elements. Else must be NULL. */
51         const struct ec_config_schema *subschema;
52 };
53
54 TAILQ_HEAD(ec_config_list, ec_config);
55
56 /**
57  * Structure storing the configuration data.
58  */
59 struct ec_config {
60         /** type of value stored in the union */
61         enum ec_config_type type;
62
63         union {
64                 bool boolean;   /** Boolean value */
65                 int64_t i64;    /** Signed integer value */
66                 uint64_t u64;   /** Unsigned integer value */
67                 char *string;   /** String value */
68                 struct ec_node *node;       /** Node value */
69                 struct ec_dict *dict;     /** Hash table value */
70                 struct ec_config_list list; /** List value */
71         };
72
73         /**
74          * Next in list, only valid if type is list.
75          */
76         TAILQ_ENTRY(ec_config) next;
77 };
78
79 /* schema */
80
81 /**
82  * Validate a configuration schema array.
83  *
84  * @param schema
85  *   Pointer to the first element of the schema array. The array
86  *   must be terminated by a sentinel entry (type == EC_CONFIG_TYPE_NONE).
87  * @return
88  *   0 if the schema is valid, or -1 on error (errno is set).
89  */
90 int ec_config_schema_validate(const struct ec_config_schema *schema);
91
92 /**
93  * Dump a configuration schema array.
94  *
95  * @param out
96  *   Output stream on which the dump will be sent.
97  * @param schema
98  *   Pointer to the first element of the schema array. The array
99  *   must be terminated by a sentinel entry (type == EC_CONFIG_TYPE_NONE).
100  */
101 void ec_config_schema_dump(FILE *out, const struct ec_config_schema *schema);
102
103 /**
104  * Find a schema entry matching the key.
105  *
106  * Browse the schema array and lookup for the given key.
107  *
108  * @param schema
109  *   Pointer to the first element of the schema array. The array
110  *   must be terminated by a sentinel entry (type == EC_CONFIG_TYPE_NONE).
111  * @return
112  *   The schema entry if it matches a key, or NULL if not found.
113  */
114 const struct ec_config_schema *
115 ec_config_schema_lookup(const struct ec_config_schema *schema,
116                         const char *key);
117
118 /**
119  * Get the type of a schema entry.
120  *
121  * @param schema_elt
122  *   Pointer to an element of the schema array.
123  * @return
124  *   The type of the schema entry.
125  */
126 enum ec_config_type
127 ec_config_schema_type(const struct ec_config_schema *schema_elt);
128
129 /**
130  * Get the subschema of a schema entry.
131  *
132  * @param schema_elt
133  *   Pointer to an element of the schema array.
134  * @return
135  *   The subschema if any, or NULL.
136  */
137 const struct ec_config_schema *
138 ec_config_schema_sub(const struct ec_config_schema *schema_elt);
139
140 /**
141  * Check if a key name is reserved in a config dict.
142  *
143  * Some key names are reserved and should not be used in configs.
144  *
145  * @param name
146  *   The name of the key to test.
147  * @return
148  *   True if the key name is reserved and must not be used, else false.
149  */
150 bool ec_config_key_is_reserved(const char *name);
151
152 /**
153  * Array of reserved key names.
154  */
155 extern const char *ec_config_reserved_keys[];
156
157
158 /* config */
159
160 /**
161  * Get the type of the configuration.
162  *
163  * @param config
164  *   The configuration.
165  * @return
166  *   The configuration type.
167  */
168 enum ec_config_type ec_config_get_type(const struct ec_config *config);
169
170 /**
171  * Create a boolean configuration value.
172  *
173  * @param boolean
174  *   The boolean value to be set.
175  * @return
176  *   The configuration object, or NULL on error (errno is set).
177  */
178 struct ec_config *ec_config_bool(bool boolean);
179
180 /**
181  * Create a signed integer configuration value.
182  *
183  * @param i64
184  *   The signed integer value to be set.
185  * @return
186  *   The configuration object, or NULL on error (errno is set).
187  */
188 struct ec_config *ec_config_i64(int64_t i64);
189
190 /**
191  * Create an unsigned configuration value.
192  *
193  * @param u64
194  *   The unsigned integer value to be set.
195  * @return
196  *   The configuration object, or NULL on error (errno is set).
197  */
198 struct ec_config *ec_config_u64(uint64_t u64);
199
200 /**
201  * Create a string configuration value.
202  *
203  * @param string
204  *   The string value to be set. The string is copied into the
205  *   configuration object.
206  * @return
207  *   The configuration object, or NULL on error (errno is set).
208  */
209 struct ec_config *ec_config_string(const char *string);
210
211 /**
212  * Create a node configuration value.
213  *
214  * @param node
215  *   The node pointer to be set. The node is "consumed" by
216  *   the function and should not be used by the caller, even
217  *   on error. The caller can use ec_node_clone() to keep a
218  *   reference on the node.
219  * @return
220  *   The configuration object, or NULL on error (errno is set).
221  */
222 struct ec_config *ec_config_node(struct ec_node *node);
223
224 /**
225  * Create a hash table configuration value.
226  *
227  * @return
228  *   A configuration object containing an empty hash table, or NULL on
229  *   error (errno is set).
230  */
231 struct ec_config *ec_config_dict(void);
232
233 /**
234  * Create a list configuration value.
235  *
236  * @return
237  *   The configuration object containing an empty list, or NULL on
238  *   error (errno is set).
239  */
240 struct ec_config *ec_config_list(void);
241
242 /**
243  * Add a config object into a list.
244  *
245  * @param list
246  *   The list configuration in which the value will be added.
247  * @param value
248  *   The value configuration to add in the list. The value object
249  *   will be freed when freeing the list object. On error, the
250  *   value object is also freed.
251  * @return
252  *   0 on success, else -1 (errno is set).
253  */
254 int ec_config_list_add(struct ec_config *list, struct ec_config *value);
255
256 /**
257  * Remove an element from a list.
258  *
259  * The element is freed and should not be accessed.
260  *
261  * @param list
262  *   The list configuration.
263  * @param config
264  *   The element to remove from the list.
265  * @return
266  *   0 on success, -1 on error (errno is set).
267  */
268 int ec_config_list_del(struct ec_config *list, struct ec_config *config);
269
270 /**
271  * Count the number of elements in a list or dict.
272  *
273  * @param config
274  *   The configuration that must be a list or a dict.
275  * @return
276  *   The number of elements, or -1 on error (errno is set).
277  */
278 ssize_t ec_config_count(const struct ec_config *config);
279
280 /**
281  * Validate a configuration.
282  *
283  * @param dict
284  *   A hash table configuration to validate.
285  * @param schema
286  *   Pointer to the first element of the schema array. The array
287  *   must be terminated by a sentinel entry (type == EC_CONFIG_TYPE_NONE).
288  * @return
289  *   0 on success, -1 on error (errno is set).
290  */
291 int ec_config_validate(const struct ec_config *dict,
292                 const struct ec_config_schema *schema);
293
294 /**
295  * Set a value in a hash table configuration
296  *
297  * @param dict
298  *   A hash table configuration to validate.
299  * @param key
300  *   The key to update.
301  * @param value
302  *   The value to set. The value object will be freed when freeing the
303  *   dict object. On error, the value object is also freed.
304  * @return
305  *   0 on success, -1 on error (errno is set).
306  */
307 int ec_config_dict_set(struct ec_config *dict, const char *key,
308                 struct ec_config *value);
309
310 /**
311  * Remove an element from a hash table configuration.
312  *
313  * The element is freed and should not be accessed.
314  *
315  * @param dict
316  *   A hash table configuration to validate.
317  * @param key
318  *   The key of the configuration to delete.
319  * @return
320  *   0 on success, -1 on error (errno is set).
321  */
322 int ec_config_dict_del(struct ec_config *config, const char *key);
323
324 /**
325  * Compare two configurations.
326  */
327 int ec_config_cmp(const struct ec_config *config1,
328                 const struct ec_config *config2);
329
330 /**
331  * Get configuration value.
332  */
333 struct ec_config *ec_config_dict_get(const struct ec_config *config,
334                                 const char *key);
335
336 /**
337  * Get the first element of a list.
338  *
339  * Example of use:
340  * for (config = ec_config_list_iter(list);
341  *      config != NULL;
342  *      config = ec_config_list_next(list, config)) {
343  *              ...
344  * }
345  *
346  * @param list
347  *   The list configuration to iterate.
348  * @return
349  *   The first configuration element, or NULL on error (errno is set).
350  */
351 struct ec_config *ec_config_list_first(struct ec_config *list);
352
353 /**
354  * Get next element in list.
355  *
356  * @param list
357  *   The list configuration beeing iterated.
358  * @param config
359  *   The current configuration element.
360  * @return
361  *   The next configuration element, or NULL if there is no more element.
362  */
363 struct ec_config *
364 ec_config_list_next(struct ec_config *list, struct ec_config *config);
365
366 /**
367  * Free a configuration.
368  *
369  * @param config
370  *   The element to free.
371  */
372 void ec_config_free(struct ec_config *config);
373
374 /**
375  * Compare two configurations.
376  *
377  * @return
378  *   0 if the configurations are equal, else -1.
379  */
380 int ec_config_cmp(const struct ec_config *value1,
381                 const struct ec_config *value2);
382
383 /**
384  * Duplicate a configuration.
385  *
386  * @param config
387  *   The configuration to duplicate.
388  * @return
389  *   The duplicated configuration, or NULL on error (errno is set).
390  */
391 struct ec_config *
392 ec_config_dup(const struct ec_config *config);
393
394 /**
395  * Dump a configuration.
396  *
397  * @param out
398  *   Output stream on which the dump will be sent.
399  * @param config
400  *   The configuration to dump.
401  */
402 void ec_config_dump(FILE *out, const struct ec_config *config);
403
404 #endif