1 /***********************************************************************
2  Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License as published by
5    the Free Software Foundation; either version 2, or (at your option)
6    any later version.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 ***********************************************************************/
13 #ifndef FC__REGISTRY_INI_H
14 #define FC__REGISTRY_INI_H
15 
16 #ifdef __cplusplus
17 extern "C" {
18 #endif /* __cplusplus */
19 
20 /* utility */
21 #include "ioz.h"
22 #include "support.h"            /* bool type and fc__attribute */
23 
24 /* Opaque types. */
25 struct section_file;
26 struct section;
27 struct entry;
28 
29 /* Typedefs. */
30 typedef const void *secfile_data_t;
31 
32 typedef bool (*secfile_enum_is_valid_fn_t) (int enumerator);
33 typedef const char * (*secfile_enum_name_fn_t) (int enumerator);
34 typedef int (*secfile_enum_by_name_fn_t) (const char *enum_name,
35                                           int (*strcmp_fn)(const char *,
36                                                            const char *));
37 typedef int (*secfile_enum_iter_fn_t) (void);
38 typedef int (*secfile_enum_next_fn_t) (int enumerator);
39 typedef const char * (*secfile_enum_name_data_fn_t) (secfile_data_t data,
40                                                      int enumerator);
41 
42 /* Create a 'struct section_list' and related functions: */
43 #define SPECLIST_TAG section
44 #include "speclist.h"
45 #define section_list_iterate(seclist, psection) \
46        TYPED_LIST_ITERATE(struct section, seclist, psection)
47 #define section_list_iterate_end  LIST_ITERATE_END
48 #define section_list_iterate_rev(seclist, psection) \
49        TYPED_LIST_ITERATE_REV(struct section, seclist, psection)
50 #define section_list_iterate_rev_end  LIST_ITERATE_REV_END
51 
52 /* Create a 'struct entry_list' and related functions: */
53 #define SPECLIST_TAG entry
54 #include "speclist.h"
55 #define entry_list_iterate(entlist, pentry) \
56        TYPED_LIST_ITERATE(struct entry, entlist, pentry)
57 #define entry_list_iterate_end  LIST_ITERATE_END
58 
59 /* Main functions. */
60 struct section_file *secfile_load_section(const char *filename,
61                                           const char *section,
62                                           bool allow_duplicates);
63 struct section_file *secfile_from_stream(fz_FILE *stream,
64                                          bool allow_duplicates);
65 
66 bool secfile_save(const struct section_file *secfile, const char *filename,
67                   int compression_level, enum fz_method compression_method);
68 void secfile_check_unused(const struct section_file *secfile);
69 const char *secfile_name(const struct section_file *secfile);
70 
71 /* Insertion functions. */
72 struct entry *secfile_insert_bool_full(struct section_file *secfile,
73                                        bool value, const char *comment,
74                                        bool allow_replace,
75                                        const char *path, ...)
76                                        fc__attribute((__format__(__printf__, 5, 6)));
77 #define secfile_insert_bool(secfile, value, path, ...)                      \
78   secfile_insert_bool_full(secfile, value, NULL, FALSE,                     \
79                            path, ## __VA_ARGS__)
80 #define secfile_insert_bool_comment(secfile, value, comment, path, ...)     \
81   secfile_insert_bool_full(secfile, value, comment, FALSE,                  \
82                            path, ## __VA_ARGS__)
83 #define secfile_replace_bool(secfile, value, path, ...)                     \
84   secfile_insert_bool_full(secfile, value, NULL, TRUE,                      \
85                            path, ## __VA_ARGS__)
86 #define secfile_replace_bool_comment(secfile, value, comment, path, ...)    \
87   secfile_insert_bool_full(secfile, value, comment, TRUE,                   \
88                            path, ## __VA_ARGS__)
89 size_t secfile_insert_bool_vec_full(struct section_file *secfile,
90                                     const bool *values, size_t dim,
91                                     const char *comment, bool allow_replace,
92                                     const char *path, ...)
93                                     fc__attribute((__format__(__printf__, 6, 7)));
94 #define secfile_insert_bool_vec(secfile, values, dim, path, ...)            \
95   secfile_insert_bool_vec_full(secfile, values, dim, NULL, FALSE,           \
96                                path, ## __VA_ARGS__)
97 #define secfile_insert_bool_vec_comment(secfile, values, dim,               \
98                                         comment, path, ...)                 \
99   secfile_insert_bool_vec_full(secfile, values, dim, comment, FALSE,        \
100                                path, ## __VA_ARGS__)
101 #define secfile_replace_bool_vec(secfile, values, dim, path, ...)           \
102   secfile_insert_bool_vec_full(secfile, values, dim, NULL, TRUE,            \
103                                path, ## __VA_ARGS__)
104 #define secfile_replace_bool_vec_comment(secfile, values, dim,              \
105                                          comment, path, ...)                \
106   secfile_insert_bool_vec_full(secfile, values, comment, TRUE,              \
107                                path, ## __VA_ARGS__)
108 
109 struct entry *secfile_insert_int_full(struct section_file *secfile,
110                                       int value, const char *comment,
111                                       bool allow_replace,
112                                       const char *path, ...)
113                                       fc__attribute((__format__ (__printf__, 5, 6)));
114 #define secfile_insert_int(secfile, value, path, ...)                       \
115   secfile_insert_int_full(secfile, value, NULL, FALSE,                      \
116                           path, ## __VA_ARGS__)
117 #define secfile_insert_int_comment(secfile, value, comment, path, ...)      \
118   secfile_insert_int_full(secfile, value, comment, FALSE,                   \
119                           path, ## __VA_ARGS__)
120 #define secfile_replace_int(secfile, value, path, ...)                      \
121   secfile_insert_int_full(secfile, value, NULL, TRUE,                       \
122                           path, ## __VA_ARGS__)
123 #define secfile_replace_int_comment(secfile, value, comment, path, ...)     \
124   secfile_insert_int_full(secfile, value, comment, TRUE,                    \
125                           path, ## __VA_ARGS__)
126 size_t secfile_insert_int_vec_full(struct section_file *secfile,
127                                    const int *values, size_t dim,
128                                    const char *comment, bool allow_replace,
129                                    const char *path, ...)
130                                    fc__attribute((__format__ (__printf__, 6, 7)));
131 #define secfile_insert_int_vec(secfile, values, dim, path, ...)             \
132   secfile_insert_int_vec_full(secfile, values, dim, NULL, FALSE,            \
133                               path, ## __VA_ARGS__)
134 #define secfile_insert_int_vec_comment(secfile, values, dim,                \
135                                        comment, path, ...)                  \
136   secfile_insert_int_vec_full(secfile, values, dim, comment, FALSE,         \
137                               path, ## __VA_ARGS__)
138 #define secfile_replace_int_vec(secfile, values, dim, path, ...)            \
139   secfile_insert_int_vec_full(secfile, values, dim,  NULL, TRUE,            \
140                               path, ## __VA_ARGS__)
141 #define secfile_replace_int_vec_comment(secfile, values, dim,               \
142                                         comment, path, ...)                 \
143   secfile_insert_int_vec_full(secfile, values, dim, comment, TRUE,          \
144                               path, ## __VA_ARGS__)
145 
146 struct entry *secfile_insert_float_full(struct section_file *secfile,
147                                         float value, const char *comment,
148                                         bool allow_replace,
149                                         const char *path, ...)
150                                         fc__attribute((__format__ (__printf__, 5, 6)));
151 #define secfile_insert_float(secfile, value, path, ...)                     \
152   secfile_insert_float_full(secfile, value, NULL, FALSE,                    \
153                             path, ## __VA_ARGS__)
154 
155 struct section *secfile_insert_include(struct section_file *secfile,
156                                        const char *filename);
157 
158 struct entry *secfile_insert_str_full(struct section_file *secfile,
159                                       const char *str,
160                                       const char *comment,
161                                       bool allow_replace, bool no_escape,
162                                       bool include,
163                                       const char *path, ...)
164                                       fc__attribute((__format__(__printf__, 7, 8)));
165 #define secfile_insert_str(secfile, string, path, ...)                      \
166   secfile_insert_str_full(secfile, string, NULL, FALSE, FALSE, FALSE,       \
167                           path, ## __VA_ARGS__)
168 #define secfile_insert_str_noescape(secfile, string, path, ...)             \
169   secfile_insert_str_full(secfile, string, NULL, FALSE, TRUE, FALSE,        \
170                           path, ## __VA_ARGS__)
171 #define secfile_insert_str_comment(secfile, string, comment, path, ...)     \
172   secfile_insert_str_full(secfile, string, comment, FALSE, TRUE, FALSE,     \
173                           path, ## __VA_ARGS__)
174 #define secfile_insert_str_noescape_comment(secfile, string,                \
175                                             comment, path, ...)             \
176   secfile_insert_str_full(secfile, string, comment, FALSE, TRUE, FALSE,     \
177                           path, ## __VA_ARGS__)
178 #define secfile_replace_str(secfile, string, path, ...)                     \
179   secfile_insert_str_full(secfile, string, NULL, TRUE, FALSE, FALSE,        \
180                           path, ## __VA_ARGS__)
181 #define secfile_replace_str_noescape(secfile, string, path, ...)            \
182   secfile_insert_str_full(secfile, string, NULL, TRUE, TRUE, FALSE,         \
183                           path, ## __VA_ARGS__)
184 #define secfile_replace_str_comment(secfile, string, comment, path, ...)    \
185   secfile_insert_str_full(secfile, string, comment, TRUE, TRUE, FALSE,      \
186                           path, ## __VA_ARGS__)
187 #define secfile_replace_str_noescape_comment(secfile, string,               \
188                                              comment, path, ...)            \
189   secfile_insert_str_full(secfile, string, comment, TRUE, TRUE, FALSE,      \
190                           path, ## __VA_ARGS__)
191 size_t secfile_insert_str_vec_full(struct section_file *secfile,
192                                    const char *const *strings, size_t dim,
193                                    const char *comment, bool allow_replace,
194                                    bool no_escape, const char *path, ...)
195                                    fc__attribute((__format__(__printf__, 7, 8)));
196 #define secfile_insert_str_vec(secfile, strings, dim, path, ...)            \
197   secfile_insert_str_vec_full(secfile, strings, dim, NULL, FALSE, FALSE,    \
198                               path, ## __VA_ARGS__)
199 #define secfile_insert_str_vec_noescape(secfile, strings, dim, path, ...)   \
200   secfile_insert_str_vec_full(secfile, strings, dim, NULL, FALSE, TRUE,     \
201                               path, ## __VA_ARGS__)
202 #define secfile_insert_str_vec_comment(secfile, strings, dim,               \
203                                        comment, path, ...)                  \
204   secfile_insert_str_vec_full(secfile, strings, dim, comment, FALSE, TRUE,  \
205                               path, ## __VA_ARGS__)
206 #define secfile_insert_str_vec_noescape_comment(secfile, strings, dim,      \
207                                                 comment, path, ...)         \
208   secfile_insert_str_vec_full(secfile, strings, dim, comment, FALSE, TRUE,  \
209                               path, ## __VA_ARGS__)
210 #define secfile_replace_str_vec(secfile, strings, dim, path, ...)           \
211   secfile_insert_str_vec_full(secfile, strings, dim, NULL, TRUE, FALSE,     \
212                               path, ## __VA_ARGS__)
213 #define secfile_replace_str_vec_noescape(secfile, strings, dim, path, ...)  \
214   secfile_insert_str_vec_full(secfile, strings, dim, NULL, TRUE, TRUE,      \
215                               path, ## __VA_ARGS__)
216 #define secfile_replace_str_vec_comment(secfile, strings, dim,              \
217                                         comment, path, ...)                 \
218   secfile_insert_str_vec_full(secfile, strings, dim, comment, TRUE, TRUE,   \
219                               path, ## __VA_ARGS__)
220 #define secfile_replace_str_vec_noescape_comment(secfile, strings, dim,     \
221                                                  comment, path, ...)        \
222   secfile_insert_str_vec_full(secfile, strings, dim, comment, TRUE, TRUE,   \
223                               path, ## __VA_ARGS__)
224 
225 struct entry *secfile_insert_plain_enum_full(struct section_file *secfile,
226                                              int enumerator,
227                                              secfile_enum_name_fn_t name_fn,
228                                              const char *comment,
229                                              bool allow_replace,
230                                              const char *path, ...)
231                                              fc__attribute((__format__(__printf__, 6, 7)));
232 struct entry *secfile_insert_bitwise_enum_full(struct section_file *secfile,
233                                                int bitwise_val,
234                                                secfile_enum_name_fn_t name_fn,
235                                                secfile_enum_iter_fn_t begin_fn,
236                                                secfile_enum_iter_fn_t end_fn,
237                                                secfile_enum_next_fn_t next_fn,
238                                                const char *comment,
239                                                bool allow_replace,
240                                                const char *path, ...)
241                                                fc__attribute((__format__(__printf__, 9, 10)));
242 #define secfile_insert_enum_full(secfile, enumerator, specenum_type,        \
243                                  comment, allow_replace, path, ...)         \
244 (specenum_type##_is_bitwise()                                               \
245  ? secfile_insert_bitwise_enum_full(secfile, enumerator,                    \
246                                     (secfile_enum_name_fn_t)                \
247                                     specenum_type##_name,                   \
248                                     (secfile_enum_iter_fn_t)                \
249                                     specenum_type##_begin,                  \
250                                     (secfile_enum_iter_fn_t)                \
251                                     specenum_type##_end,                    \
252                                     (secfile_enum_next_fn_t)                \
253                                     specenum_type##_next,                   \
254                                     comment, allow_replace,                 \
255                                     path, ## __VA_ARGS__)                   \
256  : secfile_insert_plain_enum_full(secfile, enumerator,                      \
257                                   (secfile_enum_name_fn_t)                  \
258                                   specenum_type##_name,                     \
259                                   comment, allow_replace,                   \
260                                   path, ## __VA_ARGS__))
261 #define secfile_insert_enum(secfile, enumerator, specenum_type, path, ...)  \
262   secfile_insert_enum_full(secfile, enumerator, specenum_type, NULL, FALSE, \
263                            path, ## __VA_ARGS__)
264 #define secfile_insert_enum_comment(secfile, enumerator, specenum_type,     \
265                                     comment, path, ...)                     \
266   secfile_insert_enum_full(secfile, enumerator, specenum_type, comment,     \
267                            FALSE, path, ## __VA_ARGS__)
268 #define secfile_replace_enum(secfile, enumerator, specenum_type, path, ...) \
269   secfile_insert_enum_full(secfile, enumerator, specenum_type, NULL, TRUE,  \
270                            path, ## __VA_ARGS__)
271 #define secfile_replace_enum_comment(secfile, enumerator, specenum_type,    \
272                                      comment, path, ...)                    \
273   secfile_insert_enum_full(secfile, enumerator, specenum_type, comment,     \
274                            TRUE, path, ## __VA_ARGS__)
275 size_t secfile_insert_plain_enum_vec_full(struct section_file *secfile,
276                                           const int *enumurators, size_t dim,
277                                           secfile_enum_name_fn_t name_fn,
278                                           const char *comment,
279                                           bool allow_replace,
280                                           const char *path, ...)
281                                           fc__attribute((__format__(__printf__, 7, 8)));
282 size_t secfile_insert_bitwise_enum_vec_full(struct section_file *secfile,
283                                             const int *bitwise_vals,
284                                             size_t dim,
285                                             secfile_enum_name_fn_t name_fn,
286                                             secfile_enum_iter_fn_t begin_fn,
287                                             secfile_enum_iter_fn_t end_fn,
288                                             secfile_enum_next_fn_t next_fn,
289                                             const char *comment,
290                                             bool allow_replace,
291                                             const char *path, ...)
292                                             fc__attribute((__format__(__printf__, 10, 11)));
293 #define secfile_insert_enum_vec_full(secfile, enumerators, dim,             \
294                                      specenum_type, comment, allow_replace, \
295                                      path, ...)                             \
296 (specenum_type##_is_bitwise()                                               \
297  ? secfile_insert_bitwise_enum_vec_full(secfile, (const int *) enumerators, \
298                                         dim,                                \
299                                         (secfile_enum_name_fn_t)            \
300                                         specenum_type##_name,               \
301                                         (secfile_enum_iter_fn_t)            \
302                                         specenum_type##_begin,              \
303                                         (secfile_enum_iter_fn_t)            \
304                                         specenum_type##_end,                \
305                                         (secfile_enum_next_fn_t)            \
306                                         specenum_type##_next,               \
307                                         comment, allow_replace,             \
308                                         path, ## __VA_ARGS__)               \
309  : secfile_insert_plain_enum_vec_full(secfile, (const int *) enumerators,   \
310                                       dim,                                  \
311                                       (secfile_enum_name_fn_t)              \
312                                       specenum_type##_name,                 \
313                                       comment, allow_replace,               \
314                                       path, ## __VA_ARGS__))
315 #define secfile_insert_enum_vec(secfile, enumerators, dim, specenum_type,   \
316                                 path, ...)                                  \
317   secfile_insert_enum_vec_full(secfile, enumerators, dim, specenum_type,    \
318                                NULL, FALSE, path, ## __VA_ARGS__)
319 #define secfile_insert_enum_vec_comment(secfile, enumerators, dim,          \
320                                         specenum_type, comment, path, ...)  \
321   secfile_insert_enum_vec_full(secfile, enumerators, dim, specenum_type,    \
322                                comment, FALSE, path, ## __VA_ARGS__)
323 #define secfile_replace_enum_vec(secfile, enumerators, dim, specenum_type,  \
324                                  path, ...)                                 \
325   secfile_insert_enum_vec_full(secfile, enumerators, dim, specenum_type,    \
326                                NULL, TRUE, path, ## __VA_ARGS__)
327 #define secfile_replace_enum_vec_comment(secfile, enumerators, dim,         \
328                                          specenum_type, comment, path, ...) \
329   secfile_insert_enum_vec_full(secfile, enumerators, dim, specenum_type,    \
330                                comment, TRUE, path, ## __VA_ARGS__)
331 
332 struct entry *secfile_insert_enum_data_full(struct section_file *secfile,
333                                             int value, bool bitwise,
334                                             secfile_enum_name_data_fn_t name_fn,
335                                             secfile_data_t data,
336                                             const char *comment,
337                                             bool allow_replace,
338                                             const char *path, ...)
339                                             fc__attribute((__format__(__printf__, 8, 9)));
340 #define secfile_insert_enum_data(secfile, value, bitwise, name_fn, data,    \
341                                  path, ...)                                 \
342   secfile_insert_enum_data_full(secfile, value, bitwise, name_fn, data,     \
343                                 NULL, FALSE, path, ## __VA_ARGS__)
344 #define secfile_insert_enum_data_comment(secfile, value, bitwise, name_fn,  \
345                                          data, path, ...)                   \
346   secfile_insert_enum_data_full(secfile, value, bitwise, name_fn, data,     \
347                                 comment, FALSE, path, ## __VA_ARGS__)
348 #define secfile_replace_enum_data(secfile, value, bitwise, name_fn, data,   \
349                                   path, ...)                                \
350   secfile_insert_enum_data_full(secfile, value, bitwise, name_fn, data,     \
351                                 NULL, TRUE, path, ## __VA_ARGS__)
352 #define secfile_replace_enum_data_comment(secfile, value, bitwise, name_fn, \
353                                           data, path, ...)                  \
354   secfile_insert_enum_data_full(secfile, value, bitwise, name_fn, data,     \
355                                 comment, TRUE, path, ## __VA_ARGS__)
356 size_t secfile_insert_enum_vec_data_full(struct section_file *secfile,
357                                          const int *values, size_t dim,
358                                          bool bitwise,
359                                          secfile_enum_name_data_fn_t name_fn,
360                                          secfile_data_t data,
361                                          const char *comment,
362                                          bool allow_replace,
363                                          const char *path, ...)
364                                          fc__attribute((__format__(__printf__, 9, 10)));
365 #define secfile_insert_enum_vec_data(secfile, values, dim, bitwise,         \
366                                      name_fn, data, path, ...)              \
367   secfile_insert_enum_vec_data_full(secfile, values, dim, bitwise, name_fn, \
368                                     data, NULL, FALSE, path, ## __VA_ARGS__)
369 #define secfile_insert_enum_vec_data_comment(secfile, values, dim, bitwise, \
370                                              name_fn, data, path, ...)      \
371   secfile_insert_enum_vec_data_full(secfile, values, dim, bitwise, name_fn, \
372                                     data, comment, FALSE, path,             \
373                                     ## __VA_ARGS__)
374 #define secfile_replace_enum_vec_data(secfile, values, dim, bitwise,        \
375                                       name_fn, data, path, ...)             \
376   secfile_insert_enum_vec_data_full(secfile, values, dim, bitwise, name_fn, \
377                                     data, NULL, TRUE, path, ## __VA_ARGS__)
378 #define secfile_replace_enum_vec_data_comment(secfile, values, dim,         \
379                                               bitwise, name_fn, data, path, \
380                                               ...)                          \
381   secfile_insert_enum_vec_data_full(secfile, values, dim, bitwise, name_fn, \
382                                     data, comment, TRUE, path,              \
383                                     ## __VA_ARGS__)
384 
385 struct entry *secfile_insert_filereference(struct section_file *secfile,
386                                            char *filename, char *path, ...)
387                               fc__attribute((__format__ (__printf__, 3, 4)));
388 
389 /* Deletion function. */
390 bool secfile_entry_delete(struct section_file *secfile,
391                           const char *path, ...)
392                           fc__attribute((__format__ (__printf__, 2, 3)));
393 
394 /* Lookup functions. */
395 struct entry *secfile_entry_by_path(const struct section_file *secfile,
396                                     const char *path);
397 struct entry *secfile_entry_lookup(const struct section_file *secfile,
398                                    const char *path, ...)
399                                    fc__attribute((__format__ (__printf__, 2, 3)));
400 
401 bool secfile_lookup_bool(const struct section_file *secfile, bool *bval,
402                          const char *path, ...)
403                          fc__warn_unused_result
404                          fc__attribute((__format__ (__printf__, 3, 4)));
405 bool secfile_lookup_bool_default(const struct section_file *secfile,
406                                  bool def, const char *path, ...)
407                                  fc__warn_unused_result
408                                  fc__attribute((__format__ (__printf__, 3, 4)));
409 bool *secfile_lookup_bool_vec(const struct section_file *secfile,
410                               size_t *dim, const char *path, ...)
411                               fc__warn_unused_result
412                               fc__attribute((__format__ (__printf__, 3, 4)));
413 
414 bool secfile_lookup_int(const struct section_file *secfile, int *ival,
415                         const char *path, ...)
416                         fc__warn_unused_result
417                         fc__attribute((__format__ (__printf__, 3, 4)));
418 int secfile_lookup_int_default(const struct section_file *secfile, int def,
419                                const char *path, ...)
420                                fc__warn_unused_result
421                                fc__attribute((__format__ (__printf__, 3, 4)));
422 int secfile_lookup_int_def_min_max(const struct section_file *secfile,
423                                 int defval, int minval, int maxval,
424                                 const char *path, ...)
425                                 fc__warn_unused_result
426                                 fc__attribute((__format__ (__printf__, 5, 6)));
427 int *secfile_lookup_int_vec(const struct section_file *secfile,
428                             size_t *dim, const char *path, ...)
429                             fc__warn_unused_result
430                             fc__attribute((__format__ (__printf__, 3, 4)));
431 
432 bool secfile_lookup_float(const struct section_file *secfile, float *fval,
433                           const char *path, ...)
434                           fc__warn_unused_result
435                           fc__attribute((__format__ (__printf__, 3, 4)));
436 float secfile_lookup_float_default(const struct section_file *secfile,
437                                    float def, const char *path, ...);
438 
439 const char *secfile_lookup_str(const struct section_file *secfile,
440                                const char *path, ...)
441                                fc__warn_unused_result
442                                fc__attribute((__format__ (__printf__, 2, 3)));
443 const char *secfile_lookup_str_default(const struct section_file *secfile,
444                                        const char *def,
445                                        const char *path, ...)
446                                        fc__warn_unused_result
447                                        fc__attribute((__format__ (__printf__, 3, 4)));
448 const char **secfile_lookup_str_vec(const struct section_file *secfile,
449                                     size_t *dim, const char *path, ...)
450                                     fc__attribute((__format__ (__printf__, 3, 4)));
451 
452 bool secfile_lookup_plain_enum_full(const struct section_file *secfile,
453                                     int *penumerator,
454                                     secfile_enum_is_valid_fn_t is_valid_fn,
455                                     secfile_enum_by_name_fn_t by_name_fn,
456                                     const char *path, ...)
457                                     fc__warn_unused_result
458                                     fc__attribute((__format__ (__printf__, 5, 6)));
459 bool secfile_lookup_bitwise_enum_full(const struct section_file *secfile,
460                                       int *penumerator,
461                                       secfile_enum_is_valid_fn_t is_valid_fn,
462                                       secfile_enum_by_name_fn_t by_name_fn,
463                                       const char *path, ...)
464                                       fc__warn_unused_result
465                                       fc__attribute((__format__ (__printf__, 5, 6)));
466 #define secfile_lookup_enum(secfile, enumerator, specenum_type, path, ...)  \
467 (specenum_type##_is_bitwise()                                               \
468  ? secfile_lookup_bitwise_enum_full(secfile, FC_ENUM_PTR(enumerator),       \
469                                     (secfile_enum_is_valid_fn_t)            \
470                                     specenum_type##_is_valid,               \
471                                     (secfile_enum_by_name_fn_t)             \
472                                     specenum_type##_by_name,                \
473                                     path, ## __VA_ARGS__)                   \
474  : secfile_lookup_plain_enum_full(secfile, FC_ENUM_PTR(enumerator),         \
475                                   (secfile_enum_is_valid_fn_t)              \
476                                   specenum_type##_is_valid,                 \
477                                   (secfile_enum_by_name_fn_t)               \
478                                   specenum_type##_by_name,                  \
479                                   path, ## __VA_ARGS__))
480 int secfile_lookup_plain_enum_default_full(const struct section_file
481                                            *secfile, int defval,
482                                            secfile_enum_is_valid_fn_t
483                                            is_valid_fn,
484                                            secfile_enum_by_name_fn_t
485                                            by_name_fn,
486                                            const char *path, ...)
487                                            fc__warn_unused_result
488                                            fc__attribute((__format__ (__printf__, 5, 6)));
489 int secfile_lookup_bitwise_enum_default_full(const struct section_file
490                                              *secfile, int defval,
491                                              secfile_enum_is_valid_fn_t
492                                              is_valid_fn,
493                                              secfile_enum_by_name_fn_t
494                                              by_name_fn,
495                                              const char *path, ...)
496                                              fc__warn_unused_result
497                                              fc__attribute((__format__ (__printf__, 5, 6)));
498 #define secfile_lookup_enum_default(secfile, defval, specenum_type,         \
499                                     path, ...)                              \
500 (specenum_type##_is_bitwise()                                               \
501  ? secfile_lookup_bitwise_enum_default_full(secfile, defval,                \
502                                             (secfile_enum_is_valid_fn_t)    \
503                                             specenum_type##_is_valid,       \
504                                             (secfile_enum_by_name_fn_t)     \
505                                             specenum_type##_by_name,        \
506                                             path, ## __VA_ARGS__)           \
507  : secfile_lookup_plain_enum_default_full(secfile, defval,                  \
508                                           (secfile_enum_is_valid_fn_t)      \
509                                           specenum_type##_is_valid,         \
510                                           (secfile_enum_by_name_fn_t)       \
511                                           specenum_type##_by_name,          \
512                                           path, ## __VA_ARGS__))
513 int *secfile_lookup_plain_enum_vec_full(const struct section_file *secfile,
514                                         size_t *dim,
515                                         secfile_enum_is_valid_fn_t
516                                         is_valid_fn,
517                                         secfile_enum_by_name_fn_t
518                                         by_name_fn,
519                                         const char *path, ...)
520                                         fc__warn_unused_result
521                                         fc__attribute((__format__ (__printf__, 5, 6)));
522 int *secfile_lookup_bitwise_enum_vec_full(const struct section_file *secfile,
523                                           size_t *dim,
524                                           secfile_enum_is_valid_fn_t
525                                           is_valid_fn,
526                                           secfile_enum_by_name_fn_t
527                                           by_name_fn,
528                                           const char *path, ...)
529                                           fc__warn_unused_result
530                                           fc__attribute((__format__ (__printf__, 5, 6)));
531 #define secfile_lookup_enum_vec(secfile, dim, specenum_type,                \
532                                 path, ...)                                  \
533 (specenum_type##_is_bitwise()                                               \
534  ? (enum specenum_type *)                                                   \
535    secfile_lookup_bitwise_enum_vec_full(secfile, dim,                       \
536                                         (secfile_enum_is_valid_fn_t)        \
537                                         specenum_type##_is_valid,           \
538                                         (secfile_enum_by_name_fn_t)         \
539                                         specenum_type##_by_name,            \
540                                         path, ## __VA_ARGS__)               \
541  : (enum specenum_type *)                                                   \
542    secfile_lookup_plain_enum_vec_full(secfile, dim,                         \
543                                       (secfile_enum_is_valid_fn_t)          \
544                                       specenum_type##_is_valid,             \
545                                       (secfile_enum_by_name_fn_t)           \
546                                       specenum_type##_by_name,              \
547                                       path, ## __VA_ARGS__))
548 
549 bool secfile_lookup_enum_data(const struct section_file *secfile,
550                               int *pvalue, bool bitwise,
551                               secfile_enum_name_data_fn_t name_fn,
552                               secfile_data_t data, const char *path, ...)
553                               fc__warn_unused_result
554                               fc__attribute((__format__ (__printf__, 6, 7)));
555 int secfile_lookup_enum_default_data(const struct section_file *secfile,
556                                      int defval, bool bitwise,
557                                      secfile_enum_name_data_fn_t name_fn,
558                                      secfile_data_t data,
559                                      const char *path, ...)
560                                      fc__warn_unused_result
561                                      fc__attribute((__format__ (__printf__, 6, 7)));
562 int *secfile_lookup_enum_vec_data(const struct section_file *secfile,
563                                   size_t *dim, bool bitwise,
564                                   secfile_enum_name_data_fn_t name_fn,
565                                   secfile_data_t data, const char *path, ...)
566                                   fc__warn_unused_result
567                                   fc__attribute((__format__ (__printf__, 6, 7)));
568 
569 /* Sections functions. */
570 struct section *secfile_section_by_name(const struct section_file *secfile,
571                                         const char *section_name);
572 struct section *secfile_section_lookup(const struct section_file *secfile,
573                                        const char *path, ...)
574                                        fc__attribute((__format__ (__printf__, 2, 3)));
575 const struct section_list *
576 secfile_sections(const struct section_file *secfile);
577 struct section_list *
578 secfile_sections_by_name_prefix(const struct section_file *secfile,
579                                 const char *prefix);
580 struct section *secfile_section_new(struct section_file *secfile,
581                                     const char *section_name);
582 
583 
584 /* Independant section functions. */
585 void section_destroy(struct section *psection);
586 void section_clear_all(struct section *psection);
587 
588 bool section_set_name(struct section *psection, const char *section_name);
589 
590 /* Entry functions. */
591 const struct entry_list *section_entries(const struct section *psection);
592 struct entry *section_entry_by_name(const struct section *psection,
593                                     const char *entry_name);
594 struct entry *section_entry_lookup(const struct section *psection,
595                                    const char *path, ...)
596                                    fc__attribute((__format__ (__printf__, 2, 3)));
597 struct entry *section_entry_int_new(struct section *psection,
598                                     const char *entry_name,
599                                     int value);
600 struct entry *section_entry_bool_new(struct section *psection,
601                                      const char *entry_name,
602                                      bool value);
603 struct entry *section_entry_float_new(struct section *psection,
604                                       const char *entry_name,
605                                       float value);
606 struct entry *section_entry_str_new(struct section *psection,
607                                     const char *entry_name,
608                                     const char *value, bool escaped);
609 
610 /* Independant entry functions. */
611 enum entry_type {
612   ENTRY_BOOL,
613   ENTRY_INT,
614   ENTRY_FLOAT,
615   ENTRY_STR,
616   ENTRY_FILEREFERENCE,
617   ENTRY_ILLEGAL
618 };
619 
620 void entry_destroy(struct entry *pentry);
621 
622 struct section *entry_section(const struct entry *pentry);
623 enum entry_type entry_type(const struct entry *pentry);
624 int entry_path(const struct entry *pentry, char *buf, size_t buf_len);
625 
626 const char *entry_name(const struct entry *pentry);
627 bool entry_set_name(struct entry *pentry, const char *entry_name);
628 
629 const char *entry_comment(const struct entry *pentry);
630 void entry_set_comment(struct entry *pentry, const char *comment);
631 
632 bool entry_int_get(const struct entry *pentry, int *value);
633 bool entry_int_set(struct entry *pentry, int value);
634 
635 bool entry_bool_get(const struct entry *pentry, bool *value);
636 bool entry_bool_set(struct entry *pentry, bool value);
637 
638 bool entry_float_get(const struct entry *pentry, float *value);
639 bool entry_float_set(struct entry *pentry, float value);
640 
641 bool entry_str_get(const struct entry *pentry, const char **value);
642 bool entry_str_set(struct entry *pentry, const char *value);
643 bool entry_str_escaped(const struct entry *pentry);
644 bool entry_str_set_escaped(struct entry *pentry, bool escaped);
645 bool entry_str_set_gt_marking(struct entry *pentry, bool gt_marking);
646 
647 #ifdef __cplusplus
648 }
649 #endif /* __cplusplus */
650 
651 #endif  /* FC__REGISTRY_INI_H */
652