1: #define _GNU_SOURCE
2: #include "check_confuse.h"
3: #include <string.h>
4: #include <sys/types.h>
5:
6: static cfg_t *cfg = 0;
7:
8: #define ACTION_NONE 0
9: #define ACTION_RUN 1
10: #define ACTION_WALK 2
11: #define ACTION_CRAWL 3
12: #define ACTION_JUMP 4
13:
14: static int parse_action(cfg_t *cfg, cfg_opt_t *opt, const char *value, void *result)
15: {
16: if (strcmp(value, "run") == 0)
17: *(int *)result = ACTION_RUN;
18: else if (strcmp(value, "walk") == 0)
19: *(int *)result = ACTION_WALK;
20: else if (strcmp(value, "crawl") == 0)
21: *(int *)result = ACTION_CRAWL;
22: else if (strcmp(value, "jump") == 0)
23: *(int *)result = ACTION_JUMP;
24: else {
25: /* cfg_error(cfg, "Invalid action value '%s'", value); */
26: return -1;
27: }
28: return 0;
29: }
30:
31: int validate_speed(cfg_t *cfg, cfg_opt_t *opt)
32: {
33: unsigned int i;
34:
35: for (i = 0; i < cfg_opt_size(opt); i++) {
36: if (cfg_opt_getnint(opt, i) <= 0) {
37: /* cfg_error(cfg, "speed must be positive in section %s", cfg->name); */
38: return 1;
39: }
40: }
41: return 0;
42: }
43:
44: int validate_speed2(cfg_t *cfg, cfg_opt_t *opt, void *value)
45: {
46: int *val = (int *)value;
47:
48: if (*val <= 0)
49: return 1; /* Speed must be positive */
50:
51: if (*val >= 42)
52: *val = 42; /* Allow, but adjust MAX */
53:
54: return 0;
55: }
56:
57: int validate_name2(cfg_t *cfg, cfg_opt_t *opt, void *value)
58: {
59: char *str = (char *)value;
60:
61: if (!str || !str[0])
62: return 1; /* Must be a valid string */
63:
64: if (strlen(str) > 42)
65: return 1; /* Cannot be longer than ... */
66:
67: return 0;
68: }
69:
70: int validate_ip(cfg_t *cfg, cfg_opt_t *opt)
71: {
72: unsigned int i, j;
73:
74: for (i = 0; i < cfg_opt_size(opt); i++) {
75: unsigned int v[4];
76: char *ip = cfg_opt_getnstr(opt, i);
77:
78: if (sscanf(ip, "%u.%u.%u.%u", v + 0, v + 1, v + 2, v + 3) != 4) {
79: /* cfg_error(cfg, "invalid IP address %s in section %s", ip, cfg->name); */
80: return 1;
81: }
82: for (j = 0; j < 4; j++) {
83: if (v[j] > 0xff) {
84: return 1;
85: }
86: }
87: }
88: return 0;
89: }
90:
91: int validate_action(cfg_t *cfg, cfg_opt_t *opt)
92: {
93: cfg_opt_t *name_opt;
94: cfg_t *action_sec = cfg_opt_getnsec(opt, 0);
95:
96: fail_unless(action_sec != 0);
97:
98: name_opt = cfg_getopt(action_sec, "name");
99:
100: fail_unless(name_opt != 0);
101: fail_unless(cfg_opt_size(name_opt) == 1);
102:
103: if (cfg_opt_getnstr(name_opt, 0) == NULL) {
104: /* cfg_error(cfg, "missing required option 'name' in section %s", opt->name); */
105: return 1;
106: }
107: return 0;
108: }
109:
110: void validate_setup(void)
111: {
112: cfg_opt_t *opt = 0;
113:
114: static cfg_opt_t action_opts[] = {
115: CFG_INT("speed", 0, CFGF_NONE),
116: CFG_STR("name", 0, CFGF_NONE),
117: CFG_INT("xspeed", 0, CFGF_NONE),
118: CFG_END()
119: };
120:
121: static cfg_opt_t multi_opts[] = {
122: CFG_INT_LIST("speeds", 0, CFGF_NONE),
123: CFG_SEC("options", action_opts, CFGF_NONE),
124: CFG_END()
125: };
126:
127: cfg_opt_t opts[] = {
128: CFG_STR_LIST("ip-address", 0, CFGF_NONE),
129: CFG_INT_CB("action", ACTION_NONE, CFGF_NONE, parse_action),
130: CFG_SEC("options", action_opts, CFGF_NONE),
131: CFG_SEC("multi_options", multi_opts, CFGF_MULTI),
132: CFG_END()
133: };
134:
135: cfg = cfg_init(opts, 0);
136:
137: cfg_set_validate_func(cfg, "ip-address", validate_ip);
138: fail_unless(cfg_set_validate_func(cfg, "ip-address", validate_ip) == validate_ip);
139: opt = cfg_getopt(cfg, "ip-address");
140: fail_unless(opt != 0);
141: fail_unless(opt->validcb == validate_ip);
142:
143: cfg_set_validate_func(cfg, "options", validate_action);
144: fail_unless(cfg_set_validate_func(cfg, "options", validate_action) == validate_action);
145: opt = cfg_getopt(cfg, "options");
146: fail_unless(opt != 0);
147: fail_unless(opt->validcb == validate_action);
148:
149: cfg_set_validate_func(cfg, "options|speed", validate_speed);
150: fail_unless(cfg_set_validate_func(cfg, "options|speed", validate_speed) == validate_speed);
151: opt = cfg_getopt(cfg, "options|speed");
152: fail_unless(opt != 0);
153: fail_unless(opt->validcb == validate_speed);
154:
155: cfg_set_validate_func(cfg, "multi_options|speeds", validate_speed);
156: fail_unless(cfg_set_validate_func(cfg, "multi_options|speeds", validate_speed) == validate_speed);
157:
158: cfg_set_validate_func(cfg, "multi_options|options|xspeed", validate_speed);
159: fail_unless(cfg_set_validate_func(cfg, "multi_options|options|xspeed", validate_speed) == validate_speed);
160:
161: /* Validate callbacks for *set*() functions, i.e. not when parsing file content */
162: cfg_set_validate_func2(cfg, "multi_options|speed", validate_speed2);
163: cfg_set_validate_func2(cfg, "multi_options|options|name", validate_name2);
164: }
165:
166: void validate_teardown(void)
167: {
168: cfg_free(cfg);
169: }
170:
171: void validate_test(void)
172: {
173: char *buf;
174: unsigned int i;
175:
176: buf = "action = wlak";
177: fail_unless(cfg_parse_buf(cfg, buf) == CFG_PARSE_ERROR);
178:
179: buf = "action = walk";
180: fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS);
181:
182: buf = "action = run" " options { speed = 6 }";
183: fail_unless(cfg_parse_buf(cfg, buf) == CFG_PARSE_ERROR);
184:
185: buf = "action = jump" " options { speed = 2 name = 'Joe' }";
186: fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS);
187:
188: buf = "action = crawl" " options { speed = -2 name = 'Smith' }";
189: fail_unless(cfg_parse_buf(cfg, buf) == CFG_PARSE_ERROR);
190:
191: buf = "ip-address = { 0.0.0.0 , 1.2.3.4 , 192.168.0.254 , 10.0.0.255 , 20.30.40.256}";
192: fail_unless(cfg_parse_buf(cfg, buf) == CFG_PARSE_ERROR);
193: buf = "ip-address = { 0.0.0.0 , 1.2.3.4 , 192.168.0.254 , 10.0.0.255 , 20.30.40.250}";
194: fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS);
195: buf = "ip-address = { 1.2.3. }";
196: fail_unless(cfg_parse_buf(cfg, buf) == CFG_PARSE_ERROR);
197:
198: buf = "action = run" " multi_options { speeds = {1, 2, 3, 4, 5} }";
199: fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS);
200: for (i = 0; i < cfg_size(cfg, "multi_options"); i++) {
201: cfg_t *multisec = cfg_getnsec(cfg, "multi_options", i);
202: cfg_opt_t *speeds_opt = cfg_getopt(multisec, "speeds");
203:
204: fail_unless(speeds_opt != 0);
205: fail_unless(speeds_opt->validcb == validate_speed);
206: }
207:
208: buf = "action = run" " multi_options { speeds = {1, 2, 3, -4, 5} }";
209: fail_unless(cfg_parse_buf(cfg, buf) == CFG_PARSE_ERROR);
210:
211: buf = "action = run" " multi_options { speeds = {1, 2, 3, 4, 0} }";
212: fail_unless(cfg_parse_buf(cfg, buf) == CFG_PARSE_ERROR);
213:
214: buf = "action = run" " multi_options { options { xspeed = 3 } }";
215: fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS);
216:
217: buf = "action = run" " multi_options { options { xspeed = -3 } }";
218: fail_unless(cfg_parse_buf(cfg, buf) == CFG_PARSE_ERROR);
219: }
220:
221: int main(void)
222: {
223: validate_setup();
224: validate_test();
225: validate_teardown();
226:
227: return 0;
228: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>