fa6b5010828c0ecf3ba1e0db309f3a4c100ddd4d
[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
12 #ifndef EC_COUNT_OF //XXX
13 #define EC_COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / \
14                 ((size_t)(!(sizeof(x) % sizeof(0[x])))))
15 #endif
16
17 struct ec_config;
18 struct ec_keyval;
19
20 /**
21  * The type identifier for a config value.
22  */
23 enum ec_config_type {
24         EC_CONFIG_TYPE_NONE = 0,
25         EC_CONFIG_TYPE_BOOL,
26         EC_CONFIG_TYPE_INT64,
27         EC_CONFIG_TYPE_UINT64,
28         EC_CONFIG_TYPE_STRING,
29         EC_CONFIG_TYPE_NODE,
30         EC_CONFIG_TYPE_LIST,
31         EC_CONFIG_TYPE_DICT,
32 };
33
34 /**
35  * Structure describing the format of a configuration value.
36  *
37  * This structure is used in a const array which is referenced by a
38  * struct ec_config. Each entry of the array represents a key/value
39  * storage of the configuration dictionary.
40  */
41 struct ec_config_schema {
42         const char *key;          /**< The key string (NULL for list elts). */
43         const char *desc;         /**< A description of the value. */
44         enum ec_config_type type; /**< Type of the value */
45
46         /** If type is dict or list, the schema of the dict or list
47          * elements. Else must be NULL. */
48         const struct ec_config_schema *subschema;
49
50         /** The subschema array len in case of dict (> 0) or list (set
51          * to 1). Else must be 0. */
52         size_t subschema_len;
53
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_keyval *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.
88  * @param schema_len
89  *   Length of the schema array.
90  * @return
91  *   0 if the schema is valid, or -1 on error (errno is set).
92  */
93 int ec_config_schema_validate(const struct ec_config_schema *schema,
94                         size_t schema_len);
95
96 /**
97  * Dump a configuration schema array.
98  *
99  * @param out
100  *   Output stream on which the dump will be sent.
101  * @param schema
102  *   Pointer to the first element of the schema array.
103  * @param schema_len
104  *   Length of the schema array.
105  */
106 void ec_config_schema_dump(FILE *out, const struct ec_config_schema *schema,
107                         size_t schema_len);
108
109
110 /* config */
111
112 /**
113  * Create a boolean configuration value.
114  *
115  * @param boolean
116  *   The boolean value to be set.
117  * @return
118  *   The configuration object, or NULL on error (errno is set).
119  */
120 struct ec_config *ec_config_bool(bool boolean);
121
122 /**
123  * Create a signed integer configuration value.
124  *
125  * @param i64
126  *   The signed integer value to be set.
127  * @return
128  *   The configuration object, or NULL on error (errno is set).
129  */
130 struct ec_config *ec_config_i64(int64_t i64);
131
132 /**
133  * Create an unsigned configuration value.
134  *
135  * @param u64
136  *   The unsigned integer value to be set.
137  * @return
138  *   The configuration object, or NULL on error (errno is set).
139  */
140 struct ec_config *ec_config_u64(uint64_t u64);
141
142 /**
143  * Create a string configuration value.
144  *
145  * @param string
146  *   The string value to be set. The string is copied into the
147  *   configuration object.
148  * @return
149  *   The configuration object, or NULL on error (errno is set).
150  */
151 struct ec_config *ec_config_string(const char *string);
152
153 /**
154  * Create a node configuration value.
155  *
156  * @param node
157  *   The node pointer to be set. The node is "consumed" by
158  *   the function and should not be used by the caller, even
159  *   on error. The caller can use ec_node_clone() to keep a
160  *   reference on the node.
161  * @return
162  *   The configuration object, or NULL on error (errno is set).
163  */
164 struct ec_config *ec_config_node(struct ec_node *node);
165
166 /**
167  * Create a hash table configuration value.
168  *
169  * @return
170  *   A configuration object containing an empty hash table, or NULL on
171  *   error (errno is set).
172  */
173 struct ec_config *ec_config_dict(void);
174
175 /**
176  * Create a list configuration value.
177  *
178  * @return
179  *   The configuration object containing an empty list, or NULL on
180  *   error (errno is set).
181  */
182 struct ec_config *ec_config_list(void);
183
184 /**
185  * Add a config object into a list.
186  *
187  * @param list
188  *   The list configuration in which the value will be added.
189  * @param value
190  *   The value configuration to add in the list. The value object
191  *   will be freed when freeing the list object. On error, the
192  *   value object is also freed.
193  * @return
194  *   0 on success, else -1 (errno is set).
195  */
196 int ec_config_list_add(struct ec_config *list, struct ec_config *value);
197
198 /**
199  * Remove an element from a list.
200  *
201  * The element is freed and should not be accessed.
202  *
203  * @param list
204  *   The list configuration.
205  * @param config
206  *   The element to remove from the list.
207  * @return
208  *   0 on success, -1 on error (errno is set).
209  */
210 int ec_config_list_del(struct ec_config *list, struct ec_config *config);
211
212 /**
213  * Validate a configuration.
214  *
215  * @param dict
216  *   A hash table configuration to validate.
217  * @param schema
218  *   Pointer to the first element of the schema array.
219  * @param schema_len
220  *   Length of the schema array.
221  * @return
222  *   0 on success, -1 on error (errno is set).
223  */
224 int ec_config_validate(const struct ec_config *dict,
225                 const struct ec_config_schema *schema,
226                 size_t schema_len);
227
228 /**
229  * Set a value in a hash table configuration
230  *
231  * @param dict
232  *   A hash table configuration to validate.
233  * @param key
234  *   The key to update.
235  * @param value
236  *   The value to set. The value object will be freed when freeing the
237  *   dict object. On error, the value object is also freed.
238  * @return
239  *   0 on success, -1 on error (errno is set).
240  */
241 int ec_config_dict_set(struct ec_config *dict, const char *key,
242                 struct ec_config *value);
243
244 /**
245  * Remove an element from a hash table configuration.
246  *
247  * The element is freed and should not be accessed.
248  *
249  * @param dict
250  *   A hash table configuration to validate.
251  * @param key
252  *   The key of the configuration to delete.
253  * @return
254  *   0 on success, -1 on error (errno is set).
255  */
256 int ec_config_dict_del(struct ec_config *config, const char *key);
257
258 /**
259  * Compare two configurations.
260  */
261 int ec_config_cmp(const struct ec_config *config1,
262                 const struct ec_config *config2);
263
264 /**
265  * Get configuration value.
266  */
267 struct ec_config *ec_config_dict_get(const struct ec_config *config,
268                                 const char *key);
269
270 /**
271  * Get the first element of a list.
272  *
273  * Example of use:
274  * for (config = ec_config_list_iter(list);
275  *      config != NULL;
276  *      config = ec_config_list_next(list, config)) {
277  *              ...
278  * }
279  *
280  * @param list
281  *   The list configuration to iterate.
282  * @return
283  *   The first configuration element, or NULL on error (errno is set).
284  */
285 struct ec_config *ec_config_list_first(struct ec_config *list);
286
287 /**
288  * Get next element in list.
289  *
290  * @param list
291  *   The list configuration beeing iterated.
292  * @param config
293  *   The current configuration element.
294  * @return
295  *   The next configuration element, or NULL if there is no more element.
296  */
297 struct ec_config *
298 ec_config_list_next(struct ec_config *list, struct ec_config *config);
299
300 /**
301  * Free a configuration.
302  *
303  * @param config
304  *   The element to free.
305  */
306 void ec_config_free(struct ec_config *config);
307
308 /**
309  * Compare two configurations.
310  *
311  * @return
312  *   0 if the configurations are equal, else -1.
313  */
314 int ec_config_cmp(const struct ec_config *value1,
315                 const struct ec_config *value2);
316
317 /**
318  * Duplicate a configuration.
319  *
320  * @param config
321  *   The configuration to duplicate.
322  * @return
323  *   The duplicated configuration, or NULL on error (errno is set).
324  */
325 struct ec_config *
326 ec_config_dup(const struct ec_config *config);
327
328 /**
329  * Dump a configuration.
330  *
331  * @param out
332  *   Output stream on which the dump will be sent.
333  * @param config
334  *   The configuration to dump.
335  */
336 void ec_config_dump(FILE *out, const struct ec_config *config);
337
338 #endif