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