]> git.ozlabs.org Git - ccan/blob - ccan/opt/test/run-set_alloc.c
b30a77d8fc552aa8c293ee303f62081c7fab60a8
[ccan] / ccan / opt / test / run-set_alloc.c
1 #include <ccan/tap/tap.h>
2 #include <stdlib.h>
3
4 /* Make sure we override these! */
5 static void *no_malloc(size_t size)
6 {
7         abort();
8 }
9 static void *no_realloc(void *p, size_t size)
10 {
11         abort();
12 }
13 static void no_free(void *p)
14 {
15         abort();
16 }
17 #define malloc no_malloc
18 #define realloc no_realloc
19 #define free no_free
20
21 #include <ccan/opt/opt.c>
22 #include <ccan/opt/usage.c>
23 #include <ccan/opt/helpers.c>
24 #include <ccan/opt/parse.c>
25 #include "utils.h"
26
27 #undef malloc
28 #undef realloc
29 #undef free
30
31 static unsigned int alloc_count, realloc_count, free_count;
32 static void *ptrs[100];
33
34 static void **find_ptr(void *p)
35 {
36         unsigned int i;
37
38         for (i = 0; i < 100; i++)
39                 if (ptrs[i] == p)
40                         return ptrs + i;
41         return NULL;
42 }
43
44 static void *allocfn(size_t size)
45 {
46         alloc_count++;
47         return *find_ptr(NULL) = malloc(size);
48 }
49
50 static void *reallocfn(void *ptr, size_t size)
51 {
52         realloc_count++;
53         if (!ptr)
54                 alloc_count++;
55
56         return *find_ptr(ptr) = realloc(ptr, size);
57 }
58
59 static void freefn(void *ptr)
60 {
61         free_count++;
62         free(ptr);
63         *find_ptr(ptr) = NULL;
64 }
65
66 int main(int argc, char *argv[])
67 {
68         const char *myname = argv[0];
69
70         plan_tests(220);
71
72         opt_set_alloc(allocfn, reallocfn, freefn);
73
74         /* Simple short arg.*/
75         opt_register_noarg("-a", test_noarg, NULL, "All");
76         ok1(parse_args(&argc, &argv, "-a", NULL));
77         ok1(argc == 1);
78         ok1(argv[0] == myname);
79         ok1(argv[1] == NULL);
80         ok1(test_cb_called == 1);
81
82         /* Simple long arg. */
83         opt_register_noarg("--aaa", test_noarg, NULL, "AAAAll");
84         ok1(parse_args(&argc, &argv, "--aaa", NULL));
85         ok1(argc == 1);
86         ok1(argv[0] == myname);
87         ok1(argv[1] == NULL);
88         ok1(test_cb_called == 2);
89
90         /* Both long and short args. */
91         opt_register_noarg("--aaa|-a", test_noarg, NULL, "AAAAAAll");
92         ok1(parse_args(&argc, &argv, "--aaa", "-a", NULL));
93         ok1(argc == 1);
94         ok1(argv[0] == myname);
95         ok1(argv[1] == NULL);
96         ok1(test_cb_called == 4);
97
98         /* Extra arguments preserved. */
99         ok1(parse_args(&argc, &argv, "--aaa", "-a", "extra", "args", NULL));
100         ok1(argc == 3);
101         ok1(argv[0] == myname);
102         ok1(strcmp(argv[1], "extra") == 0);
103         ok1(strcmp(argv[2], "args") == 0);
104         ok1(test_cb_called == 6);
105
106         /* Malformed versions. */
107         ok1(!parse_args(&argc, &argv, "--aaa=arg", NULL));
108         ok1(strstr(err_output, ": --aaa: doesn't allow an argument"));
109         ok1(!parse_args(&argc, &argv, "--aa", NULL));
110         ok1(strstr(err_output, ": --aa: unrecognized option"));
111         ok1(!parse_args(&argc, &argv, "--aaargh", NULL));
112         ok1(strstr(err_output, ": --aaargh: unrecognized option"));
113
114         /* Argument variants. */
115         reset_options();
116         test_cb_called = 0;
117         opt_register_arg("-a|--aaa", test_arg, NULL, "aaa", "AAAAAAll");
118         ok1(parse_args(&argc, &argv, "--aaa", "aaa", NULL));
119         ok1(argc == 1);
120         ok1(argv[0] == myname);
121         ok1(test_cb_called == 1);
122
123         ok1(parse_args(&argc, &argv, "--aaa=aaa", NULL));
124         ok1(argc == 1);
125         ok1(argv[0] == myname);
126         ok1(test_cb_called == 2);
127
128         ok1(parse_args(&argc, &argv, "-a", "aaa", NULL));
129         ok1(argc == 1);
130         ok1(argv[0] == myname);
131         ok1(test_cb_called == 3);
132
133         /* Malformed versions. */
134         ok1(!parse_args(&argc, &argv, "-a", NULL));
135         ok1(strstr(err_output, ": -a: requires an argument"));
136         ok1(!parse_args(&argc, &argv, "--aaa", NULL));
137         ok1(strstr(err_output, ": --aaa: requires an argument"));
138         ok1(!parse_args(&argc, &argv, "--aa", NULL));
139         ok1(strstr(err_output, ": --aa: unrecognized option"));
140         ok1(!parse_args(&argc, &argv, "--aaargh", NULL));
141         ok1(strstr(err_output, ": --aaargh: unrecognized option"));
142
143         /* Now, tables. */
144         /* Short table: */
145         reset_options();
146         test_cb_called = 0;
147         opt_register_table(short_table, NULL);
148         ok1(parse_args(&argc, &argv, "-a", NULL));
149         ok1(argc == 1);
150         ok1(argv[0] == myname);
151         ok1(argv[1] == NULL);
152         ok1(test_cb_called == 1);
153         /* This one needs an arg. */
154         ok1(parse_args(&argc, &argv, "-b", NULL) == false);
155         ok1(test_cb_called == 1);
156         ok1(parse_args(&argc, &argv, "-b", "b", NULL));
157         ok1(argc == 1);
158         ok1(argv[0] == myname);
159         ok1(argv[1] == NULL);
160         ok1(test_cb_called == 2);
161
162         /* Long table: */
163         reset_options();
164         test_cb_called = 0;
165         opt_register_table(long_table, NULL);
166         ok1(parse_args(&argc, &argv, "--ddd", NULL));
167         ok1(argc == 1);
168         ok1(argv[0] == myname);
169         ok1(argv[1] == NULL);
170         ok1(test_cb_called == 1);
171         /* This one needs an arg. */
172         ok1(parse_args(&argc, &argv, "--eee", NULL) == false);
173         ok1(test_cb_called == 1);
174         ok1(parse_args(&argc, &argv, "--eee", "eee", NULL));
175         ok1(argc == 1);
176         ok1(argv[0] == myname);
177         ok1(argv[1] == NULL);
178         ok1(test_cb_called == 2);
179
180         /* Short and long, both. */
181         reset_options();
182         test_cb_called = 0;
183         opt_register_table(long_and_short_table, NULL);
184         ok1(parse_args(&argc, &argv, "-g", NULL));
185         ok1(argc == 1);
186         ok1(argv[0] == myname);
187         ok1(argv[1] == NULL);
188         ok1(test_cb_called == 1);
189         ok1(parse_args(&argc, &argv, "--ggg", NULL));
190         ok1(argc == 1);
191         ok1(argv[0] == myname);
192         ok1(argv[1] == NULL);
193         ok1(test_cb_called == 2);
194         /* This one needs an arg. */
195         ok1(parse_args(&argc, &argv, "-h", NULL) == false);
196         ok1(test_cb_called == 2);
197         ok1(parse_args(&argc, &argv, "-h", "hhh", NULL));
198         ok1(argc == 1);
199         ok1(argv[0] == myname);
200         ok1(argv[1] == NULL);
201         ok1(test_cb_called == 3);
202         ok1(parse_args(&argc, &argv, "--hhh", NULL) == false);
203         ok1(test_cb_called == 3);
204         ok1(parse_args(&argc, &argv, "--hhh", "hhh", NULL));
205         ok1(argc == 1);
206         ok1(argv[0] == myname);
207         ok1(argv[1] == NULL);
208         ok1(test_cb_called == 4);
209
210         /* Those will all work as tables. */
211         test_cb_called = 0;
212         reset_options();
213         opt_register_table(subtables, NULL);
214         ok1(parse_args(&argc, &argv, "-a", NULL));
215         ok1(argc == 1);
216         ok1(argv[0] == myname);
217         ok1(argv[1] == NULL);
218         ok1(test_cb_called == 1);
219         /* This one needs an arg. */
220         ok1(parse_args(&argc, &argv, "-b", NULL) == false);
221         ok1(test_cb_called == 1);
222         ok1(parse_args(&argc, &argv, "-b", "b", NULL));
223         ok1(argc == 1);
224         ok1(argv[0] == myname);
225         ok1(argv[1] == NULL);
226         ok1(test_cb_called == 2);
227
228         ok1(parse_args(&argc, &argv, "--ddd", NULL));
229         ok1(argc == 1);
230         ok1(argv[0] == myname);
231         ok1(argv[1] == NULL);
232         ok1(test_cb_called == 3);
233         /* This one needs an arg. */
234         ok1(parse_args(&argc, &argv, "--eee", NULL) == false);
235         ok1(test_cb_called == 3);
236         ok1(parse_args(&argc, &argv, "--eee", "eee", NULL));
237         ok1(argc == 1);
238         ok1(argv[0] == myname);
239         ok1(argv[1] == NULL);
240         ok1(test_cb_called == 4);
241
242         /* Short and long, both. */
243         ok1(parse_args(&argc, &argv, "-g", NULL));
244         ok1(argc == 1);
245         ok1(argv[0] == myname);
246         ok1(argv[1] == NULL);
247         ok1(test_cb_called == 5);
248         ok1(parse_args(&argc, &argv, "--ggg", NULL));
249         ok1(argc == 1);
250         ok1(argv[0] == myname);
251         ok1(argv[1] == NULL);
252         ok1(test_cb_called == 6);
253         /* This one needs an arg. */
254         ok1(parse_args(&argc, &argv, "-h", NULL) == false);
255         ok1(test_cb_called == 6);
256         ok1(parse_args(&argc, &argv, "-h", "hhh", NULL));
257         ok1(argc == 1);
258         ok1(argv[0] == myname);
259         ok1(argv[1] == NULL);
260         ok1(test_cb_called == 7);
261         ok1(parse_args(&argc, &argv, "--hhh", NULL) == false);
262         ok1(test_cb_called == 7);
263         ok1(parse_args(&argc, &argv, "--hhh", "hhh", NULL));
264         ok1(argc == 1);
265         ok1(argv[0] == myname);
266         ok1(argv[1] == NULL);
267         ok1(test_cb_called == 8);
268
269         /* Now the tricky one: -? must not be confused with an unknown option */
270         test_cb_called = 0;
271         reset_options();
272
273         /* glibc's getopt does not handle ? with arguments. */
274         opt_register_noarg("-?", test_noarg, NULL, "Help");
275         ok1(parse_args(&argc, &argv, "-?", NULL));
276         ok1(test_cb_called == 1);
277         ok1(parse_args(&argc, &argv, "-a", NULL) == false);
278         ok1(test_cb_called == 1);
279         ok1(strstr(err_output, ": -a: unrecognized option"));
280         ok1(parse_args(&argc, &argv, "--aaaa", NULL) == false);
281         ok1(test_cb_called == 1);
282         ok1(strstr(err_output, ": --aaaa: unrecognized option"));
283
284         test_cb_called = 0;
285         reset_options();
286
287         /* Corner cases involving short arg parsing weirdness. */
288         opt_register_noarg("-a|--aaa", test_noarg, NULL, "a");
289         opt_register_arg("-b|--bbb", test_arg, NULL, "bbb", "b");
290         opt_register_arg("-c|--ccc", test_arg, NULL, "aaa", "c");
291         /* -aa == -a -a */
292         ok1(parse_args(&argc, &argv, "-aa", NULL));
293         ok1(test_cb_called == 2);
294         ok1(parse_args(&argc, &argv, "-aab", NULL) == false);
295         ok1(test_cb_called == 4);
296         ok1(strstr(err_output, ": -b: requires an argument"));
297         ok1(parse_args(&argc, &argv, "-bbbb", NULL));
298         ok1(test_cb_called == 5);
299         ok1(parse_args(&argc, &argv, "-aabbbb", NULL));
300         ok1(test_cb_called == 8);
301         ok1(parse_args(&argc, &argv, "-aabbbb", "-b", "bbb", NULL));
302         ok1(test_cb_called == 12);
303         ok1(parse_args(&argc, &argv, "-aabbbb", "--bbb", "bbb", NULL));
304         ok1(test_cb_called == 16);
305         ok1(parse_args(&argc, &argv, "-aabbbb", "--bbb=bbb", NULL));
306         ok1(test_cb_called == 20);
307         ok1(parse_args(&argc, &argv, "-aacaaa", NULL));
308         ok1(test_cb_called == 23);
309         ok1(parse_args(&argc, &argv, "-aacaaa", "-a", NULL));
310         ok1(test_cb_called == 27);
311         ok1(parse_args(&argc, &argv, "-aacaaa", "--bbb", "bbb", "-aacaaa",
312                        NULL));
313         ok1(test_cb_called == 34);
314
315         test_cb_called = 0;
316         reset_options();
317
318         /* -- and POSIXLY_CORRECT */
319         opt_register_noarg("-a|--aaa", test_noarg, NULL, "a");
320         ok1(parse_args(&argc, &argv, "-a", "--", "-a", NULL));
321         ok1(test_cb_called == 1);
322         ok1(argc == 2);
323         ok1(strcmp(argv[1], "-a") == 0);
324         ok1(!argv[2]);
325
326         unsetenv("POSIXLY_CORRECT");
327         ok1(parse_args(&argc, &argv, "-a", "somearg", "-a", "--", "-a", NULL));
328         ok1(test_cb_called == 3);
329         ok1(argc == 3);
330         ok1(strcmp(argv[1], "somearg") == 0);
331         ok1(strcmp(argv[2], "-a") == 0);
332         ok1(!argv[3]);
333
334         setenv("POSIXLY_CORRECT", "1", 1);
335         ok1(parse_args(&argc, &argv, "-a", "somearg", "-a", "--", "-a", NULL));
336         ok1(test_cb_called == 4);
337         ok1(argc == 5);
338         ok1(strcmp(argv[1], "somearg") == 0);
339         ok1(strcmp(argv[2], "-a") == 0);
340         ok1(strcmp(argv[3], "--") == 0);
341         ok1(strcmp(argv[4], "-a") == 0);
342         ok1(!argv[5]);
343
344         /* We should have tested each one at least once! */
345         ok1(realloc_count);
346         ok1(alloc_count);
347         ok1(free_count);
348
349         ok1(free_count < alloc_count);
350         reset_options();
351         ok1(free_count == alloc_count);
352
353         /* parse_args allocates argv */
354         free(argv);
355         return exit_status();
356 }