1 #include <ccan/tap/tap.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>
9 static void reset_options(void)
13 opt_count = opt_num_short = opt_num_short_arg = opt_num_long = 0;
18 int main(int argc, char *argv[])
20 const char *myname = argv[0];
24 /* Simple short arg.*/
25 opt_register_noarg("-a", test_noarg, NULL, "All");
26 ok1(parse_args(&argc, &argv, "-a", NULL));
28 ok1(argv[0] == myname);
30 ok1(test_cb_called == 1);
32 /* Simple long arg. */
33 opt_register_noarg("--aaa", test_noarg, NULL, "AAAAll");
34 ok1(parse_args(&argc, &argv, "--aaa", NULL));
36 ok1(argv[0] == myname);
38 ok1(test_cb_called == 2);
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));
44 ok1(argv[0] == myname);
46 ok1(test_cb_called == 4);
48 /* Extra arguments preserved. */
49 ok1(parse_args(&argc, &argv, "--aaa", "-a", "extra", "args", NULL));
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);
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"));
64 /* Argument variants. */
67 opt_register_arg("-a|--aaa", test_arg, NULL, "aaa", "AAAAAAll");
68 ok1(parse_args(&argc, &argv, "--aaa", "aaa", NULL));
70 ok1(argv[0] == myname);
71 ok1(test_cb_called == 1);
73 ok1(parse_args(&argc, &argv, "--aaa=aaa", NULL));
75 ok1(argv[0] == myname);
76 ok1(test_cb_called == 2);
78 ok1(parse_args(&argc, &argv, "-a", "aaa", NULL));
80 ok1(argv[0] == myname);
81 ok1(test_cb_called == 3);
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"));
97 opt_register_table(short_table, NULL);
98 ok1(parse_args(&argc, &argv, "-a", NULL));
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));
108 ok1(argv[0] == myname);
109 ok1(argv[1] == NULL);
110 ok1(test_cb_called == 2);
115 opt_register_table(long_table, NULL);
116 ok1(parse_args(&argc, &argv, "--ddd", NULL));
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));
126 ok1(argv[0] == myname);
127 ok1(argv[1] == NULL);
128 ok1(test_cb_called == 2);
130 /* Short and long, both. */
133 opt_register_table(long_and_short_table, NULL);
134 ok1(parse_args(&argc, &argv, "-g", NULL));
136 ok1(argv[0] == myname);
137 ok1(argv[1] == NULL);
138 ok1(test_cb_called == 1);
139 ok1(parse_args(&argc, &argv, "--ggg", NULL));
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));
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));
156 ok1(argv[0] == myname);
157 ok1(argv[1] == NULL);
158 ok1(test_cb_called == 4);
160 /* Those will all work as tables. */
163 opt_register_table(subtables, NULL);
164 ok1(parse_args(&argc, &argv, "-a", NULL));
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));
174 ok1(argv[0] == myname);
175 ok1(argv[1] == NULL);
176 ok1(test_cb_called == 2);
178 ok1(parse_args(&argc, &argv, "--ddd", NULL));
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));
188 ok1(argv[0] == myname);
189 ok1(argv[1] == NULL);
190 ok1(test_cb_called == 4);
192 /* Short and long, both. */
193 ok1(parse_args(&argc, &argv, "-g", NULL));
195 ok1(argv[0] == myname);
196 ok1(argv[1] == NULL);
197 ok1(test_cb_called == 5);
198 ok1(parse_args(&argc, &argv, "--ggg", NULL));
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));
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));
215 ok1(argv[0] == myname);
216 ok1(argv[1] == NULL);
217 ok1(test_cb_called == 8);
219 /* Now the tricky one: -? must not be confused with an unknown option */
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"));
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");
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",
263 ok1(test_cb_called == 34);
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);
273 ok1(strcmp(argv[1], "-a") == 0);
276 unsetenv("POSIXLY_CORRECT");
277 ok1(parse_args(&argc, &argv, "-a", "somearg", "-a", "--", "-a", NULL));
278 ok1(test_cb_called == 3);
280 ok1(strcmp(argv[1], "somearg") == 0);
281 ok1(strcmp(argv[2], "-a") == 0);
284 setenv("POSIXLY_CORRECT", "1", 1);
285 ok1(parse_args(&argc, &argv, "-a", "somearg", "-a", "--", "-a", NULL));
286 ok1(test_cb_called == 4);
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);
294 /* parse_args allocates argv */
296 return exit_status();