2 Configuration file handling on top of tini
4 Copyright (C) Amitay Isaacs 2017
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, see <http://www.gnu.org/licenses/>.
24 #include "conf/conf.c"
26 static void test1(void)
28 TALLOC_CTX
*mem_ctx
= talloc_new(NULL
);
29 struct conf_context
*conf
;
33 ret
= conf_init(mem_ctx
, &conf
);
37 conf_define_section(conf
, "section1", NULL
);
38 status
= conf_valid(conf
);
39 assert(status
== true);
41 conf_define_section(conf
, NULL
, NULL
);
42 status
= conf_valid(conf
);
43 assert(status
== false);
48 static void test2(void)
50 TALLOC_CTX
*mem_ctx
= talloc_new(NULL
);
51 struct conf_context
*conf
;
55 ret
= conf_init(mem_ctx
, &conf
);
59 conf_define_string(conf
, "section1", "key1", "default", NULL
);
60 status
= conf_valid(conf
);
61 assert(status
== false);
66 static void test3(void)
68 TALLOC_CTX
*mem_ctx
= talloc_new(NULL
);
69 struct conf_context
*conf
;
73 ret
= conf_init(mem_ctx
, &conf
);
77 conf_define_section(conf
, "section1", NULL
);
78 status
= conf_valid(conf
);
79 assert(status
== true);
81 conf_define_string(conf
, "section1", "key1", NULL
, NULL
);
82 status
= conf_valid(conf
);
83 assert(status
== true);
85 conf_define_string(conf
, "section1", "key1", "value1", NULL
);
86 status
= conf_valid(conf
);
87 assert(status
== false);
92 static void test4(void)
94 TALLOC_CTX
*mem_ctx
= talloc_new(NULL
);
95 struct conf_context
*conf
;
99 ret
= conf_init(mem_ctx
, &conf
);
101 assert(conf
!= NULL
);
103 conf_define_section(conf
, "section1", NULL
);
104 status
= conf_valid(conf
);
105 assert(status
== true);
107 conf_define_string(conf
, "section1", "key1", NULL
, NULL
);
108 status
= conf_valid(conf
);
109 assert(status
== true);
111 conf_define_integer(conf
, "section1", "key1", 10, NULL
);
112 status
= conf_valid(conf
);
113 assert(status
== false);
115 talloc_free(mem_ctx
);
118 static void test5(void)
120 TALLOC_CTX
*mem_ctx
= talloc_new(NULL
);
121 struct conf_context
*conf
;
129 ret
= conf_init(mem_ctx
, &conf
);
131 assert(conf
!= NULL
);
133 conf_define_section(conf
, "section1", NULL
);
134 status
= conf_valid(conf
);
135 assert(status
== true);
137 conf_define_string(conf
, "section1", "key1", "value1", NULL
);
138 conf_define_integer(conf
, "section1", "key2", 10, NULL
);
139 conf_define_boolean(conf
, "section1", "key3", true, NULL
);
141 conf_assign_string_pointer(conf
, "section1", "key1", &s_val
);
142 conf_assign_integer_pointer(conf
, "section1", "key2", &i_val
);
143 conf_assign_boolean_pointer(conf
, "section1", "key3", &b_val
);
145 status
= conf_valid(conf
);
146 assert(status
== true);
148 status
= conf_query(conf
, "section1", "key1", &type
);
149 assert(status
== true);
150 assert(type
== CONF_STRING
);
152 status
= conf_query(conf
, "section1", "key2", &type
);
153 assert(status
== true);
154 assert(type
== CONF_INTEGER
);
156 status
= conf_query(conf
, "section1", "key3", &type
);
157 assert(status
== true);
158 assert(type
== CONF_BOOLEAN
);
160 assert(strcmp(s_val
, "value1") == 0);
162 assert(b_val
== true);
164 conf_set_defaults(conf
);
166 assert(strcmp(s_val
, "value1") == 0);
168 assert(b_val
== true);
170 talloc_free(mem_ctx
);
173 static void test6(void)
175 TALLOC_CTX
*mem_ctx
= talloc_new(NULL
);
176 struct conf_context
*conf
;
179 const char *s_val
, *s2_val
;
181 bool b_val
, b2_val
, is_default
;
183 ret
= conf_init(mem_ctx
, &conf
);
185 assert(conf
!= NULL
);
187 conf_define_section(conf
, "section1", NULL
);
188 status
= conf_valid(conf
);
189 assert(status
== true);
191 conf_define_string(conf
, "section1", "key1", "default", NULL
);
192 conf_define_integer(conf
, "section1", "key2", 10, NULL
);
193 conf_define_boolean(conf
, "section1", "key3", true, NULL
);
195 conf_assign_string_pointer(conf
, "section1", "key1", &s_val
);
196 conf_assign_integer_pointer(conf
, "section1", "key2", &i_val
);
197 conf_assign_boolean_pointer(conf
, "section1", "key3", &b_val
);
199 status
= conf_valid(conf
);
200 assert(status
== true);
203 ret
= conf_get_string(conf
, "section1", "key1", &s2_val
, &is_default
);
205 assert(strcmp(s2_val
, "default") == 0);
206 assert(is_default
== true);
209 ret
= conf_get_integer(conf
, "section1", "key2", &i2_val
, &is_default
);
211 assert(i2_val
== 10);
212 assert(is_default
== true);
215 ret
= conf_get_boolean(conf
, "section1", "key3", &b2_val
, &is_default
);
217 assert(b2_val
== true);
218 assert(is_default
== true);
220 ret
= conf_set_string(conf
, "section1", "key1", "foobar");
223 ret
= conf_set_integer(conf
, "section1", "key2", 20);
226 ret
= conf_set_boolean(conf
, "section1", "key3", false);
229 assert(strcmp(s_val
, "foobar") == 0);
231 assert(b_val
== false);
234 ret
= conf_get_string(conf
, "section1", "key1", &s2_val
, &is_default
);
236 assert(strcmp(s2_val
, "foobar") == 0);
237 assert(is_default
== false);
240 ret
= conf_get_integer(conf
, "section1", "key2", &i2_val
, &is_default
);
242 assert(i2_val
== 20);
243 assert(is_default
== false);
246 ret
= conf_get_boolean(conf
, "section1", "key3", &b2_val
, &is_default
);
248 assert(b2_val
== false);
249 assert(is_default
== false);
251 conf_dump(conf
, stdout
);
253 conf_set_defaults(conf
);
255 assert(strcmp(s_val
, "default") == 0);
257 assert(b_val
== true);
259 talloc_free(mem_ctx
);
262 static bool test7_validate_string(const char *key
,
263 const char *old_value
, const char *new_value
,
264 enum conf_update_mode mode
)
269 static bool test7_validate_integer(const char *key
,
270 int old_value
, int new_value
,
271 enum conf_update_mode mode
)
276 static bool test7_validate_boolean(const char *key
,
277 bool old_value
, bool new_value
,
278 enum conf_update_mode mode
)
283 static void test7(void)
285 TALLOC_CTX
*mem_ctx
= talloc_new(NULL
);
286 struct conf_context
*conf
;
289 const char *s_val
, *s2_val
;
293 ret
= conf_init(mem_ctx
, &conf
);
295 assert(conf
!= NULL
);
297 conf_define_section(conf
, "section1", NULL
);
298 status
= conf_valid(conf
);
299 assert(status
== true);
301 conf_define_string(conf
, "section1", "key1", "default",
302 test7_validate_string
);
303 conf_define_integer(conf
, "section1", "key2", 10,
304 test7_validate_integer
);
305 conf_define_boolean(conf
, "section1", "key3", true,
306 test7_validate_boolean
);
308 conf_assign_string_pointer(conf
, "section1", "key1", &s_val
);
309 conf_assign_integer_pointer(conf
, "section1", "key2", &i_val
);
310 conf_assign_boolean_pointer(conf
, "section1", "key3", &b_val
);
312 status
= conf_valid(conf
);
313 assert(status
== true);
315 ret
= conf_set_string(conf
, "section1", "key1", "default");
318 ret
= conf_set_string(conf
, "section1", "key1", "foobar");
319 assert(ret
== EINVAL
);
321 ret
= conf_set_integer(conf
, "section1", "key2", 10);
324 ret
= conf_set_integer(conf
, "section1", "key2", 20);
325 assert(ret
== EINVAL
);
327 ret
= conf_set_boolean(conf
, "section1", "key3", true);
330 ret
= conf_set_boolean(conf
, "section1", "key3", false);
331 assert(ret
== EINVAL
);
333 assert(strcmp(s_val
, "default") == 0);
335 assert(b_val
== true);
337 ret
= conf_get_string(conf
, "section1", "key2", &s2_val
, NULL
);
338 assert(ret
== EINVAL
);
340 ret
= conf_get_integer(conf
, "section1", "key3", &i2_val
, NULL
);
341 assert(ret
== EINVAL
);
343 ret
= conf_get_boolean(conf
, "section1", "key1", &b2_val
, NULL
);
344 assert(ret
== EINVAL
);
346 talloc_free(mem_ctx
);
349 static bool test8_validate(struct conf_context
*conf
,
351 enum conf_update_mode mode
)
356 static void test8(const char *filename
)
358 TALLOC_CTX
*mem_ctx
= talloc_new(NULL
);
359 struct conf_context
*conf
;
363 ret
= conf_init(mem_ctx
, &conf
);
365 assert(conf
!= NULL
);
367 conf_define_section(conf
, "section1", test8_validate
);
368 status
= conf_valid(conf
);
369 assert(status
== true);
371 conf_define_string(conf
, "section1", "key1", "default", NULL
);
373 status
= conf_valid(conf
);
374 assert(status
== true);
376 ret
= conf_load(conf
, filename
, true);
377 conf_dump(conf
, stdout
);
379 talloc_free(mem_ctx
);
383 static void test9(const char *filename
, bool ignore_unknown
)
385 TALLOC_CTX
*mem_ctx
= talloc_new(NULL
);
386 struct conf_context
*conf
;
390 ret
= conf_init(mem_ctx
, &conf
);
392 assert(conf
!= NULL
);
394 conf_define_section(conf
, "section1", NULL
);
396 conf_define_string(conf
, "section1", "key1", "value1", NULL
);
397 conf_define_integer(conf
, "section1", "key2", 10, NULL
);
398 conf_define_boolean(conf
, "section1", "key3", true, NULL
);
400 status
= conf_valid(conf
);
401 assert(status
== true);
403 conf_set_boolean(conf
, "section1", "key3", false);
405 ret
= conf_load(conf
, filename
, ignore_unknown
);
406 conf_dump(conf
, stdout
);
408 talloc_free(mem_ctx
);
412 static void test11(const char *filename
)
414 TALLOC_CTX
*mem_ctx
= talloc_new(NULL
);
415 char reload
[PATH_MAX
];
416 struct conf_context
*conf
;
420 ret
= snprintf(reload
, sizeof(reload
), "%s.reload", filename
);
421 assert((size_t)ret
< sizeof(reload
));
423 ret
= conf_init(mem_ctx
, &conf
);
425 assert(conf
!= NULL
);
427 conf_define_section(conf
, "section1", NULL
);
429 conf_define_string(conf
, "section1", "key1", "value1", NULL
);
430 conf_define_integer(conf
, "section1", "key2", 10, NULL
);
431 conf_define_boolean(conf
, "section1", "key3", true, NULL
);
433 status
= conf_valid(conf
);
434 assert(status
== true);
436 ret
= conf_load(conf
, filename
, false);
439 ret
= rename(reload
, filename
);
442 ret
= conf_reload(conf
);
445 conf_dump(conf
, stdout
);
447 talloc_free(mem_ctx
);
451 int main(int argc
, const char **argv
)
456 fprintf(stderr
, "Usage: %s <testnum> [<config>]\n", argv
[0]);
461 if (num
> 7 && argc
!= 3) {
462 fprintf(stderr
, "Usage: %s <testnum> [<config>]\n", argv
[0]);
500 test9(argv
[2], true);
504 test9(argv
[2], false);