Fix indentation
[gnulib.git] / tests / test-argp.c
1 /* Test suite for argp.
2    Copyright (C) 2006-2007, 2009-2010 Free Software Foundation, Inc.
3    This file is part of the GNUlib Library.
4
5    This program is free software: you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17
18 #include <config.h>
19
20 #include "argp.h"
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #if HAVE_STRING_H
25 # include <string.h>
26 #endif
27 #if HAVE_STRINGS_H
28 # include <strings.h>
29 #endif
30 #include "progname.h"
31
32 struct test_args
33 {
34   int test;
35   int verbose;
36   char *file;
37   char *hidden;
38   int opt;
39   char *optional;
40   int optional_set;
41   int group_2_1_option;
42   int group_1_1_option;
43 };
44
45 static struct argp_option group1_option[] = {
46   { NULL, 0, NULL, 0, "Option Group 1", 0 },
47   { "verbose", 'v', NULL, 0, "Simple option without arguments", 1 },
48   { "file", 'f', "FILE", 0, "Option with a mandatory argument", 1 },
49   { "input", 0, NULL, OPTION_ALIAS, NULL, 1 },
50   { "hidden", 'H', "FILE", OPTION_HIDDEN, "Hidden option", 1 },
51   { NULL, 0, NULL, 0, NULL, 0 }
52 };
53
54 static error_t
55 group1_parser (int key, char *arg, struct argp_state *state)
56 {
57   struct test_args *args = state->input;
58
59   switch (key)
60     {
61     case 'v':
62       args->verbose++;
63       break;
64
65     case 'f':
66       args->file = arg;
67       break;
68
69     case 'H':
70       args->hidden = arg;
71       break;
72
73     default:
74       return ARGP_ERR_UNKNOWN;
75     }
76   return 0;
77 }
78
79 struct argp group1_argp = {
80   group1_option,
81   group1_parser
82 };
83
84 struct argp_child group1_child = {
85   &group1_argp,
86   0,
87   "",
88   1
89 };
90 \f
91
92 static struct argp_option group1_1_option[] = {
93   { NULL, 0, NULL, 0, "Option Group 1.1", 0 },
94   { "cantiga", 'C', NULL, 0, "create a cantiga" },
95   { "sonet", 'S', NULL, 0, "create a sonet" },
96   { NULL, 0, NULL, 0, NULL, 0 }
97 };
98
99 static error_t
100 group1_1_parser (int key, char *arg, struct argp_state *state)
101 {
102   struct test_args *args = state->input;
103   switch (key)
104     {
105     case 'C':
106     case 'S':
107       args->group_1_1_option = key;
108       break;
109     default:
110       return ARGP_ERR_UNKNOWN;
111     }
112   return 0;
113 }
114
115 struct argp group1_1_argp = {
116   group1_1_option,
117   group1_1_parser
118 };
119
120 struct argp_child group1_1_child = {
121   &group1_1_argp,
122   0,
123   "",
124   2
125 };
126 \f
127
128 static struct argp_option group2_option[] = {
129   { NULL, 0, NULL, 0, "Option Group 2", 0 },
130   { "option", 'O', NULL, 0, "An option", 1 },
131   { "optional", 'o', "ARG", OPTION_ARG_OPTIONAL,
132     "Option with an optional argument. ARG is one of the following:", 2 },
133   { "one", 0, NULL, OPTION_DOC | OPTION_NO_TRANS, "one unit", 3 },
134   { "two", 0, NULL, OPTION_DOC | OPTION_NO_TRANS, "two units", 3 },
135   { "many", 0, NULL, OPTION_DOC | OPTION_NO_TRANS, "many units", 3 },
136   { NULL, 0, NULL, 0, NULL, 0 }
137 };
138
139 static error_t
140 group2_parser (int key, char *arg, struct argp_state *state)
141 {
142   struct test_args *args = state->input;
143
144   switch (key)
145     {
146     case 'O':
147       args->opt = 1;
148       break;
149
150     case 'o':
151       args->optional_set = 1;
152       args->optional = arg;
153       break;
154
155     default:
156       return ARGP_ERR_UNKNOWN;
157     }
158   return 0;
159 }
160
161 struct argp group2_argp = {
162   group2_option,
163   group2_parser
164 };
165
166 struct argp_child group2_child = {
167   &group2_argp,
168   0,
169   "",
170   2
171 };
172 \f
173
174 static struct argp_option group2_1_option[] = {
175   { NULL, 0, NULL, 0, "Option Group 2.1", 0 },
176   { "poem", 'p', NULL, 0, "create a poem" },
177   { "limerick", 'l', NULL, 0, "create a limerick" },
178   { NULL, 0, NULL, 0, NULL, 0 }
179 };
180
181 static error_t
182 group2_1_parser (int key, char *arg, struct argp_state *state)
183 {
184   struct test_args *args = state->input;
185   switch (key)
186     {
187     case 'p':
188     case 'e':
189       args->group_2_1_option = key;
190       break;
191     default:
192       return ARGP_ERR_UNKNOWN;
193     }
194   return 0;
195 }
196
197 struct argp group2_1_argp = {
198   group2_1_option,
199   group2_1_parser
200 };
201
202 struct argp_child group2_1_child = {
203   &group2_1_argp,
204   0,
205   "",
206   2
207 };
208 \f
209
210 static struct argp_option main_options[] = {
211   { NULL, 0, NULL, 0, "Main options", 0 },
212   { "test", 't', NULL, 0, NULL, 1 },
213   { NULL, 0, NULL, 0, NULL, 0 }
214 };
215
216 static error_t
217 parse_opt (int key, char *arg, struct argp_state *state)
218 {
219   struct test_args *args = state->input;
220   int i;
221
222   switch (key)
223     {
224     case ARGP_KEY_INIT:
225       for (i = 0; state->root_argp->children[i].argp; i++)
226         state->child_inputs[i] = args;
227       break;
228
229     case 't':
230       args->test = 1;
231       break;
232
233     default:
234       return ARGP_ERR_UNKNOWN;
235     }
236   return 0;
237 }
238
239 const char *argp_program_version = "test_argp (" PACKAGE_NAME ") " VERSION;
240 const char *argp_program_bug_address = "<" PACKAGE_BUGREPORT ">";
241 static char doc[] = "documentation string";
242
243 struct argp test_argp = {
244   main_options,
245   parse_opt,
246   "ARGS...",
247   doc,
248   NULL,
249   NULL,
250   NULL
251 };
252
253 #define NARGS(a) (sizeof(a) / sizeof((a)[0]) - 1)
254 #define ARGV0 "test-argp"
255 #define init_args(a) memset (&(a), 0, sizeof (a));
256
257 #define INIT_TEST_COMMON(n)     \
258  int argc = NARGS (argv);       \
259  struct test_args test_args;    \
260  init_args(test_args);          \
261  test_number = n;
262
263 #define INIT_TEST1(n, arg1)            \
264  char *argv[] = { ARGV0, arg1, NULL }; \
265  INIT_TEST_COMMON(n)
266
267 #define INIT_TEST2(n, arg1, arg2)            \
268  char *argv[] = { ARGV0, arg1, arg2, NULL }; \
269  INIT_TEST_COMMON(n)
270
271 #define INIT_TEST3(n, arg1, arg2, arg3)            \
272  char *argv[] = { ARGV0, arg1, arg2, arg3, NULL }; \
273  INIT_TEST_COMMON(n)
274
275 int test_number;
276 unsigned failure_count = 0;
277
278 void
279 fail (const char *msg)
280 {
281   fprintf (stderr, "Test %d: %s\n", test_number, msg);
282   failure_count++;
283 }
284
285 void
286 test1 (struct argp *argp)
287 {
288   INIT_TEST1 (1, "--test");
289   if (argp_parse (argp, argc, argv, 0, NULL, &test_args))
290     fail ("argp_parse failed");
291   else if (test_args.test != 1)
292     fail ("option not processed");
293 }
294
295 void
296 test2 (struct argp *argp)
297 {
298   INIT_TEST1 (2, "-t");
299   if (argp_parse (argp, argc, argv, 0, NULL, &test_args))
300     fail ("argp_parse failed");
301   else if (test_args.test != 1)
302     fail ("option not processed");
303 }
304
305 void
306 test_file (struct argp *argp, int argc, char **argv, struct test_args *args)
307 {
308   if (argp_parse (argp, argc, argv, 0, NULL, args))
309     fail ("argp_parse failed");
310   else if (!args->file)
311     fail ("option not processed");
312   else if (strcmp (args->file, "FILE"))
313     fail ("option processed incorrectly");
314 }
315
316 void
317 test3 (struct argp *argp)
318 {
319   INIT_TEST1 (3, "--file=FILE");
320   test_file (argp, argc, argv, &test_args);
321 }
322
323 void
324 test4 (struct argp *argp)
325 {
326   INIT_TEST2 (4, "--file", "FILE");
327   test_file (argp, argc, argv, &test_args);
328 }
329
330 void
331 test5 (struct argp *argp)
332 {
333   INIT_TEST1 (5, "--input=FILE");
334   test_file (argp, argc, argv, &test_args);
335 }
336
337 void
338 test6 (struct argp *argp)
339 {
340   INIT_TEST2 (6, "--input", "FILE");
341   test_file (argp, argc, argv, &test_args);
342 }
343
344 void
345 test_optional (struct argp *argp, int argc, char **argv,
346                struct test_args *args, char *val, char *a)
347 {
348   int index;
349   if (argp_parse (argp, argc, argv, 0, &index, args))
350     fail ("argp_parse failed");
351   else if (!args->optional_set)
352     fail ("option not processed");
353
354   if (!val)
355     {
356       if (args->optional)
357         fail ("option processed incorrectly");
358     }
359   else if (strcmp (args->optional, val))
360     fail ("option processed incorrectly");
361
362   if (a)
363     {
364       if (index == argc)
365         fail ("expected command line argument not found");
366       else if (strcmp (argv[index], a))
367         fail ("expected command line argument does not match");
368     }
369 }
370
371 void
372 test7 (struct argp *argp)
373 {
374   INIT_TEST1 (7, "-oARG");
375   test_optional (argp, argc, argv, &test_args, "ARG", NULL);
376 }
377
378 void
379 test8 (struct argp *argp)
380 {
381   INIT_TEST2 (8, "-o", "ARG");
382   test_optional (argp, argc, argv, &test_args, NULL, "ARG");
383 }
384
385 void
386 test9 (struct argp *argp)
387 {
388   INIT_TEST1 (9, "--optional=ARG");
389   test_optional (argp, argc, argv, &test_args, "ARG", NULL);
390 }
391
392 void
393 test10 (struct argp *argp)
394 {
395   INIT_TEST2 (10, "--optional", "ARG");
396   test_optional (argp, argc, argv, &test_args, NULL, "ARG");
397 }
398
399 void
400 test11 (struct argp *argp)
401 {
402   INIT_TEST1 (11, "--optiona=ARG");
403   test_optional (argp, argc, argv, &test_args, "ARG", NULL);
404 }
405
406 void
407 test12 (struct argp *argp)
408 {
409   INIT_TEST3 (12, "--option", "--optional=OPT", "FILE");
410   test_optional (argp, argc, argv, &test_args, "OPT", "FILE");
411 }
412
413 void
414 test13 (struct argp *argp)
415 {
416   INIT_TEST1 (1, "--cantiga");
417   if (argp_parse (argp, argc, argv, 0, NULL, &test_args))
418     fail ("argp_parse failed");
419   else if (test_args.group_1_1_option != 'C')
420     fail ("option not processed");
421 }
422
423 void
424 test14 (struct argp *argp)
425 {
426   INIT_TEST1 (1, "--limerick");
427   if (argp_parse (argp, argc, argv, 0, NULL, &test_args))
428     fail ("argp_parse failed");
429   else if (test_args.group_2_1_option != 'l')
430     fail ("option not processed");
431 }
432
433
434
435 typedef void (*test_fp) (struct argp *argp);
436
437 test_fp test_fun[] = {
438   test1,  test2,  test3,  test4,
439   test5,  test6,  test7,  test8,
440   test9,  test10, test11, test12,
441   test13, test14,
442   NULL
443 };
444
445 int
446 main (int argc, char **argv)
447 {
448   struct argp_child argp_children[3], group1_children[2], group2_children[2];
449   test_fp *fun;
450
451   set_program_name (argv[0]);
452
453   group1_children[0] = group1_1_child;
454   group1_children[1].argp = NULL;
455   group1_argp.children = group1_children;
456
457   group2_children[0] = group2_1_child;
458   group2_children[1].argp = NULL;
459   group2_argp.children = group2_children;
460
461   argp_children[0] = group1_child;
462   argp_children[1] = group2_child;
463   argp_children[2].argp = NULL;
464   test_argp.children = argp_children;
465
466   if (argc > 0)
467     {
468       struct test_args test_args;
469       init_args (test_args);
470       return argp_parse (&test_argp, argc, argv, 0, NULL, &test_args);
471     }
472
473   for (fun = test_fun; *fun; fun++)
474     (*fun) (&test_argp);
475
476   if (failure_count)
477     return 1;
478
479   return 0;
480 }