1: #include "check_confuse.h"
2: #include <string.h>
3:
4: static cfg_t *cfg;
5: static int numopts = 0;
6:
7: static void list_setup(void)
8: {
9: static cfg_opt_t subsec_opts[] = {
10: CFG_STR_LIST("subsubstring", 0, CFGF_NONE),
11: CFG_INT_LIST("subsubinteger", 0, CFGF_NONE),
12: CFG_FLOAT_LIST("subsubfloat", 0, CFGF_NONE),
13: CFG_BOOL_LIST("subsubbool", 0, CFGF_NONE),
14: CFG_END()
15: };
16:
17: static cfg_opt_t sec_opts[] = {
18: CFG_STR_LIST("substring", "{subdefault1, subdefault2}", CFGF_NONE),
19: CFG_INT_LIST("subinteger", "{17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 300}", CFGF_NONE), /* 14 values */
20: CFG_FLOAT_LIST("subfloat", "{8.37}", CFGF_NONE),
21: CFG_BOOL_LIST("subbool", "{true}", CFGF_NONE),
22: CFG_SEC("subsection", subsec_opts, CFGF_MULTI | CFGF_TITLE),
23: CFG_END()
24: };
25:
26: cfg_opt_t opts[] = {
27: CFG_STR_LIST("string", "{default1, default2, default3}", CFGF_NONE),
28: CFG_INT_LIST("integer", "{4711, 123456789}", CFGF_NONE),
29: CFG_FLOAT_LIST("float", "{0.42}", CFGF_NONE),
30: CFG_BOOL_LIST("bool", "{false, true, no, yes, off, on}", CFGF_NONE),
31: CFG_SEC("section", sec_opts, CFGF_MULTI),
32: CFG_END()
33: };
34:
35: cfg = cfg_init(opts, 0);
36: numopts = cfg_numopts(opts);
37: fail_unless(numopts == 5);
38:
39: memset(opts, 0, sizeof(opts));
40: memset(sec_opts, 0, sizeof(sec_opts));
41: memset(subsec_opts, 0, sizeof(subsec_opts));
42: }
43:
44: static void list_teardown(void)
45: {
46: cfg_free(cfg);
47: }
48:
49: static void list_string_test(void)
50: {
51: char *buf;
52: char *multi[2];
53:
54: fail_unless(cfg_size(cfg, "string") == 3);
55: fail_unless(cfg_opt_size(cfg_getopt(cfg, "string")) == 3);
56: fail_unless(strcmp(cfg_getnstr(cfg, "string", 0), "default1") == 0);
57: fail_unless(strcmp(cfg_getnstr(cfg, "string", 1), "default2") == 0);
58: fail_unless(strcmp(cfg_getnstr(cfg, "string", 2), "default3") == 0);
59: buf = "string = {\"manually\", 'set'}";
60: fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS);
61: fail_unless(cfg_size(cfg, "string") == 2);
62: fail_unless(strcmp(cfg_getstr(cfg, "string"), "manually") == 0);
63: fail_unless(strcmp(cfg_getnstr(cfg, "string", 1), "set") == 0);
64: cfg_setstr(cfg, "string", "manually set");
65: fail_unless(strcmp(cfg_getstr(cfg, "string"), "manually set") == 0);
66: cfg_setnstr(cfg, "string", "foobar", 1);
67: fail_unless(strcmp(cfg_getnstr(cfg, "string", 1), "foobar") == 0);
68:
69: cfg_addlist(cfg, "string", 3, "foo", "bar", "baz");
70: fail_unless(cfg_size(cfg, "string") == 5);
71: fail_unless(strcmp(cfg_getnstr(cfg, "string", 3), "bar") == 0);
72:
73: cfg_setlist(cfg, "string", 3, "baz", "foo", "bar");
74: fail_unless(cfg_size(cfg, "string") == 3);
75: fail_unless(strcmp(cfg_getnstr(cfg, "string", 0), "baz") == 0);
76:
77: buf = "string += {gaz, 'onk'}";
78: fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS);
79: fail_unless(cfg_size(cfg, "string") == 5);
80: fail_unless(strcmp(cfg_getnstr(cfg, "string", 3), "gaz") == 0);
81: fail_unless(strcmp(cfg_getnstr(cfg, "string", 4), "onk") == 0);
82:
83: multi[0] = "bar";
84: multi[1] = "foo";
85: fail_unless(cfg_setmulti(cfg, "string", 2, multi) == 0);
86: fail_unless(cfg_size(cfg, "string") == 2);
87: fail_unless(strcmp(cfg_getnstr(cfg, "string", 0), "bar") == 0);
88: fail_unless(strcmp(cfg_getnstr(cfg, "string", 1), "foo") == 0);
89: }
90:
91: static void list_integer_test(void)
92: {
93: char *buf;
94: char *multi[3];
95:
96: fail_unless(cfg_size(cfg, "integer") == 2);
97: fail_unless(cfg_opt_size(cfg_getopt(cfg, "integer")) == 2);
98:
99: fail_unless(cfg_getint(cfg, "integer") == 4711);
100: fail_unless(cfg_getnint(cfg, "integer", 1) == 123456789);
101: buf = "integer = {-46}";
102: fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS);
103: fail_unless(cfg_size(cfg, "integer") == 1);
104: fail_unless(cfg_getnint(cfg, "integer", 0) == -46);
105: cfg_setnint(cfg, "integer", 999999, 1);
106: fail_unless(cfg_size(cfg, "integer") == 2);
107: fail_unless(cfg_getnint(cfg, "integer", 1) == 999999);
108:
109: cfg_addlist(cfg, "integer", 3, 11, 22, 33);
110: fail_unless(cfg_size(cfg, "integer") == 5);
111: fail_unless(cfg_getnint(cfg, "integer", 3) == 22);
112:
113: cfg_setlist(cfg, "integer", 3, 11, 22, 33);
114: fail_unless(cfg_size(cfg, "integer") == 3);
115: fail_unless(cfg_getnint(cfg, "integer", 0) == 11);
116:
117: buf = "integer += {-1234567890, 1234567890}";
118: fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS);
119: fail_unless(cfg_size(cfg, "integer") == 5);
120: fail_unless(cfg_getnint(cfg, "integer", 3) == -1234567890);
121: fail_unless(cfg_getnint(cfg, "integer", 4) == 1234567890);
122:
123: multi[0] = "42";
124: multi[1] = "17";
125: fail_unless(cfg_setmulti(cfg, "integer", 2, multi) == 0);
126: fail_unless(cfg_size(cfg, "integer") == 2);
127: fail_unless(cfg_getnint(cfg, "integer", 0) == 42);
128: fail_unless(cfg_getnint(cfg, "integer", 1) == 17);
129:
130: multi[0] = "17";
131: multi[1] = "bad";
132: multi[2] = "42";
133: fail_unless(cfg_setmulti(cfg, "integer", 3, multi) == -1);
134: fail_unless(cfg_size(cfg, "integer") == 2);
135: fail_unless(cfg_getnint(cfg, "integer", 0) == 42);
136: fail_unless(cfg_getnint(cfg, "integer", 1) == 17);
137: }
138:
139: static void list_float_test(void)
140: {
141: char *buf;
142: char *multi[3];
143:
144: fail_unless(cfg_size(cfg, "float") == 1);
145: fail_unless(cfg_opt_size(cfg_getopt(cfg, "float")) == 1);
146:
147: fail_unless(cfg_getfloat(cfg, "float") == 0.42);
148: fail_unless(cfg_getnfloat(cfg, "float", 0) == 0.42);
149:
150: buf = "float = {-46.777, 0.1, 0.2, 0.17, 17.123}";
151: fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS);
152: fail_unless(cfg_opt_size(cfg_getopt(cfg, "float")) == 5);
153: fail_unless(cfg_getnfloat(cfg, "float", 0) == -46.777);
154: fail_unless(cfg_getnfloat(cfg, "float", 1) == 0.1);
155: fail_unless(cfg_getnfloat(cfg, "float", 2) == 0.2);
156: fail_unless(cfg_getnfloat(cfg, "float", 3) == 0.17);
157: fail_unless(cfg_getnfloat(cfg, "float", 4) == 17.123);
158:
159: cfg_setnfloat(cfg, "float", 5.1234e2, 1);
160: fail_unless(cfg_getnfloat(cfg, "float", 1) == 5.1234e2);
161:
162: cfg_addlist(cfg, "float", 1, 11.2233);
163: fail_unless(cfg_size(cfg, "float") == 6);
164: fail_unless(cfg_getnfloat(cfg, "float", 5) == 11.2233);
165:
166: cfg_setlist(cfg, "float", 2, .3, -18.17e-7);
167: fail_unless(cfg_size(cfg, "float") == 2);
168: fail_unless(cfg_getnfloat(cfg, "float", 0) == 0.3);
169: fail_unless(cfg_getnfloat(cfg, "float", 1) == -18.17e-7);
170:
171: buf = "float += {64.64, 1234.567890}";
172: fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS);
173: fail_unless(cfg_size(cfg, "float") == 4);
174: fail_unless(cfg_getnfloat(cfg, "float", 2) == 64.64);
175: fail_unless(cfg_getnfloat(cfg, "float", 3) == 1234.567890);
176:
177: multi[0] = "42";
178: multi[1] = "0.17";
179: fail_unless(cfg_setmulti(cfg, "float", 2, multi) == 0);
180: fail_unless(cfg_size(cfg, "float") == 2);
181: fail_unless(cfg_getnfloat(cfg, "float", 0) == 42);
182: fail_unless(cfg_getnfloat(cfg, "float", 1) == 0.17);
183:
184: multi[0] = "42";
185: multi[1] = "bad";
186: multi[2] = "0.17";
187: fail_unless(cfg_setmulti(cfg, "float", 3, multi) == -1);
188: fail_unless(cfg_size(cfg, "float") == 2);
189: fail_unless(cfg_getnfloat(cfg, "float", 0) == 42);
190: fail_unless(cfg_getnfloat(cfg, "float", 1) == 0.17);
191: }
192:
193: static void list_bool_test(void)
194: {
195: char *buf;
196: char *multi[3];
197:
198: fail_unless(cfg_size(cfg, "bool") == 6);
199: fail_unless(cfg_opt_size(cfg_getopt(cfg, "bool")) == 6);
200: fail_unless(cfg_getnbool(cfg, "bool", 0) == cfg_false);
201: fail_unless(cfg_getnbool(cfg, "bool", 1) == cfg_true);
202: fail_unless(cfg_getnbool(cfg, "bool", 2) == cfg_false);
203: fail_unless(cfg_getnbool(cfg, "bool", 3) == cfg_true);
204: fail_unless(cfg_getnbool(cfg, "bool", 4) == cfg_false);
205: fail_unless(cfg_getnbool(cfg, "bool", 5) == cfg_true);
206:
207: buf = "bool = {yes, yes, no, false, true}";
208: fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS);
209: fail_unless(cfg_size(cfg, "bool") == 5);
210: fail_unless(cfg_getbool(cfg, "bool") == cfg_true);
211: fail_unless(cfg_getnbool(cfg, "bool", 1) == cfg_true);
212: fail_unless(cfg_getnbool(cfg, "bool", 2) == cfg_false);
213: fail_unless(cfg_getnbool(cfg, "bool", 3) == cfg_false);
214: fail_unless(cfg_getnbool(cfg, "bool", 4) == cfg_true);
215:
216: cfg_setbool(cfg, "bool", cfg_false);
217: fail_unless(cfg_getbool(cfg, "bool") == cfg_false);
218: cfg_setnbool(cfg, "bool", cfg_false, 1);
219: fail_unless(cfg_getnbool(cfg, "bool", 1) == cfg_false);
220:
221: cfg_addlist(cfg, "bool", 2, cfg_true, cfg_false);
222: fail_unless(cfg_opt_size(cfg_getopt(cfg, "bool")) == 7);
223: fail_unless(cfg_getnbool(cfg, "bool", 5) == cfg_true);
224:
225: cfg_setlist(cfg, "bool", 4, cfg_true, cfg_true, cfg_false, cfg_true);
226: fail_unless(cfg_size(cfg, "bool") == 4);
227: fail_unless(cfg_getnbool(cfg, "bool", 0) == cfg_true);
228: fail_unless(cfg_getnbool(cfg, "bool", 1) == cfg_true);
229: fail_unless(cfg_getnbool(cfg, "bool", 2) == cfg_false);
230: fail_unless(cfg_getnbool(cfg, "bool", 3) == cfg_true);
231:
232: buf = "bool += {false, false}";
233: fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS);
234: fail_unless(cfg_size(cfg, "bool") == 6);
235: fail_unless(cfg_getnbool(cfg, "bool", 4) == cfg_false);
236: fail_unless(cfg_getnbool(cfg, "bool", 5) == cfg_false);
237:
238: multi[0] = "true";
239: multi[1] = "no";
240: fail_unless(cfg_setmulti(cfg, "bool", 2, multi) == 0);
241: fail_unless(cfg_size(cfg, "bool") == 2);
242: fail_unless(cfg_getnbool(cfg, "bool", 0) == cfg_true);
243: fail_unless(cfg_getnbool(cfg, "bool", 1) == cfg_false);
244:
245: multi[0] = "false";
246: multi[1] = "maybe";
247: multi[2] = "yes";
248: fail_unless(cfg_setmulti(cfg, "bool", 3, multi) == -1);
249: fail_unless(cfg_size(cfg, "bool") == 2);
250: fail_unless(cfg_getnbool(cfg, "bool", 0) == cfg_true);
251: fail_unless(cfg_getnbool(cfg, "bool", 1) == cfg_false);
252: }
253:
254: static void list_section_test(void)
255: {
256: char *buf;
257: cfg_t *sec, *subsec;
258: cfg_opt_t *opt;
259:
260: /* size should be 0 before any section has been parsed. Since the
261: * CFGF_MULTI flag is set, there are no default sections.
262: */
263: fail_unless(cfg_size(cfg, "section") == 0);
264: fail_unless(cfg_opt_size(cfg_getopt(cfg, "section")) == 0);
265: fail_unless(cfg_size(cfg, "section|subsection") == 0);
266: fail_unless(cfg_opt_size(cfg_getopt(cfg, "section|subsection")) == 0);
267:
268: buf = "section {}"; /* add a section with default values */
269: fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS);
270: fail_unless(cfg_size(cfg, "section") == 1);
271:
272: sec = cfg_getsec(cfg, "section");
273: fail_unless(sec != 0);
274: fail_unless(strcmp(sec->name, "section") == 0);
275: fail_unless(cfg_title(sec) == NULL);
276:
277: opt = cfg_getopt(sec, "subsection");
278: fail_unless(opt != 0);
279: fail_unless(cfg_opt_size(opt) == 0);
280: fail_unless(cfg_size(sec, "subsection") == 0);
281:
282: fail_unless(strcmp(cfg_getnstr(sec, "substring", 0), "subdefault1") == 0);
283: subsec = cfg_getsec(cfg, "section|subsection");
284: fail_unless(subsec == 0);
285:
286: buf = "section { subsection 'foo' { subsubfloat = {1.2, 3.4, 5.6} } }";
287: fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS);
288: fail_unless(cfg_size(cfg, "section") == 2);
289:
290: sec = cfg_getnsec(cfg, "section", 1);
291: fail_unless(sec != 0);
292: fail_unless(strcmp(cfg_title(cfg_getnsec(sec, "subsection", 0)), "foo") == 0);
293: fail_unless(cfg_size(sec, "subinteger") == 14);
294:
295: subsec = cfg_getsec(sec, "subsection");
296: fail_unless(cfg_size(subsec, "subsubfloat") == 3);
297: fail_unless(cfg_getnfloat(subsec, "subsubfloat", 2) == 5.6);
298: fail_unless(cfg_getnstr(subsec, "subsubstring", 0) == 0);
299:
300: sec = cfg_getnsec(cfg, "section", 0);
301: fail_unless(sec != 0);
302: fail_unless(cfg_size(sec, "subsection") == 0);
303: buf = "subsection 'bar' {}";
304: fail_unless(cfg_parse_buf(sec, buf) == CFG_SUCCESS);
305: fail_unless(cfg_size(sec, "subsection") == 1);
306: subsec = cfg_getnsec(sec, "subsection", 0);
307: fail_unless(subsec != 0);
308: fail_unless(strcmp(cfg_title(subsec), "bar") == 0);
309: fail_unless(cfg_getnfloat(subsec, "subsubfloat", 2) == 0);
310:
311: buf = "subsection 'baz' {}";
312: fail_unless(cfg_parse_buf(sec, buf) == CFG_SUCCESS);
313: fail_unless(cfg_gettsec(sec, "subsection", "bar") == subsec);
314: opt = cfg_getopt(sec, "subsection");
315: fail_unless(opt != 0);
316: fail_unless(cfg_gettsec(sec, "subsection", "baz") == cfg_opt_gettsec(opt, "baz"));
317: fail_unless(cfg_opt_gettsec(opt, "bar") == subsec);
318: fail_unless(cfg_opt_gettsec(opt, "foo") == 0);
319: fail_unless(cfg_gettsec(sec, "subsection", "section") == 0);
320:
321: fail_unless(cfg_gettsec(cfg, "section", "baz") == 0);
322: }
323:
324: static void parse_buf_test(void)
325: {
326: char *buf;
327:
328: fail_unless(cfg_parse_buf(cfg, 0) == CFG_SUCCESS);
329: fail_unless(cfg_parse_buf(cfg, "") == CFG_SUCCESS);
330:
331: buf = "bool = {true, true, false, wrong}";
332: fail_unless(cfg_parse_buf(cfg, buf) == CFG_PARSE_ERROR);
333: buf = "string = {foo, bar";
334: fail_unless(cfg_parse_buf(cfg, buf) == CFG_PARSE_ERROR);
335:
336: buf = "/* this is a comment */ bool = {true} /*// another comment */";
337: fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS);
338:
339: buf = "/*/*/ bool = {true}// */";
340: fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS);
341:
342: buf = "/////// this too is a comment\nbool = {true} // another one here /* comment */";
343: fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS);
344:
345: buf = "# this is a shell comment\nbool = {true} # another shell comment here //* comment *//";
346: fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS);
347:
348: buf = "######## this is also a shell comment\nbool = {true} ## Use the force, Luke";
349: fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS);
350:
351: /* Issue #98: Line of only hashes cause segfault */
352: buf = "##############################################\n# some text #\n##############################################\nbool = {false}";
353: fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS);
354: buf = "////////////////////////////////////////////////////////////////////////////////////////////\n// some text //\n////////////////////////////////////////////////////////////////////////////////////////////\nbool = {false}";
355: fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS);
356: buf = "/******************************************************************************************/\n// some text //\n/******************************************************************************************/\nbool = {false}";
357: fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS);
358:
359: buf = "string={/usr/local/}";
360: fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS);
361: fail_unless(strcmp(cfg_getnstr(cfg, "string", 0), "/usr/local/") == 0);
362: }
363:
364: static void nonexistent_option_test(void)
365: {
366: char *buf;
367:
368: fail_unless(cfg_numopts(cfg->opts) == numopts);
369: fail_unless(cfg_getopt(cfg, "nonexistent") == 0);
370:
371: buf = "section {}";
372: fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS);
373: fail_unless(cfg_getopt(cfg, "section|subnonexistent") == 0);
374: }
375:
376: int main(void)
377: {
378: list_setup();
379:
380: list_string_test();
381: list_integer_test();
382: list_float_test();
383: list_bool_test();
384: list_section_test();
385: parse_buf_test();
386: nonexistent_option_test();
387:
388: list_teardown();
389:
390: return 0;
391: }
392:
393: /**
394: * Local Variables:
395: * indent-tabs-mode: t
396: * c-file-style: "linux"
397: * End:
398: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>