export schema lookup
[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  * Check if a key name is reserved in a config dict.
118  *
119  * Some key names are reserved and should not be used in configs.
120  *
121  * @param name
122  *   The name of the key to test.
123  * @return
124  *   True if the key name is reserved and must not be used, else false.
125  */
126 bool ec_config_key_is_reserved(const char *name);
127
128 /**
129  * Array of reserved key names.
130  */
131 extern const char *ec_config_reserved_keys[];
132
133
134 /* config */
135
136 /**
137  * Get the type of the configuration.
138  *
139  * @param config
140  *   The configuration.
141  * @return
142  *   The configuration type.
143  */
144 enum ec_config_type ec_config_get_type(const struct ec_config *config);
145
146 /**
147  * Create a boolean configuration value.
148  *
149  * @param boolean
150  *   The boolean value to be set.
151  * @return
152  *   The configuration object, or NULL on error (errno is set).
153  */
154 struct ec_config *ec_config_bool(bool boolean);
155
156 /**
157  * Create a signed integer configuration value.
158  *
159  * @param i64
160  *   The signed integer value to be set.
161  * @return
162  *   The configuration object, or NULL on error (errno is set).
163  */
164 struct ec_config *ec_config_i64(int64_t i64);
165
166 /**
167  * Create an unsigned configuration value.
168  *
169  * @param u64
170  *   The unsigned integer value to be set.
171  * @return
172  *   The configuration object, or NULL on error (errno is set).
173  */
174 struct ec_config *ec_config_u64(uint64_t u64);
175
176 /**
177  * Create a string configuration value.
178  *
179  * @param string
180  *   The string value to be set. The string is copied into the
181  *   configuration object.
182  * @return
183  *   The configuration object, or NULL on error (errno is set).
184  */
185 struct ec_config *ec_config_string(const char *string);
186
187 /**
188  * Create a node configuration value.
189  *
190  * @param node
191  *   The node pointer to be set. The node is "consumed" by
192  *   the function and should not be used by the caller, even
193  *   on error. The caller can use ec_node_clone() to keep a
194  *   reference on the node.
195  * @return
196  *   The configuration object, or NULL on error (errno is set).
197  */
198 struct ec_config *ec_config_node(struct ec_node *node);
199
200 /**
201  * Create a hash table configuration value.
202  *
203  * @return
204  *   A configuration object containing an empty hash table, or NULL on
205  *   error (errno is set).
206  */
207 struct ec_config *ec_config_dict(void);
208
209 /**
210  * Create a list configuration value.
211  *
212  * @return
213  *   The configuration object containing an empty list, or NULL on
214  *   error (errno is set).
215  */
216 struct ec_config *ec_config_list(void);
217
218 /**
219  * Add a config object into a list.
220  *
221  * @param list
222  *   The list configuration in which the value will be added.
223  * @param value
224  *   The value configuration to add in the list. The value object
225  *   will be freed when freeing the list object. On error, the
226  *   value object is also freed.
227  * @return
228  *   0 on success, else -1 (errno is set).
229  */
230 int ec_config_list_add(struct ec_config *list, struct ec_config *value);
231
232 /**
233  * Remove an element from a list.
234  *
235  * The element is freed and should not be accessed.
236  *
237  * @param list
238  *   The list configuration.
239  * @param config
240  *   The element to remove from the list.
241  * @return
242  *   0 on success, -1 on error (errno is set).
243  */
244 int ec_config_list_del(struct ec_config *list, struct ec_config *config);
245
246 /**
247  * Validate a configuration.
248  *
249  * @param dict
250  *   A hash table configuration to validate.
251  * @param schema
252  *   Pointer to the first element of the schema array. The array
253  *   must be terminated by a sentinel entry (type == EC_CONFIG_TYPE_NONE).
254  * @return
255  *   0 on success, -1 on error (errno is set).
256  */
257 int ec_config_validate(const struct ec_config *dict,
258                 const struct ec_config_schema *schema);
259
260 /**
261  * Set a value in a hash table configuration
262  *
263  * @param dict
264  *   A hash table configuration to validate.
265  * @param key
266  *   The key to update.
267  * @param value
268  *   The value to set. The value object will be freed when freeing the
269  *   dict object. On error, the value object is also freed.
270  * @return
271  *   0 on success, -1 on error (errno is set).
272  */
273 int ec_config_dict_set(struct ec_config *dict, const char *key,
274                 struct ec_config *value);
275
276 /**
277  * Remove an element from a hash table configuration.
278  *
279  * The element is freed and should not be accessed.
280  *
281  * @param dict
282  *   A hash table configuration to validate.
283  * @param key
284  *   The key of the configuration to delete.
285  * @return
286  *   0 on success, -1 on error (errno is set).
287  */
288 int ec_config_dict_del(struct ec_config *config, const char *key);
289
290 /**
291  * Compare two configurations.
292  */
293 int ec_config_cmp(const struct ec_config *config1,
294                 const struct ec_config *config2);
295
296 /**
297  * Get configuration value.
298  */
299 struct ec_config *ec_config_dict_get(const struct ec_config *config,
300                                 const char *key);
301
302 /**
303  * Get the first element of a list.
304  *
305  * Example of use:
306  * for (config = ec_config_list_iter(list);
307  *      config != NULL;
308  *      config = ec_config_list_next(list, config)) {
309  *              ...
310  * }
311  *
312  * @param list
313  *   The list configuration to iterate.
314  * @return
315  *   The first configuration element, or NULL on error (errno is set).
316  */
317 struct ec_config *ec_config_list_first(struct ec_config *list);
318
319 /**
320  * Get next element in list.
321  *
322  * @param list
323  *   The list configuration beeing iterated.
324  * @param config
325  *   The current configuration element.
326  * @return
327  *   The next configuration element, or NULL if there is no more element.
328  */
329 struct ec_config *
330 ec_config_list_next(struct ec_config *list, struct ec_config *config);
331
332 /**
333  * Free a configuration.
334  *
335  * @param config
336  *   The element to free.
337  */
338 void ec_config_free(struct ec_config *config);
339
340 /**
341  * Compare two configurations.
342  *
343  * @return
344  *   0 if the configurations are equal, else -1.
345  */
346 int ec_config_cmp(const struct ec_config *value1,
347                 const struct ec_config *value2);
348
349 /**
350  * Duplicate a configuration.
351  *
352  * @param config
353  *   The configuration to duplicate.
354  * @return
355  *   The duplicated configuration, or NULL on error (errno is set).
356  */
357 struct ec_config *
358 ec_config_dup(const struct ec_config *config);
359
360 /**
361  * Dump a configuration.
362  *
363  * @param out
364  *   Output stream on which the dump will be sent.
365  * @param config
366  *   The configuration to dump.
367  */
368 void ec_config_dump(FILE *out, const struct ec_config *config);
369
370 #endif