Allow default name for sections
[oonf.git] / src-api / config / cfg_db.h
1
2 /*
3  * The olsr.org Optimized Link-State Routing daemon(olsrd)
4  * Copyright (c) 2004-2013, 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 #ifndef CFG_DB_H_
43 #define CFG_DB_H_
44
45 /* forward declaration */
46 struct cfg_db;
47 struct cfg_section_type;
48 struct cfg_named_section;
49 struct cfg_entry;
50
51 #include "common/avl.h"
52 #include "common/common_types.h"
53 #include "common/string.h"
54
55 #include "config/cfg_schema.h"
56
57 /* Represents a single database with configuration entries */
58 struct cfg_db {
59   /* tree of all sections of this db */
60   struct avl_tree sectiontypes;
61
62   /* linked schema of db */
63   struct cfg_schema *schema;
64 };
65
66 /* Represents a section type in a configuration database */
67 struct cfg_section_type {
68   /* node for tree in database */
69   struct avl_node node;
70
71   /* name of type */
72   const char *type;
73
74   /* backpointer to database */
75   struct cfg_db *db;
76
77   /* tree of named sections */
78   struct avl_tree names;
79 };
80
81 /* Represents a named section in a configuration database */
82 struct cfg_named_section {
83   /* node for tree in section type */
84   struct avl_node node;
85
86   /* name of named section */
87   const char *name;
88
89   /* backpointer to section type */
90   struct cfg_section_type *section_type;
91
92   /* tree of entries */
93   struct avl_tree entries;
94 };
95
96 /* Represents a configuration entry */
97 struct cfg_entry {
98   /* node for tree in named section */
99   struct avl_node node;
100
101   /* name of entry */
102   char *name;
103
104   /* value of entry, might contain multiple strings */
105   struct strarray val;
106
107   /* backpointer to named section */
108   struct cfg_named_section *named_section;
109 };
110
111 #define CFG_FOR_ALL_SECTION_TYPES(db, s_type, iterator) avl_for_each_element_safe(&db->sectiontypes, s_type, node, iterator)
112 #define CFG_FOR_ALL_SECTION_NAMES(s_type, s_name, iterator) avl_for_each_element_safe(&s_type->names, s_name, node, iterator)
113 #define CFG_FOR_ALL_ENTRIES(s_name, entry, iterator) avl_for_each_element_safe(&s_name->entries, entry, node, iterator)
114
115 EXPORT struct cfg_db *cfg_db_add(void);
116 EXPORT void cfg_db_remove(struct cfg_db *);
117 EXPORT int _cfg_db_append(struct cfg_db *dst, struct cfg_db *src,
118     const char *section_type, const char *section_name, const char *entry_name);
119
120 EXPORT struct cfg_named_section *_cfg_db_add_section(
121     struct cfg_db *, const char *section_type, const char *section_name,
122     bool *new_section);
123
124 EXPORT int cfg_db_remove_sectiontype(struct cfg_db *, const char *section_type);
125
126 EXPORT struct cfg_named_section *cfg_db_find_namedsection(
127     struct cfg_db *, const char *section_type, const char *section_name);
128 EXPORT int cfg_db_remove_namedsection(struct cfg_db *db, const char *section_type,
129     const char *section_name);
130
131 EXPORT struct cfg_entry *cfg_db_set_entry_ext(struct cfg_db *db, const char *section_type,
132     const char *section_name, const char *entry_name, const char *value,
133     bool append, bool front);
134
135 EXPORT struct cfg_entry *cfg_db_find_entry(struct cfg_db *db,
136     const char *section_type, const char *section_name, const char *entry_name);
137 EXPORT int cfg_db_remove_entry(struct cfg_db *, const char *section_type,
138     const char *section_name, const char *entry_name);
139 EXPORT const struct const_strarray *cfg_db_get_entry_value(struct cfg_db *db,
140     const char *section_type, const char *section_name, const char *entry_name);
141
142 EXPORT int cfg_db_remove_element(struct cfg_db *, const char *section_type,
143     const char *section_name, const char *entry_name, const char *value);
144
145 /**
146  * Link a configuration schema to a database
147  * @param db pointer to database
148  * @param schema pointer to schema
149  */
150 static INLINE void
151 cfg_db_link_schema(struct cfg_db *db, struct cfg_schema *schema) {
152   db->schema = schema;
153 }
154
155 /**
156  * Creates a copy of a configuration database
157  * @param src original database
158  * @return pointer to the copied database, NULL if out of memory
159  */
160 static INLINE struct cfg_db *
161 cfg_db_duplicate(struct cfg_db *src) {
162   struct cfg_db *dst;
163
164   dst = cfg_db_add();
165   if (dst) {
166     if (_cfg_db_append(dst, src, NULL, NULL, NULL)) {
167       cfg_db_remove(dst);
168       return NULL;
169     }
170   }
171   return dst;
172 }
173
174 /**
175  * Copy all settings from one configuration database to
176  * a second one.
177  * @param dst destination database which will hold the values of
178  *   both databases after the copy
179  * @param src source of the append process
180  * @return 0 if copy was successful, -1 if an error happened.
181  *   In case of an error, the destination might contain a partial
182  *   copy.
183  */
184 static INLINE int
185 cfg_db_copy(struct cfg_db *dst, struct cfg_db *src) {
186   return _cfg_db_append(dst, src, NULL, NULL, NULL);
187 }
188
189 /**
190  * Copy a section_type from one configuration database to
191  * a second one.
192  * @param dst destination database which will hold the values of
193  *   both databases after the copy
194  * @param src source of the append process
195  * @param section_type type of section to be copied
196  * @return 0 if copy was successful, -1 if an error happened.
197  *   In case of an error, the destination might contain a partial
198  *   copy.
199  */
200 static INLINE int
201 cfg_db_copy_sectiontype(struct cfg_db *dst, struct cfg_db *src,
202     const char *section_type) {
203   return _cfg_db_append(dst, src, section_type, NULL, NULL);
204 }
205
206 /**
207  * Copy a named section from one configuration database to
208  * a second one.
209  * @param dst destination database which will hold the values of
210  *   both databases after the copy
211  * @param src source of the append process
212  * @param section_type type of section to be copied
213  * @param section_name name of section to be copied
214  * @return 0 if copy was successful, -1 if an error happened.
215  *   In case of an error, the destination might contain a partial
216  *   copy.
217  */
218 static INLINE int
219 cfg_db_copy_namedsection(struct cfg_db *dst, struct cfg_db *src,
220     const char *section_type, const char *section_name) {
221   return _cfg_db_append(dst, src, section_type, section_name, NULL);
222 }
223
224 /**
225  * Copy a named section from one configuration database to
226  * a second one.
227  * @param dst destination database which will hold the values of
228  *   both databases after the copy
229  * @param src source of the append process
230  * @param section_type type of section to be copied
231  * @param section_name name of section to be copied
232  * @return 0 if copy was successful, -1 if an error happened.
233  *   In case of an error, the destination might contain a partial
234  *   copy.
235  */
236 static INLINE int
237 cfg_db_copy_entry(struct cfg_db *dst, struct cfg_db *src,
238     const char *section_type, const char *section_name, const char *entry_name) {
239   return _cfg_db_append(dst, src, section_type, section_name, entry_name);
240 }
241
242 /**
243  * Finds a section object inside a configuration database
244  * @param db pointer to configuration database
245  * @param section_type type of section
246  * @return pointer to section type , NULL if not found
247  */
248 static INLINE struct cfg_section_type *
249 cfg_db_get_sectiontype(struct cfg_db *db, const char *section_type) {
250   struct cfg_section_type *section;
251   return avl_find_element(&db->sectiontypes, section_type, section, node);
252 }
253
254 /**
255  * Finds a (named) section inside a section type
256  * @param type pointer to section type
257  * @param name name of section
258  * @return pointer to section, NULL if not found
259  */
260 static INLINE struct cfg_named_section *
261 cfg_db_get_named_section(struct cfg_section_type *type, const char *name) {
262   struct cfg_named_section *named;
263   return avl_find_element(&type->names, name, named, node);
264 }
265
266 /**
267  * Finds an entry object inside a (named) section.
268  * @param named pointer to section
269  * @param key name of entry
270  * @return pointer to entry, NULL if not found
271  */
272 static INLINE struct cfg_entry *
273 cfg_db_get_entry(struct cfg_named_section *named, const char *key) {
274   struct cfg_entry *entry;
275   return avl_find_element(&named->entries, key, entry, node);
276 }
277
278 /**
279  * Alias for cfg_db_get_sectiontype
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_find_sectiontype(struct cfg_db *db, const char *section_type) {
286   return cfg_db_get_sectiontype(db, section_type);
287 }
288
289 /**
290  * Finds an unnamed section inside a section type
291  * @param type pointer to section type
292  * @return pointer to section, NULL if not found
293  */
294 static INLINE struct cfg_named_section *
295 cfg_db_find_unnamedsection(struct cfg_db *db, const char *section_type) {
296   return cfg_db_find_namedsection(db, section_type, NULL);
297 }
298
299 /**
300  * @param named pointer to named section
301  * @return true if named sections has a name, false if its an 'unnamed' one.
302  */
303 static INLINE bool
304 cfg_db_is_named_section(struct cfg_named_section *named) {
305   return named->name != NULL;
306 }
307
308 /**
309  * @param pointer to section type
310  * @return pointer pointer to 'unnamed' named_section element,
311  *   NULL no unnamed section.
312  */
313 static INLINE struct cfg_named_section *
314 cfg_db_get_unnamed_section(struct cfg_section_type *stype) {
315   struct cfg_named_section *named;
316   return avl_find_element(&stype->names, NULL, named, node);
317 }
318
319 /**
320  * Adds a named section to a configuration database
321  * @param db pointer to configuration database
322  * @param section_type type of section
323  * @param section_name name of section
324  * @return pointer to named section, NULL if an error happened
325  */
326 static INLINE struct cfg_named_section *
327 cfg_db_add_namedsection(
328     struct cfg_db *db, const char *section_type, const char *section_name) {
329   bool dummy;
330   return _cfg_db_add_section(db, section_type, section_name, &dummy);
331 }
332
333 /**
334  * Adds an unnamed section to a configuration database
335  * @param db pointer to configuration database
336  * @param section_type type of section
337  * @return pointer to named section, NULL if an error happened
338  */
339 static INLINE struct cfg_named_section *
340 cfg_db_add_unnamedsection(
341     struct cfg_db *db, const char *section_type) {
342   bool dummy;
343   return _cfg_db_add_section(db, section_type, NULL, &dummy);
344 }
345
346 /**
347  * Sets an entry to a configuration database
348  * @param db pointer to configuration database
349  * @param section_type type of section
350  * @param section_name name of section, NULL if an unnamed one
351  * @param entry_name entry name
352  * @param value entry value
353  * @param append true if the value should be put in front of a list,
354  *   false if it should overwrite all old values
355  * @return pointer to cfg_entry, NULL if an error happened
356  */
357 static INLINE struct cfg_entry *
358 cfg_db_set_entry(struct cfg_db *db, const char *section_type,
359     const char *section_name, const char *entry_name, const char *value,
360     bool append) {
361   return cfg_db_set_entry_ext(db, section_type, section_name, entry_name,
362       value, append, true);
363 }
364
365 /**
366  * Adds an entry to a configuration database
367  * @param db pointer to configuration database
368  * @param section_type type of section
369  * @param section_name name of section, NULL if an unnamed one
370  * @param entry_name entry name
371  * @param value entry value
372  */
373 static INLINE int
374 cfg_db_overwrite_entry(struct cfg_db *db, const char *section_type,
375     const char *section_name, const char *entry_name, const char *value) {
376   if (cfg_db_set_entry(db, section_type, section_name, entry_name, value, false)) {
377     return 0;
378   }
379   return -1;
380 }
381
382 /**
383  * Appends an entry to a configuration database
384  * @param db pointer to configuration database
385  * @param section_type type of section
386  * @param section_name name of section, NULL if an unnamed one
387  * @param entry_name entry name
388  * @param value entry value
389  */
390 static INLINE int
391 cfg_db_add_entry(struct cfg_db *db, const char *section_type,
392     const char *section_name, const char *entry_name, const char *value) {
393   if (cfg_db_set_entry(db, section_type, section_name, entry_name, value, true)) {
394     return 0;
395   }
396   return -1;
397 }
398
399 /**
400  * @param entry pointer to configuration entry
401  * @return true if entry has multiple values, false otherwise
402  */
403 static INLINE bool
404 cfg_db_is_multipart_entry(struct cfg_entry *entry) {
405   return strarray_get(&entry->val, 1) != NULL;
406 }
407
408
409 /**
410  * Counts the number of list items of a configuration entry
411  * @param entry pointer to cfg entry
412  * @return number of items in the entries value
413  */
414 static INLINE size_t
415 cfg_db_entry_get_listsize(struct cfg_entry *entry) {
416   return strarray_get_count(&entry->val);
417 }
418
419 #endif /* CFG_DB_H_ */