Use spaces for indentation, not tabs.
[gnulib.git] / tests / test-getopt.h
1 /* Test of command line argument processing.
2    Copyright (C) 2009 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
16
17 /* Written by Bruno Haible <bruno@clisp.org>, 2009.  */
18
19 #include <stdbool.h>
20
21 static void
22 getopt_loop (int argc, const char **argv,
23              const char *options,
24              int *a_seen, int *b_seen,
25              const char **p_value, const char **q_value,
26              int *non_options_count, const char **non_options,
27              int *unrecognized)
28 {
29   int c;
30
31   opterr = 0;
32   while ((c = getopt (argc, (char **) argv, options)) != -1)
33     {
34       switch (c)
35         {
36         case 'a':
37           (*a_seen)++;
38           break;
39         case 'b':
40           (*b_seen)++;
41           break;
42         case 'p':
43           *p_value = optarg;
44           break;
45         case 'q':
46           *q_value = optarg;
47           break;
48         case '\1':
49           /* Must only happen with option '-' at the beginning.  */
50           ASSERT (options[0] == '-');
51           non_options[(*non_options_count)++] = optarg;
52           break;
53         case '?':
54           *unrecognized = optopt;
55           break;
56         default:
57           *unrecognized = c;
58           break;
59         }
60     }
61 }
62
63 static void
64 test_getopt (void)
65 {
66   int start;
67   bool posixly = !!getenv ("POSIXLY_CORRECT");
68   /* See comment in getopt.c:
69      glibc gets a LSB-compliant getopt.
70      Standalone applications get a POSIX-compliant getopt.  */
71 #if defined __GETOPT_PREFIX || !(__GLIBC__ >= 2 || defined __MINGW32__)
72   /* Using getopt from gnulib or from a non-glibc system.  */
73   posixly = true;
74 #endif
75
76   /* Test processing of boolean options.  */
77   for (start = OPTIND_MIN; start <= 1; start++)
78     {
79       int a_seen = 0;
80       int b_seen = 0;
81       const char *p_value = NULL;
82       const char *q_value = NULL;
83       int non_options_count = 0;
84       const char *non_options[10];
85       int unrecognized = 0;
86       int argc = 0;
87       const char *argv[10];
88
89       argv[argc++] = "program";
90       argv[argc++] = "-a";
91       argv[argc++] = "foo";
92       argv[argc++] = "bar";
93       argv[argc] = NULL;
94       optind = start;
95       getopt_loop (argc, argv, "ab",
96                    &a_seen, &b_seen, &p_value, &q_value,
97                    &non_options_count, non_options, &unrecognized);
98       ASSERT (a_seen == 1);
99       ASSERT (b_seen == 0);
100       ASSERT (p_value == NULL);
101       ASSERT (q_value == NULL);
102       ASSERT (non_options_count == 0);
103       ASSERT (unrecognized == 0);
104       ASSERT (optind == 2);
105     }
106   for (start = OPTIND_MIN; start <= 1; start++)
107     {
108       int a_seen = 0;
109       int b_seen = 0;
110       const char *p_value = NULL;
111       const char *q_value = NULL;
112       int non_options_count = 0;
113       const char *non_options[10];
114       int unrecognized = 0;
115       int argc = 0;
116       const char *argv[10];
117
118       argv[argc++] = "program";
119       argv[argc++] = "-b";
120       argv[argc++] = "-a";
121       argv[argc++] = "foo";
122       argv[argc++] = "bar";
123       argv[argc] = NULL;
124       optind = start;
125       getopt_loop (argc, argv, "ab",
126                    &a_seen, &b_seen, &p_value, &q_value,
127                    &non_options_count, non_options, &unrecognized);
128       ASSERT (a_seen == 1);
129       ASSERT (b_seen == 1);
130       ASSERT (p_value == NULL);
131       ASSERT (q_value == NULL);
132       ASSERT (non_options_count == 0);
133       ASSERT (unrecognized == 0);
134       ASSERT (optind == 3);
135     }
136   for (start = OPTIND_MIN; start <= 1; start++)
137     {
138       int a_seen = 0;
139       int b_seen = 0;
140       const char *p_value = NULL;
141       const char *q_value = NULL;
142       int non_options_count = 0;
143       const char *non_options[10];
144       int unrecognized = 0;
145       int argc = 0;
146       const char *argv[10];
147
148       argv[argc++] = "program";
149       argv[argc++] = "-ba";
150       argv[argc++] = "foo";
151       argv[argc++] = "bar";
152       argv[argc] = NULL;
153       optind = start;
154       getopt_loop (argc, argv, "ab",
155                    &a_seen, &b_seen, &p_value, &q_value,
156                    &non_options_count, non_options, &unrecognized);
157       ASSERT (a_seen == 1);
158       ASSERT (b_seen == 1);
159       ASSERT (p_value == NULL);
160       ASSERT (q_value == NULL);
161       ASSERT (non_options_count == 0);
162       ASSERT (unrecognized == 0);
163       ASSERT (optind == 2);
164     }
165   for (start = OPTIND_MIN; start <= 1; start++)
166     {
167       int a_seen = 0;
168       int b_seen = 0;
169       const char *p_value = NULL;
170       const char *q_value = NULL;
171       int non_options_count = 0;
172       const char *non_options[10];
173       int unrecognized = 0;
174       int argc = 0;
175       const char *argv[10];
176
177       argv[argc++] = "program";
178       argv[argc++] = "-ab";
179       argv[argc++] = "-a";
180       argv[argc++] = "foo";
181       argv[argc++] = "bar";
182       argv[argc] = NULL;
183       optind = start;
184       getopt_loop (argc, argv, "ab",
185                    &a_seen, &b_seen, &p_value, &q_value,
186                    &non_options_count, non_options, &unrecognized);
187       ASSERT (a_seen == 2);
188       ASSERT (b_seen == 1);
189       ASSERT (p_value == NULL);
190       ASSERT (q_value == NULL);
191       ASSERT (non_options_count == 0);
192       ASSERT (unrecognized == 0);
193       ASSERT (optind == 3);
194     }
195
196   /* Test processing of options with arguments.  */
197   for (start = OPTIND_MIN; start <= 1; start++)
198     {
199       int a_seen = 0;
200       int b_seen = 0;
201       const char *p_value = NULL;
202       const char *q_value = NULL;
203       int non_options_count = 0;
204       const char *non_options[10];
205       int unrecognized = 0;
206       int argc = 0;
207       const char *argv[10];
208
209       argv[argc++] = "program";
210       argv[argc++] = "-pfoo";
211       argv[argc++] = "bar";
212       argv[argc] = NULL;
213       optind = start;
214       getopt_loop (argc, argv, "p:q:",
215                    &a_seen, &b_seen, &p_value, &q_value,
216                    &non_options_count, non_options, &unrecognized);
217       ASSERT (a_seen == 0);
218       ASSERT (b_seen == 0);
219       ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
220       ASSERT (q_value == NULL);
221       ASSERT (non_options_count == 0);
222       ASSERT (unrecognized == 0);
223       ASSERT (optind == 2);
224     }
225   for (start = OPTIND_MIN; start <= 1; start++)
226     {
227       int a_seen = 0;
228       int b_seen = 0;
229       const char *p_value = NULL;
230       const char *q_value = NULL;
231       int non_options_count = 0;
232       const char *non_options[10];
233       int unrecognized = 0;
234       int argc = 0;
235       const char *argv[10];
236
237       argv[argc++] = "program";
238       argv[argc++] = "-p";
239       argv[argc++] = "foo";
240       argv[argc++] = "bar";
241       argv[argc] = NULL;
242       optind = start;
243       getopt_loop (argc, argv, "p:q:",
244                    &a_seen, &b_seen, &p_value, &q_value,
245                    &non_options_count, non_options, &unrecognized);
246       ASSERT (a_seen == 0);
247       ASSERT (b_seen == 0);
248       ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
249       ASSERT (q_value == NULL);
250       ASSERT (non_options_count == 0);
251       ASSERT (unrecognized == 0);
252       ASSERT (optind == 3);
253     }
254   for (start = OPTIND_MIN; start <= 1; start++)
255     {
256       int a_seen = 0;
257       int b_seen = 0;
258       const char *p_value = NULL;
259       const char *q_value = NULL;
260       int non_options_count = 0;
261       const char *non_options[10];
262       int unrecognized = 0;
263       int argc = 0;
264       const char *argv[10];
265
266       argv[argc++] = "program";
267       argv[argc++] = "-ab";
268       argv[argc++] = "-q";
269       argv[argc++] = "baz";
270       argv[argc++] = "-pfoo";
271       argv[argc++] = "bar";
272       argv[argc] = NULL;
273       optind = start;
274       getopt_loop (argc, argv, "abp:q:",
275                    &a_seen, &b_seen, &p_value, &q_value,
276                    &non_options_count, non_options, &unrecognized);
277       ASSERT (a_seen == 1);
278       ASSERT (b_seen == 1);
279       ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
280       ASSERT (q_value != NULL && strcmp (q_value, "baz") == 0);
281       ASSERT (non_options_count == 0);
282       ASSERT (unrecognized == 0);
283       ASSERT (optind == 5);
284     }
285
286 #if GNULIB_GETOPT_GNU
287   /* Test processing of options with optional arguments.  */
288   for (start = OPTIND_MIN; start <= 1; start++)
289     {
290       int a_seen = 0;
291       int b_seen = 0;
292       const char *p_value = NULL;
293       const char *q_value = NULL;
294       int non_options_count = 0;
295       const char *non_options[10];
296       int unrecognized = 0;
297       int argc = 0;
298       const char *argv[10];
299
300       argv[argc++] = "program";
301       argv[argc++] = "-pfoo";
302       argv[argc++] = "bar";
303       argv[argc] = NULL;
304       optind = start;
305       getopt_loop (argc, argv, "p::q::",
306                    &a_seen, &b_seen, &p_value, &q_value,
307                    &non_options_count, non_options, &unrecognized);
308       ASSERT (a_seen == 0);
309       ASSERT (b_seen == 0);
310       ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
311       ASSERT (q_value == NULL);
312       ASSERT (non_options_count == 0);
313       ASSERT (unrecognized == 0);
314       ASSERT (optind == 2);
315     }
316   for (start = OPTIND_MIN; start <= 1; start++)
317     {
318       int a_seen = 0;
319       int b_seen = 0;
320       const char *p_value = NULL;
321       const char *q_value = NULL;
322       int non_options_count = 0;
323       const char *non_options[10];
324       int unrecognized = 0;
325       int argc = 0;
326       const char *argv[10];
327
328       argv[argc++] = "program";
329       argv[argc++] = "-p";
330       argv[argc++] = "foo";
331       argv[argc++] = "bar";
332       argv[argc] = NULL;
333       optind = start;
334       getopt_loop (argc, argv, "p::q::",
335                    &a_seen, &b_seen, &p_value, &q_value,
336                    &non_options_count, non_options, &unrecognized);
337       ASSERT (a_seen == 0);
338       ASSERT (b_seen == 0);
339       ASSERT (p_value == NULL);
340       ASSERT (q_value == NULL);
341       ASSERT (non_options_count == 0);
342       ASSERT (unrecognized == 0);
343       ASSERT (optind == 2);
344     }
345   for (start = OPTIND_MIN; start <= 1; start++)
346     {
347       int a_seen = 0;
348       int b_seen = 0;
349       const char *p_value = NULL;
350       const char *q_value = NULL;
351       int non_options_count = 0;
352       const char *non_options[10];
353       int unrecognized = 0;
354       int argc = 0;
355       const char *argv[10];
356
357       argv[argc++] = "program";
358       argv[argc++] = "-p";
359       argv[argc++] = "-a";
360       argv[argc++] = "bar";
361       argv[argc] = NULL;
362       optind = start;
363       getopt_loop (argc, argv, "abp::q::",
364                    &a_seen, &b_seen, &p_value, &q_value,
365                    &non_options_count, non_options, &unrecognized);
366       ASSERT (a_seen == 1);
367       ASSERT (b_seen == 0);
368       ASSERT (p_value == NULL);
369       ASSERT (q_value == NULL);
370       ASSERT (non_options_count == 0);
371       ASSERT (unrecognized == 0);
372       ASSERT (optind == 3);
373     }
374 #endif
375
376   /* Check that invalid options are recognized.  */
377   for (start = OPTIND_MIN; start <= 1; start++)
378     {
379       int a_seen = 0;
380       int b_seen = 0;
381       const char *p_value = NULL;
382       const char *q_value = NULL;
383       int non_options_count = 0;
384       const char *non_options[10];
385       int unrecognized = 0;
386       int argc = 0;
387       const char *argv[10];
388
389       argv[argc++] = "program";
390       argv[argc++] = "-p";
391       argv[argc++] = "foo";
392       argv[argc++] = "-x";
393       argv[argc++] = "-a";
394       argv[argc++] = "bar";
395       argv[argc] = NULL;
396       optind = start;
397       getopt_loop (argc, argv, "abp:q:",
398                    &a_seen, &b_seen, &p_value, &q_value,
399                    &non_options_count, non_options, &unrecognized);
400       ASSERT (a_seen == 1);
401       ASSERT (b_seen == 0);
402       ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
403       ASSERT (q_value == NULL);
404       ASSERT (non_options_count == 0);
405       ASSERT (unrecognized == 'x');
406       ASSERT (optind == 5);
407     }
408
409   /* Check that by default, non-options arguments are moved to the end.  */
410   for (start = OPTIND_MIN; start <= 1; start++)
411     {
412       int a_seen = 0;
413       int b_seen = 0;
414       const char *p_value = NULL;
415       const char *q_value = NULL;
416       int non_options_count = 0;
417       const char *non_options[10];
418       int unrecognized = 0;
419       int argc = 0;
420       const char *argv[10];
421
422       argv[argc++] = "program";
423       argv[argc++] = "donald";
424       argv[argc++] = "-p";
425       argv[argc++] = "billy";
426       argv[argc++] = "duck";
427       argv[argc++] = "-a";
428       argv[argc++] = "bar";
429       argv[argc] = NULL;
430       optind = start;
431       getopt_loop (argc, argv, "abp:q:",
432                    &a_seen, &b_seen, &p_value, &q_value,
433                    &non_options_count, non_options, &unrecognized);
434       if (posixly)
435         {
436           ASSERT (strcmp (argv[0], "program") == 0);
437           ASSERT (strcmp (argv[1], "donald") == 0);
438           ASSERT (strcmp (argv[2], "-p") == 0);
439           ASSERT (strcmp (argv[3], "billy") == 0);
440           ASSERT (strcmp (argv[4], "duck") == 0);
441           ASSERT (strcmp (argv[5], "-a") == 0);
442           ASSERT (strcmp (argv[6], "bar") == 0);
443           ASSERT (argv[7] == NULL);
444           ASSERT (a_seen == 0);
445           ASSERT (b_seen == 0);
446           ASSERT (p_value == NULL);
447           ASSERT (q_value == NULL);
448           ASSERT (non_options_count == 0);
449           ASSERT (unrecognized == 0);
450           ASSERT (optind == 1);
451         }
452       else
453         {
454           ASSERT (strcmp (argv[0], "program") == 0);
455           ASSERT (strcmp (argv[1], "-p") == 0);
456           ASSERT (strcmp (argv[2], "billy") == 0);
457           ASSERT (strcmp (argv[3], "-a") == 0);
458           ASSERT (strcmp (argv[4], "donald") == 0);
459           ASSERT (strcmp (argv[5], "duck") == 0);
460           ASSERT (strcmp (argv[6], "bar") == 0);
461           ASSERT (argv[7] == NULL);
462           ASSERT (a_seen == 1);
463           ASSERT (b_seen == 0);
464           ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
465           ASSERT (q_value == NULL);
466           ASSERT (non_options_count == 0);
467           ASSERT (unrecognized == 0);
468           ASSERT (optind == 4);
469         }
470     }
471
472   /* Check that '--' ends the argument processing.  */
473   for (start = OPTIND_MIN; start <= 1; start++)
474     {
475       int a_seen = 0;
476       int b_seen = 0;
477       const char *p_value = NULL;
478       const char *q_value = NULL;
479       int non_options_count = 0;
480       const char *non_options[10];
481       int unrecognized = 0;
482       int argc = 0;
483       const char *argv[20];
484
485       argv[argc++] = "program";
486       argv[argc++] = "donald";
487       argv[argc++] = "-p";
488       argv[argc++] = "billy";
489       argv[argc++] = "duck";
490       argv[argc++] = "-a";
491       argv[argc++] = "--";
492       argv[argc++] = "-b";
493       argv[argc++] = "foo";
494       argv[argc++] = "-q";
495       argv[argc++] = "johnny";
496       argv[argc++] = "bar";
497       argv[argc] = NULL;
498       optind = start;
499       getopt_loop (argc, argv, "abp:q:",
500                    &a_seen, &b_seen, &p_value, &q_value,
501                    &non_options_count, non_options, &unrecognized);
502       if (posixly)
503         {
504           ASSERT (strcmp (argv[0], "program") == 0);
505           ASSERT (strcmp (argv[1], "donald") == 0);
506           ASSERT (strcmp (argv[2], "-p") == 0);
507           ASSERT (strcmp (argv[3], "billy") == 0);
508           ASSERT (strcmp (argv[4], "duck") == 0);
509           ASSERT (strcmp (argv[5], "-a") == 0);
510           ASSERT (strcmp (argv[6], "--") == 0);
511           ASSERT (strcmp (argv[7], "-b") == 0);
512           ASSERT (strcmp (argv[8], "foo") == 0);
513           ASSERT (strcmp (argv[9], "-q") == 0);
514           ASSERT (strcmp (argv[10], "johnny") == 0);
515           ASSERT (strcmp (argv[11], "bar") == 0);
516           ASSERT (argv[12] == NULL);
517           ASSERT (a_seen == 0);
518           ASSERT (b_seen == 0);
519           ASSERT (p_value == NULL);
520           ASSERT (q_value == NULL);
521           ASSERT (non_options_count == 0);
522           ASSERT (unrecognized == 0);
523           ASSERT (optind == 1);
524         }
525       else
526         {
527           ASSERT (strcmp (argv[0], "program") == 0);
528           ASSERT (strcmp (argv[1], "-p") == 0);
529           ASSERT (strcmp (argv[2], "billy") == 0);
530           ASSERT (strcmp (argv[3], "-a") == 0);
531           ASSERT (strcmp (argv[4], "--") == 0);
532           ASSERT (strcmp (argv[5], "donald") == 0);
533           ASSERT (strcmp (argv[6], "duck") == 0);
534           ASSERT (strcmp (argv[7], "-b") == 0);
535           ASSERT (strcmp (argv[8], "foo") == 0);
536           ASSERT (strcmp (argv[9], "-q") == 0);
537           ASSERT (strcmp (argv[10], "johnny") == 0);
538           ASSERT (strcmp (argv[11], "bar") == 0);
539           ASSERT (argv[12] == NULL);
540           ASSERT (a_seen == 1);
541           ASSERT (b_seen == 0);
542           ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
543           ASSERT (q_value == NULL);
544           ASSERT (non_options_count == 0);
545           ASSERT (unrecognized == 0);
546           ASSERT (optind == 5);
547         }
548     }
549
550 #if GNULIB_GETOPT_GNU
551   /* Check that the '-' flag causes non-options to be returned in order.  */
552   for (start = OPTIND_MIN; start <= 1; start++)
553     {
554       int a_seen = 0;
555       int b_seen = 0;
556       const char *p_value = NULL;
557       const char *q_value = NULL;
558       int non_options_count = 0;
559       const char *non_options[10];
560       int unrecognized = 0;
561       int argc = 0;
562       const char *argv[10];
563
564       argv[argc++] = "program";
565       argv[argc++] = "donald";
566       argv[argc++] = "-p";
567       argv[argc++] = "billy";
568       argv[argc++] = "duck";
569       argv[argc++] = "-a";
570       argv[argc++] = "bar";
571       argv[argc] = NULL;
572       optind = start;
573       getopt_loop (argc, argv, "-abp:q:",
574                    &a_seen, &b_seen, &p_value, &q_value,
575                    &non_options_count, non_options, &unrecognized);
576       ASSERT (strcmp (argv[0], "program") == 0);
577       ASSERT (strcmp (argv[1], "donald") == 0);
578       ASSERT (strcmp (argv[2], "-p") == 0);
579       ASSERT (strcmp (argv[3], "billy") == 0);
580       ASSERT (strcmp (argv[4], "duck") == 0);
581       ASSERT (strcmp (argv[5], "-a") == 0);
582       ASSERT (strcmp (argv[6], "bar") == 0);
583       ASSERT (argv[7] == NULL);
584       ASSERT (a_seen == 1);
585       ASSERT (b_seen == 0);
586       ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
587       ASSERT (q_value == NULL);
588       ASSERT (non_options_count == 3);
589       ASSERT (strcmp (non_options[0], "donald") == 0);
590       ASSERT (strcmp (non_options[1], "duck") == 0);
591       ASSERT (strcmp (non_options[2], "bar") == 0);
592       ASSERT (unrecognized == 0);
593       ASSERT (optind == 7);
594     }
595
596   /* Check that '--' ends the argument processing.  */
597   for (start = OPTIND_MIN; start <= 1; start++)
598     {
599       int a_seen = 0;
600       int b_seen = 0;
601       const char *p_value = NULL;
602       const char *q_value = NULL;
603       int non_options_count = 0;
604       const char *non_options[10];
605       int unrecognized = 0;
606       int argc = 0;
607       const char *argv[20];
608
609       argv[argc++] = "program";
610       argv[argc++] = "donald";
611       argv[argc++] = "-p";
612       argv[argc++] = "billy";
613       argv[argc++] = "duck";
614       argv[argc++] = "-a";
615       argv[argc++] = "--";
616       argv[argc++] = "-b";
617       argv[argc++] = "foo";
618       argv[argc++] = "-q";
619       argv[argc++] = "johnny";
620       argv[argc++] = "bar";
621       argv[argc] = NULL;
622       optind = start;
623       getopt_loop (argc, argv, "-abp:q:",
624                    &a_seen, &b_seen, &p_value, &q_value,
625                    &non_options_count, non_options, &unrecognized);
626       ASSERT (strcmp (argv[0], "program") == 0);
627       ASSERT (strcmp (argv[1], "donald") == 0);
628       ASSERT (strcmp (argv[2], "-p") == 0);
629       ASSERT (strcmp (argv[3], "billy") == 0);
630       ASSERT (strcmp (argv[4], "duck") == 0);
631       ASSERT (strcmp (argv[5], "-a") == 0);
632       ASSERT (strcmp (argv[6], "--") == 0);
633       ASSERT (strcmp (argv[7], "-b") == 0);
634       ASSERT (strcmp (argv[8], "foo") == 0);
635       ASSERT (strcmp (argv[9], "-q") == 0);
636       ASSERT (strcmp (argv[10], "johnny") == 0);
637       ASSERT (strcmp (argv[11], "bar") == 0);
638       ASSERT (argv[12] == NULL);
639       ASSERT (a_seen == 1);
640       ASSERT (b_seen == 0);
641       ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
642       ASSERT (q_value == NULL);
643       if (non_options_count == 2)
644         {
645           /* glibc behaviour.  */
646           ASSERT (non_options_count == 2);
647           ASSERT (strcmp (non_options[0], "donald") == 0);
648           ASSERT (strcmp (non_options[1], "duck") == 0);
649           ASSERT (unrecognized == 0);
650           ASSERT (optind == 7);
651         }
652       else
653         {
654           /* Another valid behaviour.  */
655           ASSERT (non_options_count == 7);
656           ASSERT (strcmp (non_options[0], "donald") == 0);
657           ASSERT (strcmp (non_options[1], "duck") == 0);
658           ASSERT (strcmp (non_options[2], "-b") == 0);
659           ASSERT (strcmp (non_options[3], "foo") == 0);
660           ASSERT (strcmp (non_options[4], "-q") == 0);
661           ASSERT (strcmp (non_options[5], "johnny") == 0);
662           ASSERT (strcmp (non_options[6], "bar") == 0);
663           ASSERT (unrecognized == 0);
664           ASSERT (optind == 12);
665         }
666     }
667 #endif
668
669   /* Check that the '-' flag has to come first.  */
670   for (start = OPTIND_MIN; start <= 1; start++)
671     {
672       int a_seen = 0;
673       int b_seen = 0;
674       const char *p_value = NULL;
675       const char *q_value = NULL;
676       int non_options_count = 0;
677       const char *non_options[10];
678       int unrecognized = 0;
679       int argc = 0;
680       const char *argv[10];
681
682       argv[argc++] = "program";
683       argv[argc++] = "donald";
684       argv[argc++] = "-p";
685       argv[argc++] = "billy";
686       argv[argc++] = "duck";
687       argv[argc++] = "-a";
688       argv[argc++] = "bar";
689       argv[argc] = NULL;
690       optind = start;
691       getopt_loop (argc, argv, "abp:q:-",
692                    &a_seen, &b_seen, &p_value, &q_value,
693                    &non_options_count, non_options, &unrecognized);
694       if (posixly)
695         {
696           ASSERT (strcmp (argv[0], "program") == 0);
697           ASSERT (strcmp (argv[1], "donald") == 0);
698           ASSERT (strcmp (argv[2], "-p") == 0);
699           ASSERT (strcmp (argv[3], "billy") == 0);
700           ASSERT (strcmp (argv[4], "duck") == 0);
701           ASSERT (strcmp (argv[5], "-a") == 0);
702           ASSERT (strcmp (argv[6], "bar") == 0);
703           ASSERT (argv[7] == NULL);
704           ASSERT (a_seen == 0);
705           ASSERT (b_seen == 0);
706           ASSERT (p_value == NULL);
707           ASSERT (q_value == NULL);
708           ASSERT (non_options_count == 0);
709           ASSERT (unrecognized == 0);
710           ASSERT (optind == 1);
711         }
712       else
713         {
714           ASSERT (strcmp (argv[0], "program") == 0);
715           ASSERT (strcmp (argv[1], "-p") == 0);
716           ASSERT (strcmp (argv[2], "billy") == 0);
717           ASSERT (strcmp (argv[3], "-a") == 0);
718           ASSERT (strcmp (argv[4], "donald") == 0);
719           ASSERT (strcmp (argv[5], "duck") == 0);
720           ASSERT (strcmp (argv[6], "bar") == 0);
721           ASSERT (argv[7] == NULL);
722           ASSERT (a_seen == 1);
723           ASSERT (b_seen == 0);
724           ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
725           ASSERT (q_value == NULL);
726           ASSERT (non_options_count == 0);
727           ASSERT (unrecognized == 0);
728           ASSERT (optind == 4);
729         }
730     }
731
732   /* Check that the '+' flag causes the first non-option to terminate the
733      loop.  */
734   for (start = OPTIND_MIN; start <= 1; start++)
735     {
736       int a_seen = 0;
737       int b_seen = 0;
738       const char *p_value = NULL;
739       const char *q_value = NULL;
740       int non_options_count = 0;
741       const char *non_options[10];
742       int unrecognized = 0;
743       int argc = 0;
744       const char *argv[10];
745
746       argv[argc++] = "program";
747       argv[argc++] = "donald";
748       argv[argc++] = "-p";
749       argv[argc++] = "billy";
750       argv[argc++] = "duck";
751       argv[argc++] = "-a";
752       argv[argc++] = "bar";
753       argv[argc] = NULL;
754       optind = start;
755       getopt_loop (argc, argv, "+abp:q:",
756                    &a_seen, &b_seen, &p_value, &q_value,
757                    &non_options_count, non_options, &unrecognized);
758       ASSERT (strcmp (argv[0], "program") == 0);
759       ASSERT (strcmp (argv[1], "donald") == 0);
760       ASSERT (strcmp (argv[2], "-p") == 0);
761       ASSERT (strcmp (argv[3], "billy") == 0);
762       ASSERT (strcmp (argv[4], "duck") == 0);
763       ASSERT (strcmp (argv[5], "-a") == 0);
764       ASSERT (strcmp (argv[6], "bar") == 0);
765       ASSERT (argv[7] == NULL);
766       ASSERT (a_seen == 0);
767       ASSERT (b_seen == 0);
768       ASSERT (p_value == NULL);
769       ASSERT (q_value == NULL);
770       ASSERT (non_options_count == 0);
771       ASSERT (unrecognized == 0);
772       ASSERT (optind == 1);
773     }
774   for (start = OPTIND_MIN; start <= 1; start++)
775     {
776       int a_seen = 0;
777       int b_seen = 0;
778       const char *p_value = NULL;
779       const char *q_value = NULL;
780       int non_options_count = 0;
781       const char *non_options[10];
782       int unrecognized = 0;
783       int argc = 0;
784       const char *argv[10];
785
786       argv[argc++] = "program";
787       argv[argc++] = "-+";
788       argv[argc] = NULL;
789       optind = start;
790       getopt_loop (argc, argv, "+abp:q:",
791                    &a_seen, &b_seen, &p_value, &q_value,
792                    &non_options_count, non_options, &unrecognized);
793       ASSERT (a_seen == 0);
794       ASSERT (b_seen == 0);
795       ASSERT (p_value == NULL);
796       ASSERT (q_value == NULL);
797       ASSERT (non_options_count == 0);
798       ASSERT (unrecognized == '+');
799       ASSERT (optind == 2);
800     }
801
802   /* Check that '--' ends the argument processing.  */
803   for (start = OPTIND_MIN; start <= 1; start++)
804     {
805       int a_seen = 0;
806       int b_seen = 0;
807       const char *p_value = NULL;
808       const char *q_value = NULL;
809       int non_options_count = 0;
810       const char *non_options[10];
811       int unrecognized = 0;
812       int argc = 0;
813       const char *argv[20];
814
815       argv[argc++] = "program";
816       argv[argc++] = "donald";
817       argv[argc++] = "-p";
818       argv[argc++] = "billy";
819       argv[argc++] = "duck";
820       argv[argc++] = "-a";
821       argv[argc++] = "--";
822       argv[argc++] = "-b";
823       argv[argc++] = "foo";
824       argv[argc++] = "-q";
825       argv[argc++] = "johnny";
826       argv[argc++] = "bar";
827       argv[argc] = NULL;
828       optind = start;
829       getopt_loop (argc, argv, "+abp:q:",
830                    &a_seen, &b_seen, &p_value, &q_value,
831                    &non_options_count, non_options, &unrecognized);
832       ASSERT (strcmp (argv[0], "program") == 0);
833       ASSERT (strcmp (argv[1], "donald") == 0);
834       ASSERT (strcmp (argv[2], "-p") == 0);
835       ASSERT (strcmp (argv[3], "billy") == 0);
836       ASSERT (strcmp (argv[4], "duck") == 0);
837       ASSERT (strcmp (argv[5], "-a") == 0);
838       ASSERT (strcmp (argv[6], "--") == 0);
839       ASSERT (strcmp (argv[7], "-b") == 0);
840       ASSERT (strcmp (argv[8], "foo") == 0);
841       ASSERT (strcmp (argv[9], "-q") == 0);
842       ASSERT (strcmp (argv[10], "johnny") == 0);
843       ASSERT (strcmp (argv[11], "bar") == 0);
844       ASSERT (argv[12] == NULL);
845       ASSERT (a_seen == 0);
846       ASSERT (b_seen == 0);
847       ASSERT (p_value == NULL);
848       ASSERT (q_value == NULL);
849       ASSERT (non_options_count == 0);
850       ASSERT (unrecognized == 0);
851       ASSERT (optind = 1);
852     }
853
854   /* Check that the '+' flag has to come first.  */
855   for (start = OPTIND_MIN; start <= 1; start++)
856     {
857       int a_seen = 0;
858       int b_seen = 0;
859       const char *p_value = NULL;
860       const char *q_value = NULL;
861       int non_options_count = 0;
862       const char *non_options[10];
863       int unrecognized = 0;
864       int argc = 0;
865       const char *argv[10];
866
867       argv[argc++] = "program";
868       argv[argc++] = "donald";
869       argv[argc++] = "-p";
870       argv[argc++] = "billy";
871       argv[argc++] = "duck";
872       argv[argc++] = "-a";
873       argv[argc++] = "bar";
874       argv[argc] = NULL;
875       optind = start;
876       getopt_loop (argc, argv, "abp:q:+",
877                    &a_seen, &b_seen, &p_value, &q_value,
878                    &non_options_count, non_options, &unrecognized);
879       if (posixly)
880         {
881           ASSERT (strcmp (argv[0], "program") == 0);
882           ASSERT (strcmp (argv[1], "donald") == 0);
883           ASSERT (strcmp (argv[2], "-p") == 0);
884           ASSERT (strcmp (argv[3], "billy") == 0);
885           ASSERT (strcmp (argv[4], "duck") == 0);
886           ASSERT (strcmp (argv[5], "-a") == 0);
887           ASSERT (strcmp (argv[6], "bar") == 0);
888           ASSERT (argv[7] == NULL);
889           ASSERT (a_seen == 0);
890           ASSERT (b_seen == 0);
891           ASSERT (p_value == NULL);
892           ASSERT (q_value == NULL);
893           ASSERT (non_options_count == 0);
894           ASSERT (unrecognized == 0);
895           ASSERT (optind == 1);
896         }
897       else
898         {
899           ASSERT (strcmp (argv[0], "program") == 0);
900           ASSERT (strcmp (argv[1], "-p") == 0);
901           ASSERT (strcmp (argv[2], "billy") == 0);
902           ASSERT (strcmp (argv[3], "-a") == 0);
903           ASSERT (strcmp (argv[4], "donald") == 0);
904           ASSERT (strcmp (argv[5], "duck") == 0);
905           ASSERT (strcmp (argv[6], "bar") == 0);
906           ASSERT (argv[7] == NULL);
907           ASSERT (a_seen == 1);
908           ASSERT (b_seen == 0);
909           ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
910           ASSERT (q_value == NULL);
911           ASSERT (non_options_count == 0);
912           ASSERT (unrecognized == 0);
913           ASSERT (optind == 4);
914         }
915     }
916 }