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