Rename "subsystems" directory to "base"
[oonf.git] / include / oonf / libconfig / cfg_db.h
1
2 /*
3  * The olsr.org Optimized Link-State Routing daemon version 2 (olsrd2)
4  * Copyright (c) 2004-2015, the olsr.org team - see HISTORY file
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  *   notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above copyright
14  *   notice, this list of conditions and the following disclaimer in
15  *   the documentation and/or other materials provided with the
16  *   distribution.
17  * * Neither the name of olsr.org, olsrd nor the names of its
18  *   contributors may be used to endorse or promote products derived
19  *   from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  * Visit http://www.olsr.org for more information.
35  *
36  * If you find this software useful feel free to make a donation
37  * to the project. For more information see the website or contact
38  * the copyright holders.
39  *
40  */
41
42 /**
43  * @file
44  */
45
46 #ifndef CFG_DB_H_
47 #define CFG_DB_H_
48
49 /* forward declaration */
50 struct cfg_db;
51 struct cfg_section_type;
52 struct cfg_named_section;
53 struct cfg_entry;
54
55 #include <oonf/libcommon/avl.h>
56 #include <oonf/oonf.h>
57 #include <oonf/libcommon/string.h>
58
59 #include <oonf/libconfig/cfg_schema.h>
60
61 /**
62  * Represents a single database with configuration entries
63  */
64 struct cfg_db {
65   /*! tree of all sections of this db */
66   struct avl_tree sectiontypes;
67
68   /*! linked schema of db */
69   struct cfg_schema *schema;
70 };
71
72 /**
73  * Represents a section type in a configuration database
74  */
75 struct cfg_section_type {
76   /*! node for tree in database */
77   struct avl_node node;
78
79   /*! name of type */
80   const char *type;
81
82   /*! backpointer to database */
83   struct cfg_db *db;
84
85   /*! tree of named sections */
86   struct avl_tree names;
87 };
88
89 /**
90  * Represents a named section in a configuration database
91  */
92 struct cfg_named_section {
93   /*! node for tree in section type */
94   struct avl_node node;
95
96   /*! name of named section */
97   const char *name;
98
99   /*! backpointer to section type */
100   struct cfg_section_type *section_type;
101
102   /*! tree of entries */
103   struct avl_tree entries;
104 };
105
106 /**
107  * Represents a configuration entry
108  */
109 struct cfg_entry {
110   /*! node for tree in named section */
111   struct avl_node node;
112
113   /*! name of entry */
114   char *name;
115
116   /*! value of entry, might contain multiple strings */
117   struct strarray val;
118
119   /*! backpointer to named section */
120   struct cfg_named_section *named_section;
121 };
122
123 /**
124  * Iterate over all sections types in a configuration database.
125  * This macro should be used similar to a for() or while() construct
126  * @param db configuration database
127  * @param s_type reference of section type variable,
128  *   will be used as the iterator variable
129  * @param safeit helper reference of of section type variable
130  */
131 #define CFG_FOR_ALL_SECTION_TYPES(db, s_type, safeit) avl_for_each_element_safe(&db->sectiontypes, s_type, node, safeit)
132
133 /**
134  * Iterate over all named sections in a section type.
135  * This macro should be used similar to a for() or while() construct
136  * @param s_type configuration section type
137  * @param s_name reference of named section variable,
138  *   will be used as the iterator variable
139  * @param safeit helper reference of of named section variable
140  */
141 #define CFG_FOR_ALL_SECTION_NAMES(s_type, s_name, safeit)                                                              \
142   avl_for_each_element_safe(&s_type->names, s_name, node, safeit)
143
144 /**
145  * Iterate over all entries in a named section.
146  * This macro should be used similar to a for() or while() construct
147  * @param s_name named configuration section
148  * @param entry reference of configuration entry variable,
149  *   will be used as the iterator variable
150  * @param safeit helper reference of configuration entry variable
151  */
152 #define CFG_FOR_ALL_ENTRIES(s_name, entry, safeit) avl_for_each_element_safe(&s_name->entries, entry, node, safeit)
153
154 EXPORT struct cfg_db *cfg_db_add(void);
155 EXPORT void cfg_db_remove(struct cfg_db *);
156 EXPORT int _cfg_db_append(
157   struct cfg_db *dst, struct cfg_db *src, const char *section_type, const char *section_name, const char *entry_name);
158
159 EXPORT struct cfg_named_section *_cfg_db_add_section(
160   struct cfg_db *, const char *section_type, const char *section_name, bool *new_section);
161
162 EXPORT int cfg_db_remove_sectiontype(struct cfg_db *, const char *section_type);
163
164 EXPORT struct cfg_named_section *cfg_db_find_namedsection(
165   const struct cfg_db *, const char *section_type, const char *section_name);
166 EXPORT int cfg_db_remove_namedsection(struct cfg_db *db, const char *section_type, const char *section_name);
167
168 EXPORT struct cfg_entry *cfg_db_set_entry_ext(struct cfg_db *db, const char *section_type, const char *section_name,
169   const char *entry_name, const char *value, bool append, bool front);
170
171 EXPORT struct cfg_entry *cfg_db_find_entry(
172   struct cfg_db *db, const char *section_type, const char *section_name, const char *entry_name);
173 EXPORT int cfg_db_remove_entry(
174   struct cfg_db *, const char *section_type, const char *section_name, const char *entry_name);
175 EXPORT const struct const_strarray *cfg_db_get_entry_value(
176   struct cfg_db *db, const char *section_type, const char *section_name, const char *entry_name);
177 EXPORT const struct const_strarray *cfg_db_get_schema_entry_value(
178   const struct cfg_named_section *section, const struct cfg_schema_entry *entry);
179
180 EXPORT int cfg_db_remove_element(
181   struct cfg_db *, const char *section_type, const char *section_name, const char *entry_name, const char *value);
182
183 /**
184  * Link a configuration schema to a database
185  * @param db pointer to database
186  * @param schema pointer to schema
187  */
188 static INLINE void
189 cfg_db_link_schema(struct cfg_db *db, struct cfg_schema *schema) {
190   db->schema = schema;
191 }
192
193 /**
194  * Creates a copy of a configuration database
195  * @param src original database
196  * @return pointer to the copied database, NULL if out of memory
197  */
198 static INLINE struct cfg_db *
199 cfg_db_duplicate(struct cfg_db *src) {
200   struct cfg_db *dst;
201
202   dst = cfg_db_add();
203   if (dst) {
204     if (_cfg_db_append(dst, src, NULL, NULL, NULL)) {
205       cfg_db_remove(dst);
206       return NULL;
207     }
208   }
209   return dst;
210 }
211
212 /**
213  * Copy all settings from one configuration database to
214  * a second one.
215  * @param dst destination database which will hold the values of
216  *   both databases after the copy
217  * @param src source of the append process
218  * @return 0 if copy was successful, -1 if an error happened.
219  *   In case of an error, the destination might contain a partial
220  *   copy.
221  */
222 static INLINE int
223 cfg_db_copy(struct cfg_db *dst, struct cfg_db *src) {
224   return _cfg_db_append(dst, src, NULL, NULL, NULL);
225 }
226
227 /**
228  * Copy a section_type from one configuration database to
229  * a second one.
230  * @param dst destination database which will hold the values of
231  *   both databases after the copy
232  * @param src source of the append process
233  * @param section_type type of section to be copied
234  * @return 0 if copy was successful, -1 if an error happened.
235  *   In case of an error, the destination might contain a partial
236  *   copy.
237  */
238 static INLINE int
239 cfg_db_copy_sectiontype(struct cfg_db *dst, struct cfg_db *src, const char *section_type) {
240   return _cfg_db_append(dst, src, section_type, NULL, NULL);
241 }
242
243 /**
244  * Copy a named section from one configuration database to
245  * a second one.
246  * @param dst destination database which will hold the values of
247  *   both databases after the copy
248  * @param src source of the append process
249  * @param section_type type of section to be copied
250  * @param section_name name of section to be copied
251  * @return 0 if copy was successful, -1 if an error happened.
252  *   In case of an error, the destination might contain a partial
253  *   copy.
254  */
255 static INLINE int
256 cfg_db_copy_namedsection(struct cfg_db *dst, struct cfg_db *src, const char *section_type, const char *section_name) {
257   return _cfg_db_append(dst, src, section_type, section_name, NULL);
258 }
259
260 /**
261  * Copy a named section from one configuration database to
262  * a second one.
263  * @param dst destination database which will hold the values of
264  *   both databases after the copy
265  * @param src source of the append process
266  * @param section_type type of section to be copied
267  * @param section_name name of section to be copied
268  * @return 0 if copy was successful, -1 if an error happened.
269  *   In case of an error, the destination might contain a partial
270  *   copy.
271  */
272 static INLINE int
273 cfg_db_copy_entry(
274   struct cfg_db *dst, struct cfg_db *src, const char *section_type, const char *section_name, const char *entry_name) {
275   return _cfg_db_append(dst, src, section_type, section_name, entry_name);
276 }
277
278 /**
279  * Finds a section object inside a configuration database
280  * @param db pointer to configuration database
281  * @param section_type type of section
282  * @return pointer to section type , NULL if not found
283  */
284 static INLINE struct cfg_section_type *
285 cfg_db_get_sectiontype(const struct cfg_db *db, const char *section_type) {
286   struct cfg_section_type *section;
287   return avl_find_element(&db->sectiontypes, section_type, section, node);
288 }
289
290 /**
291  * Finds a (named) section inside a section type
292  * @param type pointer to section type
293  * @param name name of section
294  * @return pointer to section, NULL if not found
295  */
296 static INLINE struct cfg_named_section *
297 cfg_db_get_named_section(const struct cfg_section_type *type, const char *name) {
298   struct cfg_named_section *named;
299   return avl_find_element(&type->names, name, named, node);
300 }
301
302 /**
303  * Finds an entry object inside a (named) section.
304  * @param named pointer to section
305  * @param key name of entry
306  * @return pointer to entry, NULL if not found
307  */
308 static INLINE struct cfg_entry *
309 cfg_db_get_entry(const struct cfg_named_section *named, const char *key) {
310   struct cfg_entry *entry;
311   return avl_find_element(&named->entries, key, entry, node);
312 }
313
314 /**
315  * Alias for cfg_db_get_sectiontype
316  * @param db pointer to configuration database
317  * @param section_type type of section
318  * @return pointer to section type , NULL if not found
319  */
320 static INLINE struct cfg_section_type *
321 cfg_db_find_sectiontype(const struct cfg_db *db, const char *section_type) {
322   return cfg_db_get_sectiontype(db, section_type);
323 }
324
325 /**
326  * Finds an unnamed section inside a section type
327  * @param db pointer to configuration database
328  * @param section_type type of section
329  * @return pointer to section, NULL if not found
330  */
331 static INLINE struct cfg_named_section *
332 cfg_db_find_unnamedsection(const struct cfg_db *db, const char *section_type) {
333   return cfg_db_find_namedsection(db, section_type, NULL);
334 }
335
336 /**
337  * @param named pointer to named section
338  * @return true if named sections has a name, false if its an 'unnamed' one.
339  */
340 static INLINE bool
341 cfg_db_is_named_section(const struct cfg_named_section *named) {
342   return named->name != NULL;
343 }
344
345 /**
346  * @param stype section type
347  * @return pointer pointer to 'unnamed' named_section element,
348  *   NULL no unnamed section.
349  */
350 static INLINE struct cfg_named_section *
351 cfg_db_get_unnamed_section(const struct cfg_section_type *stype) {
352   struct cfg_named_section *named;
353   return avl_find_element(&stype->names, NULL, named, node);
354 }
355
356 /**
357  * Adds a named section to a configuration database
358  * @param db pointer to configuration database
359  * @param section_type type of section
360  * @param section_name name of section
361  * @return pointer to named section, NULL if an error happened
362  */
363 static INLINE struct cfg_named_section *
364 cfg_db_add_namedsection(struct cfg_db *db, const char *section_type, const char *section_name) {
365   bool dummy;
366   return _cfg_db_add_section(db, section_type, section_name, &dummy);
367 }
368
369 /**
370  * Adds an unnamed section to a configuration database
371  * @param db pointer to configuration database
372  * @param section_type type of section
373  * @return pointer to named section, NULL if an error happened
374  */
375 static INLINE struct cfg_named_section *
376 cfg_db_add_unnamedsection(struct cfg_db *db, const char *section_type) {
377   bool dummy;
378   return _cfg_db_add_section(db, section_type, NULL, &dummy);
379 }
380
381 /**
382  * Sets an entry to a configuration database
383  * @param db pointer to configuration database
384  * @param section_type type of section
385  * @param section_name name of section, NULL if an unnamed one
386  * @param entry_name entry name
387  * @param value entry value
388  * @param append true if the value should be put in front of a list,
389  *   false if it should overwrite all old values
390  * @return pointer to cfg_entry, NULL if an error happened
391  */
392 static INLINE struct cfg_entry *
393 cfg_db_set_entry(struct cfg_db *db, const char *section_type, const char *section_name, const char *entry_name,
394   const char *value, bool append) {
395   return cfg_db_set_entry_ext(db, section_type, section_name, entry_name, value, append, true);
396 }
397
398 /**
399  * Adds an entry to a configuration database
400  * @param db pointer to configuration database
401  * @param section_type type of section
402  * @param section_name name of section, NULL if an unnamed one
403  * @param entry_name entry name
404  * @param value entry value
405  */
406 static INLINE struct cfg_entry *
407 cfg_db_overwrite_entry(
408   struct cfg_db *db, const char *section_type, const char *section_name, const char *entry_name, const char *value) {
409   return cfg_db_set_entry(db, section_type, section_name, entry_name, value, false);
410 }
411
412 /**
413  * Appends an entry to a configuration database
414  * @param db pointer to configuration database
415  * @param section_type type of section
416  * @param section_name name of section, NULL if an unnamed one
417  * @param entry_name entry name
418  * @param value entry value
419  */
420 static INLINE struct cfg_entry *
421 cfg_db_add_entry(
422   struct cfg_db *db, const char *section_type, const char *section_name, const char *entry_name, const char *value) {
423   return cfg_db_set_entry(db, section_type, section_name, entry_name, value, true);
424 }
425
426 /**
427  * @param entry pointer to configuration entry
428  * @return true if entry has multiple values, false otherwise
429  */
430 static INLINE bool
431 cfg_db_is_multipart_entry(struct cfg_entry *entry) {
432   return strarray_get(&entry->val, 1) != NULL;
433 }
434
435 /**
436  * Counts the number of list items of a configuration entry
437  * @param entry pointer to cfg entry
438  * @return number of items in the entries value
439  */
440 static INLINE size_t
441 cfg_db_entry_get_listsize(struct cfg_entry *entry) {
442   return strarray_get_count(&entry->val);
443 }
444
445 #endif /* CFG_DB_H_ */