]> git.ozlabs.org Git - ccan/blob - ccan/opt/test/run-set_alloc.c
opt: don't use raw malloc for errors.
[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         unsigned int val;
70
71         plan_tests(222);
72
73         opt_set_alloc(allocfn, reallocfn, freefn);
74
75         /* Simple short arg.*/
76         opt_register_noarg("-a", test_noarg, NULL, "All");
77         ok1(parse_args(&argc, &argv, "-a", NULL));
78         ok1(argc == 1);
79         ok1(argv[0] == myname);
80         ok1(argv[1] == NULL);
81         ok1(test_cb_called == 1);
82
83         /* Simple long arg. */
84         opt_register_noarg("--aaa", test_noarg, NULL, "AAAAll");
85         ok1(parse_args(&argc, &argv, "--aaa", NULL));
86         ok1(argc == 1);
87         ok1(argv[0] == myname);
88         ok1(argv[1] == NULL);
89         ok1(test_cb_called == 2);
90
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));
94         ok1(argc == 1);
95         ok1(argv[0] == myname);
96         ok1(argv[1] == NULL);
97         ok1(test_cb_called == 4);
98
99         /* Extra arguments preserved. */
100         ok1(parse_args(&argc, &argv, "--aaa", "-a", "extra", "args", NULL));
101         ok1(argc == 3);
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);
106
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"));
114
115         /* Argument variants. */
116         reset_options();
117         test_cb_called = 0;
118         opt_register_arg("-a|--aaa", test_arg, NULL, "aaa", "AAAAAAll");
119         ok1(parse_args(&argc, &argv, "--aaa", "aaa", NULL));
120         ok1(argc == 1);
121         ok1(argv[0] == myname);
122         ok1(test_cb_called == 1);
123
124         ok1(parse_args(&argc, &argv, "--aaa=aaa", NULL));
125         ok1(argc == 1);
126         ok1(argv[0] == myname);
127         ok1(test_cb_called == 2);
128
129         ok1(parse_args(&argc, &argv, "-a", "aaa", NULL));
130         ok1(argc == 1);
131         ok1(argv[0] == myname);
132         ok1(test_cb_called == 3);
133
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"));
143
144         /* Now, tables. */
145         /* Short table: */
146         reset_options();
147         test_cb_called = 0;
148         opt_register_table(short_table, NULL);
149         ok1(parse_args(&argc, &argv, "-a", NULL));
150         ok1(argc == 1);
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));
158         ok1(argc == 1);
159         ok1(argv[0] == myname);
160         ok1(argv[1] == NULL);
161         ok1(test_cb_called == 2);
162
163         /* Long table: */
164         reset_options();
165         test_cb_called = 0;
166         opt_register_table(long_table, NULL);
167         ok1(parse_args(&argc, &argv, "--ddd", NULL));
168         ok1(argc == 1);
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));
176         ok1(argc == 1);
177         ok1(argv[0] == myname);
178         ok1(argv[1] == NULL);
179         ok1(test_cb_called == 2);
180
181         /* Short and long, both. */
182         reset_options();
183         test_cb_called = 0;
184         opt_register_table(long_and_short_table, NULL);
185         ok1(parse_args(&argc, &argv, "-g", NULL));
186         ok1(argc == 1);
187         ok1(argv[0] == myname);
188         ok1(argv[1] == NULL);
189         ok1(test_cb_called == 1);
190         ok1(parse_args(&argc, &argv, "--ggg", NULL));
191         ok1(argc == 1);
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));
199         ok1(argc == 1);
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));
206         ok1(argc == 1);
207         ok1(argv[0] == myname);
208         ok1(argv[1] == NULL);
209         ok1(test_cb_called == 4);
210
211         /* Those will all work as tables. */
212         test_cb_called = 0;
213         reset_options();
214         opt_register_table(subtables, NULL);
215         ok1(parse_args(&argc, &argv, "-a", NULL));
216         ok1(argc == 1);
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));
224         ok1(argc == 1);
225         ok1(argv[0] == myname);
226         ok1(argv[1] == NULL);
227         ok1(test_cb_called == 2);
228
229         ok1(parse_args(&argc, &argv, "--ddd", NULL));
230         ok1(argc == 1);
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));
238         ok1(argc == 1);
239         ok1(argv[0] == myname);
240         ok1(argv[1] == NULL);
241         ok1(test_cb_called == 4);
242
243         /* Short and long, both. */
244         ok1(parse_args(&argc, &argv, "-g", NULL));
245         ok1(argc == 1);
246         ok1(argv[0] == myname);
247         ok1(argv[1] == NULL);
248         ok1(test_cb_called == 5);
249         ok1(parse_args(&argc, &argv, "--ggg", NULL));
250         ok1(argc == 1);
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));
258         ok1(argc == 1);
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));
265         ok1(argc == 1);
266         ok1(argv[0] == myname);
267         ok1(argv[1] == NULL);
268         ok1(test_cb_called == 8);
269
270         /* Now the tricky one: -? must not be confused with an unknown option */
271         test_cb_called = 0;
272         reset_options();
273
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"));
284
285         test_cb_called = 0;
286         reset_options();
287
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");
292         /* -aa == -a -a */
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",
313                        NULL));
314         ok1(test_cb_called == 34);
315
316         test_cb_called = 0;
317         reset_options();
318
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);
323         ok1(argc == 2);
324         ok1(strcmp(argv[1], "-a") == 0);
325         ok1(!argv[2]);
326
327         unsetenv("POSIXLY_CORRECT");
328         ok1(parse_args(&argc, &argv, "-a", "somearg", "-a", "--", "-a", NULL));
329         ok1(test_cb_called == 3);
330         ok1(argc == 3);
331         ok1(strcmp(argv[1], "somearg") == 0);
332         ok1(strcmp(argv[2], "-a") == 0);
333         ok1(!argv[3]);
334
335         setenv("POSIXLY_CORRECT", "1", 1);
336         ok1(parse_args(&argc, &argv, "-a", "somearg", "-a", "--", "-a", NULL));
337         ok1(test_cb_called == 4);
338         ok1(argc == 5);
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);
343         ok1(!argv[5]);
344
345         /* Finally, test the helpers don't use malloc. */
346         reset_options();
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"));
350
351         /* We should have tested each one at least once! */
352         ok1(realloc_count);
353         ok1(alloc_count);
354         ok1(free_count);
355
356         ok1(free_count < alloc_count);
357         reset_options();
358         ok1(free_count == alloc_count);
359
360         /* parse_args allocates argv */
361         free(argv);
362         return exit_status();
363 }