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