more config accessor
[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
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  * Validate a configuration.
270  *
271  * @param dict
272  *   A hash table configuration to validate.
273  * @param schema
274  *   Pointer to the first element of the schema array. The array
275  *   must be terminated by a sentinel entry (type == EC_CONFIG_TYPE_NONE).
276  * @return
277  *   0 on success, -1 on error (errno is set).
278  */
279 int ec_config_validate(const struct ec_config *dict,
280                 const struct ec_config_schema *schema);
281
282 /**
283  * Set a value in a hash table configuration
284  *
285  * @param dict
286  *   A hash table configuration to validate.
287  * @param key
288  *   The key to update.
289  * @param value
290  *   The value to set. The value object will be freed when freeing the
291  *   dict object. On error, the value object is also freed.
292  * @return
293  *   0 on success, -1 on error (errno is set).
294  */
295 int ec_config_dict_set(struct ec_config *dict, const char *key,
296                 struct ec_config *value);
297
298 /**
299  * Remove an element from a hash table configuration.
300  *
301  * The element is freed and should not be accessed.
302  *
303  * @param dict
304  *   A hash table configuration to validate.
305  * @param key
306  *   The key of the configuration to delete.
307  * @return
308  *   0 on success, -1 on error (errno is set).
309  */
310 int ec_config_dict_del(struct ec_config *config, const char *key);
311
312 /**
313  * Compare two configurations.
314  */
315 int ec_config_cmp(const struct ec_config *config1,
316                 const struct ec_config *config2);
317
318 /**
319  * Get configuration value.
320  */
321 struct ec_config *ec_config_dict_get(const struct ec_config *config,
322                                 const char *key);
323
324 /**
325  * Get the first element of a list.
326  *
327  * Example of use:
328  * for (config = ec_config_list_iter(list);
329  *      config != NULL;
330  *      config = ec_config_list_next(list, config)) {
331  *              ...
332  * }
333  *
334  * @param list
335  *   The list configuration to iterate.
336  * @return
337  *   The first configuration element, or NULL on error (errno is set).
338  */
339 struct ec_config *ec_config_list_first(struct ec_config *list);
340
341 /**
342  * Get next element in list.
343  *
344  * @param list
345  *   The list configuration beeing iterated.
346  * @param config
347  *   The current configuration element.
348  * @return
349  *   The next configuration element, or NULL if there is no more element.
350  */
351 struct ec_config *
352 ec_config_list_next(struct ec_config *list, struct ec_config *config);
353
354 /**
355  * Free a configuration.
356  *
357  * @param config
358  *   The element to free.
359  */
360 void ec_config_free(struct ec_config *config);
361
362 /**
363  * Compare two configurations.
364  *
365  * @return
366  *   0 if the configurations are equal, else -1.
367  */
368 int ec_config_cmp(const struct ec_config *value1,
369                 const struct ec_config *value2);
370
371 /**
372  * Duplicate a configuration.
373  *
374  * @param config
375  *   The configuration to duplicate.
376  * @return
377  *   The duplicated configuration, or NULL on error (errno is set).
378  */
379 struct ec_config *
380 ec_config_dup(const struct ec_config *config);
381
382 /**
383  * Dump a configuration.
384  *
385  * @param out
386  *   Output stream on which the dump will be sent.
387  * @param config
388  *   The configuration to dump.
389  */
390 void ec_config_dump(FILE *out, const struct ec_config *config);
391
392 #endif