opt: wean off getopt_long, beef up tests.
[ccan] / ccan / opt / test / run.c
1 #include <ccan/tap/tap.h>
2 #include <stdlib.h>
3 #include <ccan/opt/opt.c>
4 #include <ccan/opt/usage.c>
5 #include <ccan/opt/helpers.c>
6 #include <ccan/opt/parse.c>
7 #include "utils.h"
8
9 static void reset_options(void)
10 {
11         free(opt_table);
12         opt_table = NULL;
13         opt_count = opt_num_short = opt_num_short_arg = opt_num_long = 0;
14         free(err_output);
15         err_output = NULL;
16 }
17
18 int main(int argc, char *argv[])
19 {
20         const char *myname = argv[0];
21
22         plan_tests(215);
23
24         /* Simple short arg.*/
25         opt_register_noarg("-a", test_noarg, NULL, "All");
26         ok1(parse_args(&argc, &argv, "-a", NULL));
27         ok1(argc == 1);
28         ok1(argv[0] == myname);
29         ok1(argv[1] == NULL);
30         ok1(test_cb_called == 1);
31
32         /* Simple long arg. */
33         opt_register_noarg("--aaa", test_noarg, NULL, "AAAAll");
34         ok1(parse_args(&argc, &argv, "--aaa", NULL));
35         ok1(argc == 1);
36         ok1(argv[0] == myname);
37         ok1(argv[1] == NULL);
38         ok1(test_cb_called == 2);
39
40         /* Both long and short args. */
41         opt_register_noarg("--aaa|-a", test_noarg, NULL, "AAAAAAll");
42         ok1(parse_args(&argc, &argv, "--aaa", "-a", NULL));
43         ok1(argc == 1);
44         ok1(argv[0] == myname);
45         ok1(argv[1] == NULL);
46         ok1(test_cb_called == 4);
47
48         /* Extra arguments preserved. */
49         ok1(parse_args(&argc, &argv, "--aaa", "-a", "extra", "args", NULL));
50         ok1(argc == 3);
51         ok1(argv[0] == myname);
52         ok1(strcmp(argv[1], "extra") == 0);
53         ok1(strcmp(argv[2], "args") == 0);
54         ok1(test_cb_called == 6);
55
56         /* Malformed versions. */
57         ok1(!parse_args(&argc, &argv, "--aaa=arg", NULL));
58         ok1(strstr(err_output, ": --aaa: doesn't allow an argument"));
59         ok1(!parse_args(&argc, &argv, "--aa", NULL));
60         ok1(strstr(err_output, ": --aa: unrecognized option"));
61         ok1(!parse_args(&argc, &argv, "--aaargh", NULL));
62         ok1(strstr(err_output, ": --aaargh: unrecognized option"));
63
64         /* Argument variants. */
65         reset_options();
66         test_cb_called = 0;
67         opt_register_arg("-a|--aaa", test_arg, NULL, "aaa", "AAAAAAll");
68         ok1(parse_args(&argc, &argv, "--aaa", "aaa", NULL));
69         ok1(argc == 1);
70         ok1(argv[0] == myname);
71         ok1(test_cb_called == 1);
72
73         ok1(parse_args(&argc, &argv, "--aaa=aaa", NULL));
74         ok1(argc == 1);
75         ok1(argv[0] == myname);
76         ok1(test_cb_called == 2);
77
78         ok1(parse_args(&argc, &argv, "-a", "aaa", NULL));
79         ok1(argc == 1);
80         ok1(argv[0] == myname);
81         ok1(test_cb_called == 3);
82
83         /* Malformed versions. */
84         ok1(!parse_args(&argc, &argv, "-a", NULL));
85         ok1(strstr(err_output, ": -a: requires an argument"));
86         ok1(!parse_args(&argc, &argv, "--aaa", NULL));
87         ok1(strstr(err_output, ": --aaa: requires an argument"));
88         ok1(!parse_args(&argc, &argv, "--aa", NULL));
89         ok1(strstr(err_output, ": --aa: unrecognized option"));
90         ok1(!parse_args(&argc, &argv, "--aaargh", NULL));
91         ok1(strstr(err_output, ": --aaargh: unrecognized option"));
92
93         /* Now, tables. */
94         /* Short table: */
95         reset_options();
96         test_cb_called = 0;
97         opt_register_table(short_table, NULL);
98         ok1(parse_args(&argc, &argv, "-a", NULL));
99         ok1(argc == 1);
100         ok1(argv[0] == myname);
101         ok1(argv[1] == NULL);
102         ok1(test_cb_called == 1);
103         /* This one needs an arg. */
104         ok1(parse_args(&argc, &argv, "-b", NULL) == false);
105         ok1(test_cb_called == 1);
106         ok1(parse_args(&argc, &argv, "-b", "b", NULL));
107         ok1(argc == 1);
108         ok1(argv[0] == myname);
109         ok1(argv[1] == NULL);
110         ok1(test_cb_called == 2);
111
112         /* Long table: */
113         reset_options();
114         test_cb_called = 0;
115         opt_register_table(long_table, NULL);
116         ok1(parse_args(&argc, &argv, "--ddd", NULL));
117         ok1(argc == 1);
118         ok1(argv[0] == myname);
119         ok1(argv[1] == NULL);
120         ok1(test_cb_called == 1);
121         /* This one needs an arg. */
122         ok1(parse_args(&argc, &argv, "--eee", NULL) == false);
123         ok1(test_cb_called == 1);
124         ok1(parse_args(&argc, &argv, "--eee", "eee", NULL));
125         ok1(argc == 1);
126         ok1(argv[0] == myname);
127         ok1(argv[1] == NULL);
128         ok1(test_cb_called == 2);
129
130         /* Short and long, both. */
131         reset_options();
132         test_cb_called = 0;
133         opt_register_table(long_and_short_table, NULL);
134         ok1(parse_args(&argc, &argv, "-g", NULL));
135         ok1(argc == 1);
136         ok1(argv[0] == myname);
137         ok1(argv[1] == NULL);
138         ok1(test_cb_called == 1);
139         ok1(parse_args(&argc, &argv, "--ggg", NULL));
140         ok1(argc == 1);
141         ok1(argv[0] == myname);
142         ok1(argv[1] == NULL);
143         ok1(test_cb_called == 2);
144         /* This one needs an arg. */
145         ok1(parse_args(&argc, &argv, "-h", NULL) == false);
146         ok1(test_cb_called == 2);
147         ok1(parse_args(&argc, &argv, "-h", "hhh", NULL));
148         ok1(argc == 1);
149         ok1(argv[0] == myname);
150         ok1(argv[1] == NULL);
151         ok1(test_cb_called == 3);
152         ok1(parse_args(&argc, &argv, "--hhh", NULL) == false);
153         ok1(test_cb_called == 3);
154         ok1(parse_args(&argc, &argv, "--hhh", "hhh", NULL));
155         ok1(argc == 1);
156         ok1(argv[0] == myname);
157         ok1(argv[1] == NULL);
158         ok1(test_cb_called == 4);
159
160         /* Those will all work as tables. */
161         test_cb_called = 0;
162         reset_options();
163         opt_register_table(subtables, NULL);
164         ok1(parse_args(&argc, &argv, "-a", NULL));
165         ok1(argc == 1);
166         ok1(argv[0] == myname);
167         ok1(argv[1] == NULL);
168         ok1(test_cb_called == 1);
169         /* This one needs an arg. */
170         ok1(parse_args(&argc, &argv, "-b", NULL) == false);
171         ok1(test_cb_called == 1);
172         ok1(parse_args(&argc, &argv, "-b", "b", NULL));
173         ok1(argc == 1);
174         ok1(argv[0] == myname);
175         ok1(argv[1] == NULL);
176         ok1(test_cb_called == 2);
177
178         ok1(parse_args(&argc, &argv, "--ddd", NULL));
179         ok1(argc == 1);
180         ok1(argv[0] == myname);
181         ok1(argv[1] == NULL);
182         ok1(test_cb_called == 3);
183         /* This one needs an arg. */
184         ok1(parse_args(&argc, &argv, "--eee", NULL) == false);
185         ok1(test_cb_called == 3);
186         ok1(parse_args(&argc, &argv, "--eee", "eee", NULL));
187         ok1(argc == 1);
188         ok1(argv[0] == myname);
189         ok1(argv[1] == NULL);
190         ok1(test_cb_called == 4);
191
192         /* Short and long, both. */
193         ok1(parse_args(&argc, &argv, "-g", NULL));
194         ok1(argc == 1);
195         ok1(argv[0] == myname);
196         ok1(argv[1] == NULL);
197         ok1(test_cb_called == 5);
198         ok1(parse_args(&argc, &argv, "--ggg", NULL));
199         ok1(argc == 1);
200         ok1(argv[0] == myname);
201         ok1(argv[1] == NULL);
202         ok1(test_cb_called == 6);
203         /* This one needs an arg. */
204         ok1(parse_args(&argc, &argv, "-h", NULL) == false);
205         ok1(test_cb_called == 6);
206         ok1(parse_args(&argc, &argv, "-h", "hhh", NULL));
207         ok1(argc == 1);
208         ok1(argv[0] == myname);
209         ok1(argv[1] == NULL);
210         ok1(test_cb_called == 7);
211         ok1(parse_args(&argc, &argv, "--hhh", NULL) == false);
212         ok1(test_cb_called == 7);
213         ok1(parse_args(&argc, &argv, "--hhh", "hhh", NULL));
214         ok1(argc == 1);
215         ok1(argv[0] == myname);
216         ok1(argv[1] == NULL);
217         ok1(test_cb_called == 8);
218
219         /* Now the tricky one: -? must not be confused with an unknown option */
220         test_cb_called = 0;
221         reset_options();
222
223         /* glibc's getopt does not handle ? with arguments. */
224         opt_register_noarg("-?", test_noarg, NULL, "Help");
225         ok1(parse_args(&argc, &argv, "-?", NULL));
226         ok1(test_cb_called == 1);
227         ok1(parse_args(&argc, &argv, "-a", NULL) == false);
228         ok1(test_cb_called == 1);
229         ok1(strstr(err_output, ": -a: unrecognized option"));
230         ok1(parse_args(&argc, &argv, "--aaaa", NULL) == false);
231         ok1(test_cb_called == 1);
232         ok1(strstr(err_output, ": --aaaa: unrecognized option"));
233
234         test_cb_called = 0;
235         reset_options();
236
237         /* Corner cases involving short arg parsing weirdness. */
238         opt_register_noarg("-a|--aaa", test_noarg, NULL, "a");
239         opt_register_arg("-b|--bbb", test_arg, NULL, "bbb", "b");
240         opt_register_arg("-c|--ccc", test_arg, NULL, "aaa", "c");
241         /* -aa == -a -a */
242         ok1(parse_args(&argc, &argv, "-aa", NULL));
243         ok1(test_cb_called == 2);
244         ok1(parse_args(&argc, &argv, "-aab", NULL) == false);
245         ok1(test_cb_called == 4);
246         ok1(strstr(err_output, ": -b: requires an argument"));
247         ok1(parse_args(&argc, &argv, "-bbbb", NULL));
248         ok1(test_cb_called == 5);
249         ok1(parse_args(&argc, &argv, "-aabbbb", NULL));
250         ok1(test_cb_called == 8);
251         ok1(parse_args(&argc, &argv, "-aabbbb", "-b", "bbb", NULL));
252         ok1(test_cb_called == 12);
253         ok1(parse_args(&argc, &argv, "-aabbbb", "--bbb", "bbb", NULL));
254         ok1(test_cb_called == 16);
255         ok1(parse_args(&argc, &argv, "-aabbbb", "--bbb=bbb", NULL));
256         ok1(test_cb_called == 20);
257         ok1(parse_args(&argc, &argv, "-aacaaa", NULL));
258         ok1(test_cb_called == 23);
259         ok1(parse_args(&argc, &argv, "-aacaaa", "-a", NULL));
260         ok1(test_cb_called == 27);
261         ok1(parse_args(&argc, &argv, "-aacaaa", "--bbb", "bbb", "-aacaaa",
262                        NULL));
263         ok1(test_cb_called == 34);
264
265         test_cb_called = 0;
266         reset_options();
267
268         /* -- and POSIXLY_CORRECT */
269         opt_register_noarg("-a|--aaa", test_noarg, NULL, "a");
270         ok1(parse_args(&argc, &argv, "-a", "--", "-a", NULL));
271         ok1(test_cb_called == 1);
272         ok1(argc == 2);
273         ok1(strcmp(argv[1], "-a") == 0);
274         ok1(!argv[2]);
275
276         unsetenv("POSIXLY_CORRECT");
277         ok1(parse_args(&argc, &argv, "-a", "somearg", "-a", "--", "-a", NULL));
278         ok1(test_cb_called == 3);
279         ok1(argc == 3);
280         ok1(strcmp(argv[1], "somearg") == 0);
281         ok1(strcmp(argv[2], "-a") == 0);
282         ok1(!argv[3]);
283
284         setenv("POSIXLY_CORRECT", "1", 1);
285         ok1(parse_args(&argc, &argv, "-a", "somearg", "-a", "--", "-a", NULL));
286         ok1(test_cb_called == 4);
287         ok1(argc == 5);
288         ok1(strcmp(argv[1], "somearg") == 0);
289         ok1(strcmp(argv[2], "-a") == 0);
290         ok1(strcmp(argv[3], "--") == 0);
291         ok1(strcmp(argv[4], "-a") == 0);
292         ok1(!argv[5]);
293
294         return exit_status();
295 }