sq config
[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 <stdbool.h>
9 #include <stdint.h>
10
11 struct ec_config;
12 struct ec_keyval;
13
14 /**
15  * The type identifier for a config value.
16  */
17 enum ec_config_type {
18         EC_CONFIG_TYPE_NONE = 0,
19         EC_CONFIG_TYPE_BOOL,
20         EC_CONFIG_TYPE_INT64,
21         EC_CONFIG_TYPE_UINT64,
22         EC_CONFIG_TYPE_STRING,
23         EC_CONFIG_TYPE_NODE,
24         EC_CONFIG_TYPE_LIST,
25         EC_CONFIG_TYPE_DICT,
26 };
27
28 /**
29  * Structure describing the format of a configuration value.
30  *
31  * This structure is used in a const array which is referenced by a
32  * struct ec_config. Each entry of the array represents a key/value
33  * storage of the configuration dictionary.
34  */
35 struct ec_config_schema {
36         const char *key;          /**< The key string (NULL for list elts). */
37         const char *desc;         /**< A description of the value. */
38         enum ec_config_type type; /**< Type of the value */
39
40         /** If type is dict or list, the schema of the dict or list
41          * elements. Else must be NULL. */
42         const struct ec_config_schema *subschema;
43
44         /** The subschema array len in case of dict (> 0) or list (set
45          * to 1). Else must be 0. */
46         size_t subschema_len;
47
48 };
49
50 TAILQ_HEAD(ec_config_list, ec_config);
51
52 /**
53  * Structure storing the configuration data.
54  */
55 struct ec_config {
56         /** type of value stored in the union */
57         enum ec_config_type type;
58
59         union {
60                 bool boolean;   /** Boolean value */
61                 int64_t i64;    /** Signed integer value */
62                 uint64_t u64;   /** Unsigned integer value */
63                 char *string;   /** String value */
64                 struct ec_node *node;       /** Node value */
65                 struct ec_keyval *dict;     /** Hash table value */
66                 struct ec_config_list list; /** List value */
67         };
68
69         /**
70          * Next in list, only valid if type is list.
71          */
72         TAILQ_ENTRY(ec_config) next;
73
74         /** Associated schema. Only valid if type is dict. */
75         const struct ec_config_schema *schema;
76         size_t schema_len;           /**< Schema length. */
77 };
78
79 /* schema */
80
81 /**
82  * Validate a configuration schema array.
83  *
84  * @param schema
85  *   Pointer to the first element of the schema array.
86  * @param schema_len
87  *   Length of the schema array.
88  * @return
89  *   0 if the schema is valid, or -1 on error (errno is set).
90  */
91 int ec_config_schema_validate(const struct ec_config_schema *schema,
92                         size_t schema_len);
93
94 /**
95  * Dump a configuration schema array.
96  *
97  * @param out
98  *   Output stream on which the dump will be sent.
99  * @param schema
100  *   Pointer to the first element of the schema array.
101  * @param schema_len
102  *   Length of the schema array.
103  */
104 void ec_config_schema_dump(FILE *out, const struct ec_config_schema *schema,
105                         size_t schema_len);
106
107
108 /* config */
109
110 /**
111  * Create a boolean configuration value.
112  *
113  * @param boolean
114  *   The boolean value to be set.
115  * @return
116  *   The configuration object, or NULL on error (errno is set).
117  */
118 struct ec_config *ec_config_bool(bool boolean);
119
120 /**
121  * Create a signed integer configuration value.
122  *
123  * @param i64
124  *   The signed integer value to be set.
125  * @return
126  *   The configuration object, or NULL on error (errno is set).
127  */
128 struct ec_config *ec_config_i64(int64_t i64);
129
130 /**
131  * Create an unsigned configuration value.
132  *
133  * @param u64
134  *   The unsigned integer value to be set.
135  * @return
136  *   The configuration object, or NULL on error (errno is set).
137  */
138 struct ec_config *ec_config_u64(uint64_t u64);
139
140 /**
141  * Create a string configuration value.
142  *
143  * @param string
144  *   The string value to be set. The string is copied into the
145  *   configuration object.
146  * @return
147  *   The configuration object, or NULL on error (errno is set).
148  */
149 struct ec_config *ec_config_string(const char *string);
150
151 /**
152  * Create a node configuration value.
153  *
154  * @param node
155  *   The node pointer to be set. The node is "consumed" by
156  *   the function and should not be used by the caller, even
157  *   on error. The caller can use ec_node_clone() to keep a
158  *   reference on the node.
159  * @return
160  *   The configuration object, or NULL on error (errno is set).
161  */
162 struct ec_config *ec_config_node(struct ec_node *node);
163
164 /**
165  * Create a hash table configuration value.
166  *
167  * @param schema
168  *   Optional pointer to the first element of the schema array. Set
169  *   it to NULL if no schema should be attached.
170  * @param schema_len
171  *   Length of the schema array. Set to 0 if no schema.
172  * @return
173  *   The configuration object containing an empty hash table, or NULL on
174  *   error (errno is set).
175  */
176 struct ec_config *ec_config_dict(const struct ec_config_schema *schema,
177                                 size_t schema_len);
178
179 /**
180  * Create a list configuration value.
181  *
182  * @return
183  *   The configuration object containing an empty list, or NULL on
184  *   error (errno is set).
185  */
186 struct ec_config *ec_config_list(void);
187
188 /**
189  * Add a config object into a list.
190  *
191  * @param list
192  *   The list configuration in which the value will be added.
193  * @param value
194  *   The value configuration to add in the list. The value object
195  *   will be freed when freeing the list object. On error, the
196  *   value object is freed.
197  * @return
198  *   0 on success, else -1 (errno is set).
199  */
200 int ec_config_add(struct ec_config *list, struct ec_config *value);
201
202 void ec_config_free(struct ec_config *config);
203
204 int ec_config_validate(const struct ec_config *dict);
205
206 /* value is consumed */
207 int ec_config_set(struct ec_config *dict, const char *key,
208                 struct ec_config *value);
209
210 /**
211  * Compare two configurations.
212  */
213 int ec_config_cmp(const struct ec_config *config1,
214                 const struct ec_config *config2);
215
216 /**
217  * Get configuration value.
218  */
219 struct ec_config *ec_config_get(struct ec_config *config,
220                                 const char *key);
221
222 /**
223  * Get the first element of a list.
224  *
225  * Example of use:
226  * for (config = ec_config_list_iter(list);
227  *      config != NULL;
228  *      config = ec_config_list_next(list, config)) {
229  *              ...
230  * }
231  *
232  * @param list
233  *   The list configuration to iterate.
234  * @return
235  *   The first configuration element, or NULL on error (errno is set).
236  */
237 struct ec_config *ec_config_list_first(struct ec_config *list);
238
239 /**
240  * Get next element in list.
241  *
242  * @param list
243  *   The list configuration beeing iterated.
244  * @param config
245  *   The current configuration element.
246  * @return
247  *   The next configuration element, or NULL if there is no more element.
248  */
249 struct ec_config *
250 ec_config_list_next(struct ec_config *list, struct ec_config *config);
251
252 /**
253  * Remove an element from a list.
254  *
255  * The element is freed and should not be accessed.
256  *
257  * @param list
258  *   The list configuration.
259  * @param config
260  *   The element to remove from the list.
261  */
262 void ec_config_del(struct ec_config *list, struct ec_config *config);
263
264 /**
265  * Free a configuration.
266  *
267  * @param config
268  *   The element to free.
269  */
270 void ec_config_free(struct ec_config *config);
271
272 /**
273  * Compare two configurations.
274  *
275  * @return
276  *   0 if the configurations are equal, else -1.
277  */
278 int ec_config_cmp(const struct ec_config *value1,
279                 const struct ec_config *value2);
280
281 /**
282  * Dump a configuration.
283  *
284  * @param out
285  *   Output stream on which the dump will be sent.
286  * @param config
287  *   The configuration to dump.
288  */
289 void ec_config_dump(FILE *out, const struct ec_config *config);
290
291 #endif