1 #include <ccan/tap/tap.h>
4 /* Make sure we override these! */
5 static void *no_malloc(size_t size)
9 static void *no_realloc(void *p, size_t size)
13 static void no_free(void *p)
17 #define malloc no_malloc
18 #define realloc no_realloc
21 #include <ccan/opt/opt.c>
22 #include <ccan/opt/usage.c>
23 #include <ccan/opt/helpers.c>
24 #include <ccan/opt/parse.c>
31 static unsigned int alloc_count, realloc_count, free_count;
32 static void *ptrs[100];
34 static void **find_ptr(void *p)
38 for (i = 0; i < 100; i++)
44 static void *allocfn(size_t size)
47 return *find_ptr(NULL) = malloc(size);
50 static void *reallocfn(void *ptr, size_t size)
56 return *find_ptr(ptr) = realloc(ptr, size);
59 static void freefn(void *ptr)
63 *find_ptr(ptr) = NULL;
66 int main(int argc, char *argv[])
68 const char *myname = argv[0];
73 opt_set_alloc(allocfn, reallocfn, freefn);
75 /* Simple short arg.*/
76 opt_register_noarg("-a", test_noarg, NULL, "All");
77 ok1(parse_args(&argc, &argv, "-a", NULL));
79 ok1(argv[0] == myname);
81 ok1(test_cb_called == 1);
83 /* Simple long arg. */
84 opt_register_noarg("--aaa", test_noarg, NULL, "AAAAll");
85 ok1(parse_args(&argc, &argv, "--aaa", NULL));
87 ok1(argv[0] == myname);
89 ok1(test_cb_called == 2);
91 /* Both long and short args. */
92 opt_register_noarg("--aaa|-a", test_noarg, NULL, "AAAAAAll");
93 ok1(parse_args(&argc, &argv, "--aaa", "-a", NULL));
95 ok1(argv[0] == myname);
97 ok1(test_cb_called == 4);
99 /* Extra arguments preserved. */
100 ok1(parse_args(&argc, &argv, "--aaa", "-a", "extra", "args", NULL));
102 ok1(argv[0] == myname);
103 ok1(strcmp(argv[1], "extra") == 0);
104 ok1(strcmp(argv[2], "args") == 0);
105 ok1(test_cb_called == 6);
107 /* Malformed versions. */
108 ok1(!parse_args(&argc, &argv, "--aaa=arg", NULL));
109 ok1(strstr(err_output, ": --aaa: doesn't allow an argument"));
110 ok1(!parse_args(&argc, &argv, "--aa", NULL));
111 ok1(strstr(err_output, ": --aa: unrecognized option"));
112 ok1(!parse_args(&argc, &argv, "--aaargh", NULL));
113 ok1(strstr(err_output, ": --aaargh: unrecognized option"));
115 /* Argument variants. */
118 opt_register_arg("-a|--aaa", test_arg, NULL, "aaa", "AAAAAAll");
119 ok1(parse_args(&argc, &argv, "--aaa", "aaa", NULL));
121 ok1(argv[0] == myname);
122 ok1(test_cb_called == 1);
124 ok1(parse_args(&argc, &argv, "--aaa=aaa", NULL));
126 ok1(argv[0] == myname);
127 ok1(test_cb_called == 2);
129 ok1(parse_args(&argc, &argv, "-a", "aaa", NULL));
131 ok1(argv[0] == myname);
132 ok1(test_cb_called == 3);
134 /* Malformed versions. */
135 ok1(!parse_args(&argc, &argv, "-a", NULL));
136 ok1(strstr(err_output, ": -a: requires an argument"));
137 ok1(!parse_args(&argc, &argv, "--aaa", NULL));
138 ok1(strstr(err_output, ": --aaa: requires an argument"));
139 ok1(!parse_args(&argc, &argv, "--aa", NULL));
140 ok1(strstr(err_output, ": --aa: unrecognized option"));
141 ok1(!parse_args(&argc, &argv, "--aaargh", NULL));
142 ok1(strstr(err_output, ": --aaargh: unrecognized option"));
148 opt_register_table(short_table, NULL);
149 ok1(parse_args(&argc, &argv, "-a", NULL));
151 ok1(argv[0] == myname);
152 ok1(argv[1] == NULL);
153 ok1(test_cb_called == 1);
154 /* This one needs an arg. */
155 ok1(parse_args(&argc, &argv, "-b", NULL) == false);
156 ok1(test_cb_called == 1);
157 ok1(parse_args(&argc, &argv, "-b", "b", NULL));
159 ok1(argv[0] == myname);
160 ok1(argv[1] == NULL);
161 ok1(test_cb_called == 2);
166 opt_register_table(long_table, NULL);
167 ok1(parse_args(&argc, &argv, "--ddd", NULL));
169 ok1(argv[0] == myname);
170 ok1(argv[1] == NULL);
171 ok1(test_cb_called == 1);
172 /* This one needs an arg. */
173 ok1(parse_args(&argc, &argv, "--eee", NULL) == false);
174 ok1(test_cb_called == 1);
175 ok1(parse_args(&argc, &argv, "--eee", "eee", NULL));
177 ok1(argv[0] == myname);
178 ok1(argv[1] == NULL);
179 ok1(test_cb_called == 2);
181 /* Short and long, both. */
184 opt_register_table(long_and_short_table, NULL);
185 ok1(parse_args(&argc, &argv, "-g", NULL));
187 ok1(argv[0] == myname);
188 ok1(argv[1] == NULL);
189 ok1(test_cb_called == 1);
190 ok1(parse_args(&argc, &argv, "--ggg", NULL));
192 ok1(argv[0] == myname);
193 ok1(argv[1] == NULL);
194 ok1(test_cb_called == 2);
195 /* This one needs an arg. */
196 ok1(parse_args(&argc, &argv, "-h", NULL) == false);
197 ok1(test_cb_called == 2);
198 ok1(parse_args(&argc, &argv, "-h", "hhh", NULL));
200 ok1(argv[0] == myname);
201 ok1(argv[1] == NULL);
202 ok1(test_cb_called == 3);
203 ok1(parse_args(&argc, &argv, "--hhh", NULL) == false);
204 ok1(test_cb_called == 3);
205 ok1(parse_args(&argc, &argv, "--hhh", "hhh", NULL));
207 ok1(argv[0] == myname);
208 ok1(argv[1] == NULL);
209 ok1(test_cb_called == 4);
211 /* Those will all work as tables. */
214 opt_register_table(subtables, NULL);
215 ok1(parse_args(&argc, &argv, "-a", NULL));
217 ok1(argv[0] == myname);
218 ok1(argv[1] == NULL);
219 ok1(test_cb_called == 1);
220 /* This one needs an arg. */
221 ok1(parse_args(&argc, &argv, "-b", NULL) == false);
222 ok1(test_cb_called == 1);
223 ok1(parse_args(&argc, &argv, "-b", "b", NULL));
225 ok1(argv[0] == myname);
226 ok1(argv[1] == NULL);
227 ok1(test_cb_called == 2);
229 ok1(parse_args(&argc, &argv, "--ddd", NULL));
231 ok1(argv[0] == myname);
232 ok1(argv[1] == NULL);
233 ok1(test_cb_called == 3);
234 /* This one needs an arg. */
235 ok1(parse_args(&argc, &argv, "--eee", NULL) == false);
236 ok1(test_cb_called == 3);
237 ok1(parse_args(&argc, &argv, "--eee", "eee", NULL));
239 ok1(argv[0] == myname);
240 ok1(argv[1] == NULL);
241 ok1(test_cb_called == 4);
243 /* Short and long, both. */
244 ok1(parse_args(&argc, &argv, "-g", NULL));
246 ok1(argv[0] == myname);
247 ok1(argv[1] == NULL);
248 ok1(test_cb_called == 5);
249 ok1(parse_args(&argc, &argv, "--ggg", NULL));
251 ok1(argv[0] == myname);
252 ok1(argv[1] == NULL);
253 ok1(test_cb_called == 6);
254 /* This one needs an arg. */
255 ok1(parse_args(&argc, &argv, "-h", NULL) == false);
256 ok1(test_cb_called == 6);
257 ok1(parse_args(&argc, &argv, "-h", "hhh", NULL));
259 ok1(argv[0] == myname);
260 ok1(argv[1] == NULL);
261 ok1(test_cb_called == 7);
262 ok1(parse_args(&argc, &argv, "--hhh", NULL) == false);
263 ok1(test_cb_called == 7);
264 ok1(parse_args(&argc, &argv, "--hhh", "hhh", NULL));
266 ok1(argv[0] == myname);
267 ok1(argv[1] == NULL);
268 ok1(test_cb_called == 8);
270 /* Now the tricky one: -? must not be confused with an unknown option */
274 /* glibc's getopt does not handle ? with arguments. */
275 opt_register_noarg("-?", test_noarg, NULL, "Help");
276 ok1(parse_args(&argc, &argv, "-?", NULL));
277 ok1(test_cb_called == 1);
278 ok1(parse_args(&argc, &argv, "-a", NULL) == false);
279 ok1(test_cb_called == 1);
280 ok1(strstr(err_output, ": -a: unrecognized option"));
281 ok1(parse_args(&argc, &argv, "--aaaa", NULL) == false);
282 ok1(test_cb_called == 1);
283 ok1(strstr(err_output, ": --aaaa: unrecognized option"));
288 /* Corner cases involving short arg parsing weirdness. */
289 opt_register_noarg("-a|--aaa", test_noarg, NULL, "a");
290 opt_register_arg("-b|--bbb", test_arg, NULL, "bbb", "b");
291 opt_register_arg("-c|--ccc", test_arg, NULL, "aaa", "c");
293 ok1(parse_args(&argc, &argv, "-aa", NULL));
294 ok1(test_cb_called == 2);
295 ok1(parse_args(&argc, &argv, "-aab", NULL) == false);
296 ok1(test_cb_called == 4);
297 ok1(strstr(err_output, ": -b: requires an argument"));
298 ok1(parse_args(&argc, &argv, "-bbbb", NULL));
299 ok1(test_cb_called == 5);
300 ok1(parse_args(&argc, &argv, "-aabbbb", NULL));
301 ok1(test_cb_called == 8);
302 ok1(parse_args(&argc, &argv, "-aabbbb", "-b", "bbb", NULL));
303 ok1(test_cb_called == 12);
304 ok1(parse_args(&argc, &argv, "-aabbbb", "--bbb", "bbb", NULL));
305 ok1(test_cb_called == 16);
306 ok1(parse_args(&argc, &argv, "-aabbbb", "--bbb=bbb", NULL));
307 ok1(test_cb_called == 20);
308 ok1(parse_args(&argc, &argv, "-aacaaa", NULL));
309 ok1(test_cb_called == 23);
310 ok1(parse_args(&argc, &argv, "-aacaaa", "-a", NULL));
311 ok1(test_cb_called == 27);
312 ok1(parse_args(&argc, &argv, "-aacaaa", "--bbb", "bbb", "-aacaaa",
314 ok1(test_cb_called == 34);
319 /* -- and POSIXLY_CORRECT */
320 opt_register_noarg("-a|--aaa", test_noarg, NULL, "a");
321 ok1(parse_args(&argc, &argv, "-a", "--", "-a", NULL));
322 ok1(test_cb_called == 1);
324 ok1(strcmp(argv[1], "-a") == 0);
327 unsetenv("POSIXLY_CORRECT");
328 ok1(parse_args(&argc, &argv, "-a", "somearg", "-a", "--", "-a", NULL));
329 ok1(test_cb_called == 3);
331 ok1(strcmp(argv[1], "somearg") == 0);
332 ok1(strcmp(argv[2], "-a") == 0);
335 setenv("POSIXLY_CORRECT", "1", 1);
336 ok1(parse_args(&argc, &argv, "-a", "somearg", "-a", "--", "-a", NULL));
337 ok1(test_cb_called == 4);
339 ok1(strcmp(argv[1], "somearg") == 0);
340 ok1(strcmp(argv[2], "-a") == 0);
341 ok1(strcmp(argv[3], "--") == 0);
342 ok1(strcmp(argv[4], "-a") == 0);
345 /* Finally, test the helpers don't use malloc. */
347 opt_register_arg("-a", opt_set_uintval, opt_show_uintval, &val, "a");
348 ok1(!parse_args(&argc, &argv, "-a", "notanumber", NULL));
349 ok1(strstr(err_output, ": -a: 'notanumber' is not a number"));
351 /* We should have tested each one at least once! */
356 ok1(free_count < alloc_count);
358 ok1(free_count == alloc_count);
360 /* parse_args allocates argv */
362 return exit_status();