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