maint: update copyright
[gnulib.git] / tests / test-getopt.h
1 /* Test of command line argument processing.
2    Copyright (C) 2009-2014 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 /* The glibc/gnulib implementation of getopt supports setting optind =
22    0, but not all other implementations do.  This matters for getopt.
23    But for getopt_long, we require GNU compatibility.  */
24 #if defined __GETOPT_PREFIX || (__GLIBC__ >= 2 && !defined __UCLIBC__)
25 # define OPTIND_MIN 0
26 #elif HAVE_DECL_OPTRESET
27 # define OPTIND_MIN (optreset = 1)
28 #else
29 # define OPTIND_MIN 1
30 #endif
31
32 static void
33 getopt_loop (int argc, const char **argv,
34              const char *options,
35              int *a_seen, int *b_seen,
36              const char **p_value, const char **q_value,
37              int *non_options_count, const char **non_options,
38              int *unrecognized, bool *message_issued)
39 {
40   int c;
41   int pos = ftell (stderr);
42
43   while ((c = getopt (argc, (char **) argv, options)) != -1)
44     {
45       switch (c)
46         {
47         case 'a':
48           (*a_seen)++;
49           break;
50         case 'b':
51           (*b_seen)++;
52           break;
53         case 'p':
54           *p_value = optarg;
55           break;
56         case 'q':
57           *q_value = optarg;
58           break;
59         case '\1':
60           /* Must only happen with option '-' at the beginning.  */
61           ASSERT (options[0] == '-');
62           non_options[(*non_options_count)++] = optarg;
63           break;
64         case ':':
65           /* Must only happen with option ':' at the beginning.  */
66           ASSERT (options[0] == ':'
67                   || ((options[0] == '-' || options[0] == '+')
68                       && options[1] == ':'));
69           /* fall through */
70         case '?':
71           *unrecognized = optopt;
72           break;
73         default:
74           *unrecognized = c;
75           break;
76         }
77     }
78
79   *message_issued = pos < ftell (stderr);
80 }
81
82 static void
83 test_getopt (void)
84 {
85   int start;
86   bool posixly = !!getenv ("POSIXLY_CORRECT");
87   /* See comment in getopt.c:
88      glibc gets a LSB-compliant getopt.
89      Standalone applications get a POSIX-compliant getopt.  */
90 #if defined __GETOPT_PREFIX || !(__GLIBC__ >= 2 || defined __MINGW32__)
91   /* Using getopt from gnulib or from a non-glibc system.  */
92   posixly = true;
93 #endif
94
95   /* Test processing of boolean options.  */
96   for (start = OPTIND_MIN; start <= 1; start++)
97     {
98       int a_seen = 0;
99       int b_seen = 0;
100       const char *p_value = NULL;
101       const char *q_value = NULL;
102       int non_options_count = 0;
103       const char *non_options[10];
104       int unrecognized = 0;
105       bool output;
106       int argc = 0;
107       const char *argv[10];
108
109       argv[argc++] = "program";
110       argv[argc++] = "-a";
111       argv[argc++] = "foo";
112       argv[argc++] = "bar";
113       argv[argc] = NULL;
114       optind = start;
115       opterr = 1;
116       getopt_loop (argc, argv, "ab",
117                    &a_seen, &b_seen, &p_value, &q_value,
118                    &non_options_count, non_options, &unrecognized, &output);
119       ASSERT (a_seen == 1);
120       ASSERT (b_seen == 0);
121       ASSERT (p_value == NULL);
122       ASSERT (q_value == NULL);
123       ASSERT (non_options_count == 0);
124       ASSERT (unrecognized == 0);
125       ASSERT (optind == 2);
126       ASSERT (!output);
127     }
128   for (start = OPTIND_MIN; start <= 1; start++)
129     {
130       int a_seen = 0;
131       int b_seen = 0;
132       const char *p_value = NULL;
133       const char *q_value = NULL;
134       int non_options_count = 0;
135       const char *non_options[10];
136       int unrecognized = 0;
137       bool output;
138       int argc = 0;
139       const char *argv[10];
140
141       argv[argc++] = "program";
142       argv[argc++] = "-b";
143       argv[argc++] = "-a";
144       argv[argc++] = "foo";
145       argv[argc++] = "bar";
146       argv[argc] = NULL;
147       optind = start;
148       opterr = 1;
149       getopt_loop (argc, argv, "ab",
150                    &a_seen, &b_seen, &p_value, &q_value,
151                    &non_options_count, non_options, &unrecognized, &output);
152       ASSERT (a_seen == 1);
153       ASSERT (b_seen == 1);
154       ASSERT (p_value == NULL);
155       ASSERT (q_value == NULL);
156       ASSERT (non_options_count == 0);
157       ASSERT (unrecognized == 0);
158       ASSERT (optind == 3);
159       ASSERT (!output);
160     }
161   for (start = OPTIND_MIN; start <= 1; start++)
162     {
163       int a_seen = 0;
164       int b_seen = 0;
165       const char *p_value = NULL;
166       const char *q_value = NULL;
167       int non_options_count = 0;
168       const char *non_options[10];
169       int unrecognized = 0;
170       bool output;
171       int argc = 0;
172       const char *argv[10];
173
174       argv[argc++] = "program";
175       argv[argc++] = "-ba";
176       argv[argc++] = "foo";
177       argv[argc++] = "bar";
178       argv[argc] = NULL;
179       optind = start;
180       opterr = 1;
181       getopt_loop (argc, argv, "ab",
182                    &a_seen, &b_seen, &p_value, &q_value,
183                    &non_options_count, non_options, &unrecognized, &output);
184       ASSERT (a_seen == 1);
185       ASSERT (b_seen == 1);
186       ASSERT (p_value == NULL);
187       ASSERT (q_value == NULL);
188       ASSERT (non_options_count == 0);
189       ASSERT (unrecognized == 0);
190       ASSERT (optind == 2);
191       ASSERT (!output);
192     }
193   for (start = OPTIND_MIN; start <= 1; start++)
194     {
195       int a_seen = 0;
196       int b_seen = 0;
197       const char *p_value = NULL;
198       const char *q_value = NULL;
199       int non_options_count = 0;
200       const char *non_options[10];
201       int unrecognized = 0;
202       bool output;
203       int argc = 0;
204       const char *argv[10];
205
206       argv[argc++] = "program";
207       argv[argc++] = "-ab";
208       argv[argc++] = "-a";
209       argv[argc++] = "foo";
210       argv[argc++] = "bar";
211       argv[argc] = NULL;
212       optind = start;
213       opterr = 1;
214       getopt_loop (argc, argv, "ab",
215                    &a_seen, &b_seen, &p_value, &q_value,
216                    &non_options_count, non_options, &unrecognized, &output);
217       ASSERT (a_seen == 2);
218       ASSERT (b_seen == 1);
219       ASSERT (p_value == NULL);
220       ASSERT (q_value == NULL);
221       ASSERT (non_options_count == 0);
222       ASSERT (unrecognized == 0);
223       ASSERT (optind == 3);
224       ASSERT (!output);
225     }
226
227   /* Test processing of options with arguments.  */
228   for (start = OPTIND_MIN; start <= 1; start++)
229     {
230       int a_seen = 0;
231       int b_seen = 0;
232       const char *p_value = NULL;
233       const char *q_value = NULL;
234       int non_options_count = 0;
235       const char *non_options[10];
236       int unrecognized = 0;
237       bool output;
238       int argc = 0;
239       const char *argv[10];
240
241       argv[argc++] = "program";
242       argv[argc++] = "-pfoo";
243       argv[argc++] = "bar";
244       argv[argc] = NULL;
245       optind = start;
246       opterr = 1;
247       getopt_loop (argc, argv, "p:q:",
248                    &a_seen, &b_seen, &p_value, &q_value,
249                    &non_options_count, non_options, &unrecognized, &output);
250       ASSERT (a_seen == 0);
251       ASSERT (b_seen == 0);
252       ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
253       ASSERT (q_value == NULL);
254       ASSERT (non_options_count == 0);
255       ASSERT (unrecognized == 0);
256       ASSERT (optind == 2);
257       ASSERT (!output);
258     }
259   for (start = OPTIND_MIN; start <= 1; start++)
260     {
261       int a_seen = 0;
262       int b_seen = 0;
263       const char *p_value = NULL;
264       const char *q_value = NULL;
265       int non_options_count = 0;
266       const char *non_options[10];
267       int unrecognized = 0;
268       bool output;
269       int argc = 0;
270       const char *argv[10];
271
272       argv[argc++] = "program";
273       argv[argc++] = "-p";
274       argv[argc++] = "foo";
275       argv[argc++] = "bar";
276       argv[argc] = NULL;
277       optind = start;
278       opterr = 1;
279       getopt_loop (argc, argv, "p:q:",
280                    &a_seen, &b_seen, &p_value, &q_value,
281                    &non_options_count, non_options, &unrecognized, &output);
282       ASSERT (a_seen == 0);
283       ASSERT (b_seen == 0);
284       ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
285       ASSERT (q_value == NULL);
286       ASSERT (non_options_count == 0);
287       ASSERT (unrecognized == 0);
288       ASSERT (optind == 3);
289       ASSERT (!output);
290     }
291   for (start = OPTIND_MIN; start <= 1; start++)
292     {
293       int a_seen = 0;
294       int b_seen = 0;
295       const char *p_value = NULL;
296       const char *q_value = NULL;
297       int non_options_count = 0;
298       const char *non_options[10];
299       int unrecognized = 0;
300       bool output;
301       int argc = 0;
302       const char *argv[10];
303
304       argv[argc++] = "program";
305       argv[argc++] = "-ab";
306       argv[argc++] = "-q";
307       argv[argc++] = "baz";
308       argv[argc++] = "-pfoo";
309       argv[argc++] = "bar";
310       argv[argc] = NULL;
311       optind = start;
312       opterr = 1;
313       getopt_loop (argc, argv, "abp:q:",
314                    &a_seen, &b_seen, &p_value, &q_value,
315                    &non_options_count, non_options, &unrecognized, &output);
316       ASSERT (a_seen == 1);
317       ASSERT (b_seen == 1);
318       ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
319       ASSERT (q_value != NULL && strcmp (q_value, "baz") == 0);
320       ASSERT (non_options_count == 0);
321       ASSERT (unrecognized == 0);
322       ASSERT (optind == 5);
323       ASSERT (!output);
324     }
325
326 #if GNULIB_TEST_GETOPT_GNU
327   /* Test processing of options with optional arguments.  */
328   for (start = OPTIND_MIN; start <= 1; start++)
329     {
330       int a_seen = 0;
331       int b_seen = 0;
332       const char *p_value = NULL;
333       const char *q_value = NULL;
334       int non_options_count = 0;
335       const char *non_options[10];
336       int unrecognized = 0;
337       bool output;
338       int argc = 0;
339       const char *argv[10];
340
341       argv[argc++] = "program";
342       argv[argc++] = "-pfoo";
343       argv[argc++] = "bar";
344       argv[argc] = NULL;
345       optind = start;
346       opterr = 1;
347       getopt_loop (argc, argv, "p::q::",
348                    &a_seen, &b_seen, &p_value, &q_value,
349                    &non_options_count, non_options, &unrecognized, &output);
350       ASSERT (a_seen == 0);
351       ASSERT (b_seen == 0);
352       ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
353       ASSERT (q_value == NULL);
354       ASSERT (non_options_count == 0);
355       ASSERT (unrecognized == 0);
356       ASSERT (optind == 2);
357       ASSERT (!output);
358     }
359   for (start = OPTIND_MIN; start <= 1; start++)
360     {
361       int a_seen = 0;
362       int b_seen = 0;
363       const char *p_value = NULL;
364       const char *q_value = NULL;
365       int non_options_count = 0;
366       const char *non_options[10];
367       int unrecognized = 0;
368       bool output;
369       int argc = 0;
370       const char *argv[10];
371
372       argv[argc++] = "program";
373       argv[argc++] = "-p";
374       argv[argc++] = "foo";
375       argv[argc++] = "bar";
376       argv[argc] = NULL;
377       optind = start;
378       opterr = 1;
379       getopt_loop (argc, argv, "p::q::",
380                    &a_seen, &b_seen, &p_value, &q_value,
381                    &non_options_count, non_options, &unrecognized, &output);
382       ASSERT (a_seen == 0);
383       ASSERT (b_seen == 0);
384       ASSERT (p_value == NULL);
385       ASSERT (q_value == NULL);
386       ASSERT (non_options_count == 0);
387       ASSERT (unrecognized == 0);
388       ASSERT (optind == 2);
389       ASSERT (!output);
390     }
391   for (start = OPTIND_MIN; start <= 1; start++)
392     {
393       int a_seen = 0;
394       int b_seen = 0;
395       const char *p_value = NULL;
396       const char *q_value = NULL;
397       int non_options_count = 0;
398       const char *non_options[10];
399       int unrecognized = 0;
400       bool output;
401       int argc = 0;
402       const char *argv[10];
403
404       argv[argc++] = "program";
405       argv[argc++] = "-p";
406       argv[argc++] = "-a";
407       argv[argc++] = "bar";
408       argv[argc] = NULL;
409       optind = start;
410       opterr = 1;
411       getopt_loop (argc, argv, "abp::q::",
412                    &a_seen, &b_seen, &p_value, &q_value,
413                    &non_options_count, non_options, &unrecognized, &output);
414       ASSERT (a_seen == 1);
415       ASSERT (b_seen == 0);
416       ASSERT (p_value == NULL);
417       ASSERT (q_value == NULL);
418       ASSERT (non_options_count == 0);
419       ASSERT (unrecognized == 0);
420       ASSERT (optind == 3);
421       ASSERT (!output);
422     }
423 #endif /* GNULIB_TEST_GETOPT_GNU */
424
425   /* Check that invalid options are recognized; and that both opterr
426      and leading ':' can silence output.  */
427   for (start = OPTIND_MIN; start <= 1; start++)
428     {
429       int a_seen = 0;
430       int b_seen = 0;
431       const char *p_value = NULL;
432       const char *q_value = NULL;
433       int non_options_count = 0;
434       const char *non_options[10];
435       int unrecognized = 0;
436       bool output;
437       int argc = 0;
438       const char *argv[10];
439
440       argv[argc++] = "program";
441       argv[argc++] = "-p";
442       argv[argc++] = "foo";
443       argv[argc++] = "-x";
444       argv[argc++] = "-a";
445       argv[argc++] = "bar";
446       argv[argc] = NULL;
447       optind = start;
448       opterr = 42;
449       getopt_loop (argc, argv, "abp:q:",
450                    &a_seen, &b_seen, &p_value, &q_value,
451                    &non_options_count, non_options, &unrecognized, &output);
452       ASSERT (a_seen == 1);
453       ASSERT (b_seen == 0);
454       ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
455       ASSERT (q_value == NULL);
456       ASSERT (non_options_count == 0);
457       ASSERT (unrecognized == 'x');
458       ASSERT (optind == 5);
459       ASSERT (output);
460     }
461   for (start = OPTIND_MIN; start <= 1; start++)
462     {
463       int a_seen = 0;
464       int b_seen = 0;
465       const char *p_value = NULL;
466       const char *q_value = NULL;
467       int non_options_count = 0;
468       const char *non_options[10];
469       int unrecognized = 0;
470       bool output;
471       int argc = 0;
472       const char *argv[10];
473
474       argv[argc++] = "program";
475       argv[argc++] = "-p";
476       argv[argc++] = "foo";
477       argv[argc++] = "-x";
478       argv[argc++] = "-a";
479       argv[argc++] = "bar";
480       argv[argc] = NULL;
481       optind = start;
482       opterr = 0;
483       getopt_loop (argc, argv, "abp:q:",
484                    &a_seen, &b_seen, &p_value, &q_value,
485                    &non_options_count, non_options, &unrecognized, &output);
486       ASSERT (a_seen == 1);
487       ASSERT (b_seen == 0);
488       ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
489       ASSERT (q_value == NULL);
490       ASSERT (non_options_count == 0);
491       ASSERT (unrecognized == 'x');
492       ASSERT (optind == 5);
493       ASSERT (!output);
494     }
495   for (start = OPTIND_MIN; start <= 1; start++)
496     {
497       int a_seen = 0;
498       int b_seen = 0;
499       const char *p_value = NULL;
500       const char *q_value = NULL;
501       int non_options_count = 0;
502       const char *non_options[10];
503       int unrecognized = 0;
504       bool output;
505       int argc = 0;
506       const char *argv[10];
507
508       argv[argc++] = "program";
509       argv[argc++] = "-p";
510       argv[argc++] = "foo";
511       argv[argc++] = "-x";
512       argv[argc++] = "-a";
513       argv[argc++] = "bar";
514       argv[argc] = NULL;
515       optind = start;
516       opterr = 1;
517       getopt_loop (argc, argv, ":abp:q:",
518                    &a_seen, &b_seen, &p_value, &q_value,
519                    &non_options_count, non_options, &unrecognized, &output);
520       ASSERT (a_seen == 1);
521       ASSERT (b_seen == 0);
522       ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
523       ASSERT (q_value == NULL);
524       ASSERT (non_options_count == 0);
525       ASSERT (unrecognized == 'x');
526       ASSERT (optind == 5);
527       ASSERT (!output);
528     }
529   for (start = OPTIND_MIN; start <= 1; start++)
530     {
531       int a_seen = 0;
532       int b_seen = 0;
533       const char *p_value = NULL;
534       const char *q_value = NULL;
535       int non_options_count = 0;
536       const char *non_options[10];
537       int unrecognized = 0;
538       bool output;
539       int argc = 0;
540       const char *argv[10];
541
542       argv[argc++] = "program";
543       argv[argc++] = "-p";
544       argv[argc++] = "foo";
545       argv[argc++] = "-:";
546       argv[argc++] = "-a";
547       argv[argc++] = "bar";
548       argv[argc] = NULL;
549       optind = start;
550       opterr = 42;
551       getopt_loop (argc, argv, "abp:q:",
552                    &a_seen, &b_seen, &p_value, &q_value,
553                    &non_options_count, non_options, &unrecognized, &output);
554       ASSERT (a_seen == 1);
555       ASSERT (b_seen == 0);
556       ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
557       ASSERT (q_value == NULL);
558       ASSERT (non_options_count == 0);
559       ASSERT (unrecognized == ':');
560       ASSERT (optind == 5);
561       ASSERT (output);
562     }
563   for (start = OPTIND_MIN; start <= 1; start++)
564     {
565       int a_seen = 0;
566       int b_seen = 0;
567       const char *p_value = NULL;
568       const char *q_value = NULL;
569       int non_options_count = 0;
570       const char *non_options[10];
571       int unrecognized = 0;
572       bool output;
573       int argc = 0;
574       const char *argv[10];
575
576       argv[argc++] = "program";
577       argv[argc++] = "-p";
578       argv[argc++] = "foo";
579       argv[argc++] = "-:";
580       argv[argc++] = "-a";
581       argv[argc++] = "bar";
582       argv[argc] = NULL;
583       optind = start;
584       opterr = 0;
585       getopt_loop (argc, argv, "abp:q:",
586                    &a_seen, &b_seen, &p_value, &q_value,
587                    &non_options_count, non_options, &unrecognized, &output);
588       ASSERT (a_seen == 1);
589       ASSERT (b_seen == 0);
590       ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
591       ASSERT (q_value == NULL);
592       ASSERT (non_options_count == 0);
593       ASSERT (unrecognized == ':');
594       ASSERT (optind == 5);
595       ASSERT (!output);
596     }
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       bool output;
607       int argc = 0;
608       const char *argv[10];
609
610       argv[argc++] = "program";
611       argv[argc++] = "-p";
612       argv[argc++] = "foo";
613       argv[argc++] = "-:";
614       argv[argc++] = "-a";
615       argv[argc++] = "bar";
616       argv[argc] = NULL;
617       optind = start;
618       opterr = 1;
619       getopt_loop (argc, argv, ":abp:q:",
620                    &a_seen, &b_seen, &p_value, &q_value,
621                    &non_options_count, non_options, &unrecognized, &output);
622       ASSERT (a_seen == 1);
623       ASSERT (b_seen == 0);
624       ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
625       ASSERT (q_value == NULL);
626       ASSERT (non_options_count == 0);
627       ASSERT (unrecognized == ':');
628       ASSERT (optind == 5);
629       ASSERT (!output);
630     }
631
632   /* Check for missing argument behavior.  */
633   for (start = OPTIND_MIN; start <= 1; start++)
634     {
635       int a_seen = 0;
636       int b_seen = 0;
637       const char *p_value = NULL;
638       const char *q_value = NULL;
639       int non_options_count = 0;
640       const char *non_options[10];
641       int unrecognized = 0;
642       bool output;
643       int argc = 0;
644       const char *argv[10];
645
646       argv[argc++] = "program";
647       argv[argc++] = "-ap";
648       argv[argc] = NULL;
649       optind = start;
650       opterr = 1;
651       getopt_loop (argc, argv, "abp:q:",
652                    &a_seen, &b_seen, &p_value, &q_value,
653                    &non_options_count, non_options, &unrecognized, &output);
654       ASSERT (a_seen == 1);
655       ASSERT (b_seen == 0);
656       ASSERT (p_value == NULL);
657       ASSERT (q_value == NULL);
658       ASSERT (non_options_count == 0);
659       ASSERT (unrecognized == 'p');
660       ASSERT (optind == 2);
661       ASSERT (output);
662     }
663   for (start = OPTIND_MIN; start <= 1; start++)
664     {
665       int a_seen = 0;
666       int b_seen = 0;
667       const char *p_value = NULL;
668       const char *q_value = NULL;
669       int non_options_count = 0;
670       const char *non_options[10];
671       int unrecognized = 0;
672       bool output;
673       int argc = 0;
674       const char *argv[10];
675
676       argv[argc++] = "program";
677       argv[argc++] = "-ap";
678       argv[argc] = NULL;
679       optind = start;
680       opterr = 0;
681       getopt_loop (argc, argv, "abp:q:",
682                    &a_seen, &b_seen, &p_value, &q_value,
683                    &non_options_count, non_options, &unrecognized, &output);
684       ASSERT (a_seen == 1);
685       ASSERT (b_seen == 0);
686       ASSERT (p_value == NULL);
687       ASSERT (q_value == NULL);
688       ASSERT (non_options_count == 0);
689       ASSERT (unrecognized == 'p');
690       ASSERT (optind == 2);
691       ASSERT (!output);
692     }
693   for (start = OPTIND_MIN; start <= 1; start++)
694     {
695       int a_seen = 0;
696       int b_seen = 0;
697       const char *p_value = NULL;
698       const char *q_value = NULL;
699       int non_options_count = 0;
700       const char *non_options[10];
701       int unrecognized = 0;
702       bool output;
703       int argc = 0;
704       const char *argv[10];
705
706       argv[argc++] = "program";
707       argv[argc++] = "-ap";
708       argv[argc] = NULL;
709       optind = start;
710       opterr = 1;
711       getopt_loop (argc, argv, ":abp:q:",
712                    &a_seen, &b_seen, &p_value, &q_value,
713                    &non_options_count, non_options, &unrecognized, &output);
714       ASSERT (a_seen == 1);
715       ASSERT (b_seen == 0);
716       ASSERT (p_value == NULL);
717       ASSERT (q_value == NULL);
718       ASSERT (non_options_count == 0);
719       ASSERT (unrecognized == 'p');
720       ASSERT (optind == 2);
721       ASSERT (!output);
722     }
723
724   /* Check that by default, non-options arguments are moved to the end.  */
725   for (start = OPTIND_MIN; start <= 1; start++)
726     {
727       int a_seen = 0;
728       int b_seen = 0;
729       const char *p_value = NULL;
730       const char *q_value = NULL;
731       int non_options_count = 0;
732       const char *non_options[10];
733       int unrecognized = 0;
734       bool output;
735       int argc = 0;
736       const char *argv[10];
737
738       argv[argc++] = "program";
739       argv[argc++] = "donald";
740       argv[argc++] = "-p";
741       argv[argc++] = "billy";
742       argv[argc++] = "duck";
743       argv[argc++] = "-a";
744       argv[argc++] = "bar";
745       argv[argc] = NULL;
746       optind = start;
747       opterr = 1;
748       getopt_loop (argc, argv, "abp:q:",
749                    &a_seen, &b_seen, &p_value, &q_value,
750                    &non_options_count, non_options, &unrecognized, &output);
751       if (posixly)
752         {
753           ASSERT (strcmp (argv[0], "program") == 0);
754           ASSERT (strcmp (argv[1], "donald") == 0);
755           ASSERT (strcmp (argv[2], "-p") == 0);
756           ASSERT (strcmp (argv[3], "billy") == 0);
757           ASSERT (strcmp (argv[4], "duck") == 0);
758           ASSERT (strcmp (argv[5], "-a") == 0);
759           ASSERT (strcmp (argv[6], "bar") == 0);
760           ASSERT (argv[7] == NULL);
761           ASSERT (a_seen == 0);
762           ASSERT (b_seen == 0);
763           ASSERT (p_value == NULL);
764           ASSERT (q_value == NULL);
765           ASSERT (non_options_count == 0);
766           ASSERT (unrecognized == 0);
767           ASSERT (optind == 1);
768           ASSERT (!output);
769         }
770       else
771         {
772           ASSERT (strcmp (argv[0], "program") == 0);
773           ASSERT (strcmp (argv[1], "-p") == 0);
774           ASSERT (strcmp (argv[2], "billy") == 0);
775           ASSERT (strcmp (argv[3], "-a") == 0);
776           ASSERT (strcmp (argv[4], "donald") == 0);
777           ASSERT (strcmp (argv[5], "duck") == 0);
778           ASSERT (strcmp (argv[6], "bar") == 0);
779           ASSERT (argv[7] == NULL);
780           ASSERT (a_seen == 1);
781           ASSERT (b_seen == 0);
782           ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
783           ASSERT (q_value == NULL);
784           ASSERT (non_options_count == 0);
785           ASSERT (unrecognized == 0);
786           ASSERT (optind == 4);
787           ASSERT (!output);
788         }
789     }
790
791   /* Check that '--' ends the argument processing.  */
792   for (start = OPTIND_MIN; start <= 1; start++)
793     {
794       int a_seen = 0;
795       int b_seen = 0;
796       const char *p_value = NULL;
797       const char *q_value = NULL;
798       int non_options_count = 0;
799       const char *non_options[10];
800       int unrecognized = 0;
801       bool output;
802       int argc = 0;
803       const char *argv[20];
804
805       argv[argc++] = "program";
806       argv[argc++] = "donald";
807       argv[argc++] = "-p";
808       argv[argc++] = "billy";
809       argv[argc++] = "duck";
810       argv[argc++] = "-a";
811       argv[argc++] = "--";
812       argv[argc++] = "-b";
813       argv[argc++] = "foo";
814       argv[argc++] = "-q";
815       argv[argc++] = "johnny";
816       argv[argc++] = "bar";
817       argv[argc] = NULL;
818       optind = start;
819       opterr = 1;
820       getopt_loop (argc, argv, "abp:q:",
821                    &a_seen, &b_seen, &p_value, &q_value,
822                    &non_options_count, non_options, &unrecognized, &output);
823       if (posixly)
824         {
825           ASSERT (strcmp (argv[0], "program") == 0);
826           ASSERT (strcmp (argv[1], "donald") == 0);
827           ASSERT (strcmp (argv[2], "-p") == 0);
828           ASSERT (strcmp (argv[3], "billy") == 0);
829           ASSERT (strcmp (argv[4], "duck") == 0);
830           ASSERT (strcmp (argv[5], "-a") == 0);
831           ASSERT (strcmp (argv[6], "--") == 0);
832           ASSERT (strcmp (argv[7], "-b") == 0);
833           ASSERT (strcmp (argv[8], "foo") == 0);
834           ASSERT (strcmp (argv[9], "-q") == 0);
835           ASSERT (strcmp (argv[10], "johnny") == 0);
836           ASSERT (strcmp (argv[11], "bar") == 0);
837           ASSERT (argv[12] == NULL);
838           ASSERT (a_seen == 0);
839           ASSERT (b_seen == 0);
840           ASSERT (p_value == NULL);
841           ASSERT (q_value == NULL);
842           ASSERT (non_options_count == 0);
843           ASSERT (unrecognized == 0);
844           ASSERT (optind == 1);
845           ASSERT (!output);
846         }
847       else
848         {
849           ASSERT (strcmp (argv[0], "program") == 0);
850           ASSERT (strcmp (argv[1], "-p") == 0);
851           ASSERT (strcmp (argv[2], "billy") == 0);
852           ASSERT (strcmp (argv[3], "-a") == 0);
853           ASSERT (strcmp (argv[4], "--") == 0);
854           ASSERT (strcmp (argv[5], "donald") == 0);
855           ASSERT (strcmp (argv[6], "duck") == 0);
856           ASSERT (strcmp (argv[7], "-b") == 0);
857           ASSERT (strcmp (argv[8], "foo") == 0);
858           ASSERT (strcmp (argv[9], "-q") == 0);
859           ASSERT (strcmp (argv[10], "johnny") == 0);
860           ASSERT (strcmp (argv[11], "bar") == 0);
861           ASSERT (argv[12] == NULL);
862           ASSERT (a_seen == 1);
863           ASSERT (b_seen == 0);
864           ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
865           ASSERT (q_value == NULL);
866           ASSERT (non_options_count == 0);
867           ASSERT (unrecognized == 0);
868           ASSERT (optind == 5);
869           ASSERT (!output);
870         }
871     }
872
873 #if GNULIB_TEST_GETOPT_GNU
874   /* Check that the '-' flag causes non-options to be returned in order.  */
875   for (start = OPTIND_MIN; start <= 1; start++)
876     {
877       int a_seen = 0;
878       int b_seen = 0;
879       const char *p_value = NULL;
880       const char *q_value = NULL;
881       int non_options_count = 0;
882       const char *non_options[10];
883       int unrecognized = 0;
884       bool output;
885       int argc = 0;
886       const char *argv[10];
887
888       argv[argc++] = "program";
889       argv[argc++] = "donald";
890       argv[argc++] = "-p";
891       argv[argc++] = "billy";
892       argv[argc++] = "duck";
893       argv[argc++] = "-a";
894       argv[argc++] = "bar";
895       argv[argc] = NULL;
896       optind = start;
897       opterr = 1;
898       getopt_loop (argc, argv, "-abp:q:",
899                    &a_seen, &b_seen, &p_value, &q_value,
900                    &non_options_count, non_options, &unrecognized, &output);
901       ASSERT (strcmp (argv[0], "program") == 0);
902       ASSERT (strcmp (argv[1], "donald") == 0);
903       ASSERT (strcmp (argv[2], "-p") == 0);
904       ASSERT (strcmp (argv[3], "billy") == 0);
905       ASSERT (strcmp (argv[4], "duck") == 0);
906       ASSERT (strcmp (argv[5], "-a") == 0);
907       ASSERT (strcmp (argv[6], "bar") == 0);
908       ASSERT (argv[7] == NULL);
909       ASSERT (a_seen == 1);
910       ASSERT (b_seen == 0);
911       ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
912       ASSERT (q_value == NULL);
913       ASSERT (non_options_count == 3);
914       ASSERT (strcmp (non_options[0], "donald") == 0);
915       ASSERT (strcmp (non_options[1], "duck") == 0);
916       ASSERT (strcmp (non_options[2], "bar") == 0);
917       ASSERT (unrecognized == 0);
918       ASSERT (optind == 7);
919       ASSERT (!output);
920     }
921
922   /* Check that '--' ends the argument processing.  */
923   for (start = OPTIND_MIN; start <= 1; start++)
924     {
925       int a_seen = 0;
926       int b_seen = 0;
927       const char *p_value = NULL;
928       const char *q_value = NULL;
929       int non_options_count = 0;
930       const char *non_options[10];
931       int unrecognized = 0;
932       bool output;
933       int argc = 0;
934       const char *argv[20];
935
936       argv[argc++] = "program";
937       argv[argc++] = "donald";
938       argv[argc++] = "-p";
939       argv[argc++] = "billy";
940       argv[argc++] = "duck";
941       argv[argc++] = "-a";
942       argv[argc++] = "--";
943       argv[argc++] = "-b";
944       argv[argc++] = "foo";
945       argv[argc++] = "-q";
946       argv[argc++] = "johnny";
947       argv[argc++] = "bar";
948       argv[argc] = NULL;
949       optind = start;
950       opterr = 1;
951       getopt_loop (argc, argv, "-abp:q:",
952                    &a_seen, &b_seen, &p_value, &q_value,
953                    &non_options_count, non_options, &unrecognized, &output);
954       ASSERT (strcmp (argv[0], "program") == 0);
955       ASSERT (strcmp (argv[1], "donald") == 0);
956       ASSERT (strcmp (argv[2], "-p") == 0);
957       ASSERT (strcmp (argv[3], "billy") == 0);
958       ASSERT (strcmp (argv[4], "duck") == 0);
959       ASSERT (strcmp (argv[5], "-a") == 0);
960       ASSERT (strcmp (argv[6], "--") == 0);
961       ASSERT (strcmp (argv[7], "-b") == 0);
962       ASSERT (strcmp (argv[8], "foo") == 0);
963       ASSERT (strcmp (argv[9], "-q") == 0);
964       ASSERT (strcmp (argv[10], "johnny") == 0);
965       ASSERT (strcmp (argv[11], "bar") == 0);
966       ASSERT (argv[12] == NULL);
967       ASSERT (a_seen == 1);
968       ASSERT (b_seen == 0);
969       ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
970       ASSERT (q_value == NULL);
971       ASSERT (!output);
972       if (non_options_count == 2)
973         {
974           /* glibc behaviour.  */
975           ASSERT (non_options_count == 2);
976           ASSERT (strcmp (non_options[0], "donald") == 0);
977           ASSERT (strcmp (non_options[1], "duck") == 0);
978           ASSERT (unrecognized == 0);
979           ASSERT (optind == 7);
980         }
981       else
982         {
983           /* Another valid behaviour.  */
984           ASSERT (non_options_count == 7);
985           ASSERT (strcmp (non_options[0], "donald") == 0);
986           ASSERT (strcmp (non_options[1], "duck") == 0);
987           ASSERT (strcmp (non_options[2], "-b") == 0);
988           ASSERT (strcmp (non_options[3], "foo") == 0);
989           ASSERT (strcmp (non_options[4], "-q") == 0);
990           ASSERT (strcmp (non_options[5], "johnny") == 0);
991           ASSERT (strcmp (non_options[6], "bar") == 0);
992           ASSERT (unrecognized == 0);
993           ASSERT (optind == 12);
994         }
995     }
996
997   /* Check that the '-' flag has to come first.  */
998   for (start = OPTIND_MIN; start <= 1; start++)
999     {
1000       int a_seen = 0;
1001       int b_seen = 0;
1002       const char *p_value = NULL;
1003       const char *q_value = NULL;
1004       int non_options_count = 0;
1005       const char *non_options[10];
1006       int unrecognized = 0;
1007       bool output;
1008       int argc = 0;
1009       const char *argv[10];
1010
1011       argv[argc++] = "program";
1012       argv[argc++] = "donald";
1013       argv[argc++] = "-p";
1014       argv[argc++] = "billy";
1015       argv[argc++] = "duck";
1016       argv[argc++] = "-a";
1017       argv[argc++] = "bar";
1018       argv[argc] = NULL;
1019       optind = start;
1020       opterr = 1;
1021       getopt_loop (argc, argv, "abp:q:-",
1022                    &a_seen, &b_seen, &p_value, &q_value,
1023                    &non_options_count, non_options, &unrecognized, &output);
1024       if (posixly)
1025         {
1026           ASSERT (strcmp (argv[0], "program") == 0);
1027           ASSERT (strcmp (argv[1], "donald") == 0);
1028           ASSERT (strcmp (argv[2], "-p") == 0);
1029           ASSERT (strcmp (argv[3], "billy") == 0);
1030           ASSERT (strcmp (argv[4], "duck") == 0);
1031           ASSERT (strcmp (argv[5], "-a") == 0);
1032           ASSERT (strcmp (argv[6], "bar") == 0);
1033           ASSERT (argv[7] == NULL);
1034           ASSERT (a_seen == 0);
1035           ASSERT (b_seen == 0);
1036           ASSERT (p_value == NULL);
1037           ASSERT (q_value == NULL);
1038           ASSERT (non_options_count == 0);
1039           ASSERT (unrecognized == 0);
1040           ASSERT (optind == 1);
1041           ASSERT (!output);
1042         }
1043       else
1044         {
1045           ASSERT (strcmp (argv[0], "program") == 0);
1046           ASSERT (strcmp (argv[1], "-p") == 0);
1047           ASSERT (strcmp (argv[2], "billy") == 0);
1048           ASSERT (strcmp (argv[3], "-a") == 0);
1049           ASSERT (strcmp (argv[4], "donald") == 0);
1050           ASSERT (strcmp (argv[5], "duck") == 0);
1051           ASSERT (strcmp (argv[6], "bar") == 0);
1052           ASSERT (argv[7] == NULL);
1053           ASSERT (a_seen == 1);
1054           ASSERT (b_seen == 0);
1055           ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
1056           ASSERT (q_value == NULL);
1057           ASSERT (non_options_count == 0);
1058           ASSERT (unrecognized == 0);
1059           ASSERT (optind == 4);
1060           ASSERT (!output);
1061         }
1062     }
1063
1064   /* Check that the '+' flag causes the first non-option to terminate the
1065      loop.  */
1066   for (start = OPTIND_MIN; start <= 1; start++)
1067     {
1068       int a_seen = 0;
1069       int b_seen = 0;
1070       const char *p_value = NULL;
1071       const char *q_value = NULL;
1072       int non_options_count = 0;
1073       const char *non_options[10];
1074       int unrecognized = 0;
1075       bool output;
1076       int argc = 0;
1077       const char *argv[10];
1078
1079       argv[argc++] = "program";
1080       argv[argc++] = "donald";
1081       argv[argc++] = "-p";
1082       argv[argc++] = "billy";
1083       argv[argc++] = "duck";
1084       argv[argc++] = "-a";
1085       argv[argc++] = "bar";
1086       argv[argc] = NULL;
1087       optind = start;
1088       opterr = 1;
1089       getopt_loop (argc, argv, "+abp:q:",
1090                    &a_seen, &b_seen, &p_value, &q_value,
1091                    &non_options_count, non_options, &unrecognized, &output);
1092       ASSERT (strcmp (argv[0], "program") == 0);
1093       ASSERT (strcmp (argv[1], "donald") == 0);
1094       ASSERT (strcmp (argv[2], "-p") == 0);
1095       ASSERT (strcmp (argv[3], "billy") == 0);
1096       ASSERT (strcmp (argv[4], "duck") == 0);
1097       ASSERT (strcmp (argv[5], "-a") == 0);
1098       ASSERT (strcmp (argv[6], "bar") == 0);
1099       ASSERT (argv[7] == NULL);
1100       ASSERT (a_seen == 0);
1101       ASSERT (b_seen == 0);
1102       ASSERT (p_value == NULL);
1103       ASSERT (q_value == NULL);
1104       ASSERT (non_options_count == 0);
1105       ASSERT (unrecognized == 0);
1106       ASSERT (optind == 1);
1107       ASSERT (!output);
1108     }
1109   for (start = OPTIND_MIN; start <= 1; start++)
1110     {
1111       int a_seen = 0;
1112       int b_seen = 0;
1113       const char *p_value = NULL;
1114       const char *q_value = NULL;
1115       int non_options_count = 0;
1116       const char *non_options[10];
1117       int unrecognized = 0;
1118       bool output;
1119       int argc = 0;
1120       const char *argv[10];
1121
1122       argv[argc++] = "program";
1123       argv[argc++] = "-+";
1124       argv[argc] = NULL;
1125       optind = start;
1126       getopt_loop (argc, argv, "+abp:q:",
1127                    &a_seen, &b_seen, &p_value, &q_value,
1128                    &non_options_count, non_options, &unrecognized, &output);
1129       ASSERT (a_seen == 0);
1130       ASSERT (b_seen == 0);
1131       ASSERT (p_value == NULL);
1132       ASSERT (q_value == NULL);
1133       ASSERT (non_options_count == 0);
1134       ASSERT (unrecognized == '+');
1135       ASSERT (optind == 2);
1136       ASSERT (output);
1137     }
1138
1139   /* Check that '--' ends the argument processing.  */
1140   for (start = OPTIND_MIN; start <= 1; start++)
1141     {
1142       int a_seen = 0;
1143       int b_seen = 0;
1144       const char *p_value = NULL;
1145       const char *q_value = NULL;
1146       int non_options_count = 0;
1147       const char *non_options[10];
1148       int unrecognized = 0;
1149       bool output;
1150       int argc = 0;
1151       const char *argv[20];
1152
1153       argv[argc++] = "program";
1154       argv[argc++] = "donald";
1155       argv[argc++] = "-p";
1156       argv[argc++] = "billy";
1157       argv[argc++] = "duck";
1158       argv[argc++] = "-a";
1159       argv[argc++] = "--";
1160       argv[argc++] = "-b";
1161       argv[argc++] = "foo";
1162       argv[argc++] = "-q";
1163       argv[argc++] = "johnny";
1164       argv[argc++] = "bar";
1165       argv[argc] = NULL;
1166       optind = start;
1167       opterr = 1;
1168       getopt_loop (argc, argv, "+abp:q:",
1169                    &a_seen, &b_seen, &p_value, &q_value,
1170                    &non_options_count, non_options, &unrecognized, &output);
1171       ASSERT (strcmp (argv[0], "program") == 0);
1172       ASSERT (strcmp (argv[1], "donald") == 0);
1173       ASSERT (strcmp (argv[2], "-p") == 0);
1174       ASSERT (strcmp (argv[3], "billy") == 0);
1175       ASSERT (strcmp (argv[4], "duck") == 0);
1176       ASSERT (strcmp (argv[5], "-a") == 0);
1177       ASSERT (strcmp (argv[6], "--") == 0);
1178       ASSERT (strcmp (argv[7], "-b") == 0);
1179       ASSERT (strcmp (argv[8], "foo") == 0);
1180       ASSERT (strcmp (argv[9], "-q") == 0);
1181       ASSERT (strcmp (argv[10], "johnny") == 0);
1182       ASSERT (strcmp (argv[11], "bar") == 0);
1183       ASSERT (argv[12] == NULL);
1184       ASSERT (a_seen == 0);
1185       ASSERT (b_seen == 0);
1186       ASSERT (p_value == NULL);
1187       ASSERT (q_value == NULL);
1188       ASSERT (non_options_count == 0);
1189       ASSERT (unrecognized == 0);
1190       ASSERT (optind == 1);
1191       ASSERT (!output);
1192     }
1193 #endif /* GNULIB_TEST_GETOPT_GNU */
1194
1195   /* Check that the '+' flag has to come first.  */
1196   for (start = OPTIND_MIN; start <= 1; start++)
1197     {
1198       int a_seen = 0;
1199       int b_seen = 0;
1200       const char *p_value = NULL;
1201       const char *q_value = NULL;
1202       int non_options_count = 0;
1203       const char *non_options[10];
1204       int unrecognized = 0;
1205       bool output;
1206       int argc = 0;
1207       const char *argv[10];
1208
1209       argv[argc++] = "program";
1210       argv[argc++] = "donald";
1211       argv[argc++] = "-p";
1212       argv[argc++] = "billy";
1213       argv[argc++] = "duck";
1214       argv[argc++] = "-a";
1215       argv[argc++] = "bar";
1216       argv[argc] = NULL;
1217       optind = start;
1218       opterr = 1;
1219       getopt_loop (argc, argv, "abp:q:+",
1220                    &a_seen, &b_seen, &p_value, &q_value,
1221                    &non_options_count, non_options, &unrecognized, &output);
1222       if (posixly)
1223         {
1224           ASSERT (strcmp (argv[0], "program") == 0);
1225           ASSERT (strcmp (argv[1], "donald") == 0);
1226           ASSERT (strcmp (argv[2], "-p") == 0);
1227           ASSERT (strcmp (argv[3], "billy") == 0);
1228           ASSERT (strcmp (argv[4], "duck") == 0);
1229           ASSERT (strcmp (argv[5], "-a") == 0);
1230           ASSERT (strcmp (argv[6], "bar") == 0);
1231           ASSERT (argv[7] == NULL);
1232           ASSERT (a_seen == 0);
1233           ASSERT (b_seen == 0);
1234           ASSERT (p_value == NULL);
1235           ASSERT (q_value == NULL);
1236           ASSERT (non_options_count == 0);
1237           ASSERT (unrecognized == 0);
1238           ASSERT (optind == 1);
1239           ASSERT (!output);
1240         }
1241       else
1242         {
1243           ASSERT (strcmp (argv[0], "program") == 0);
1244           ASSERT (strcmp (argv[1], "-p") == 0);
1245           ASSERT (strcmp (argv[2], "billy") == 0);
1246           ASSERT (strcmp (argv[3], "-a") == 0);
1247           ASSERT (strcmp (argv[4], "donald") == 0);
1248           ASSERT (strcmp (argv[5], "duck") == 0);
1249           ASSERT (strcmp (argv[6], "bar") == 0);
1250           ASSERT (argv[7] == NULL);
1251           ASSERT (a_seen == 1);
1252           ASSERT (b_seen == 0);
1253           ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
1254           ASSERT (q_value == NULL);
1255           ASSERT (non_options_count == 0);
1256           ASSERT (unrecognized == 0);
1257           ASSERT (optind == 4);
1258           ASSERT (!output);
1259         }
1260     }
1261
1262 #if GNULIB_TEST_GETOPT_GNU
1263   /* If GNU extensions are supported, require compliance with POSIX
1264      interpretation on leading '+' behavior.
1265      http://austingroupbugs.net/view.php?id=191  */
1266   for (start = OPTIND_MIN; start <= 1; start++)
1267     {
1268       int a_seen = 0;
1269       int b_seen = 0;
1270       const char *p_value = NULL;
1271       const char *q_value = NULL;
1272       int non_options_count = 0;
1273       const char *non_options[10];
1274       int unrecognized = 0;
1275       bool output;
1276       int argc = 0;
1277       const char *argv[10];
1278
1279       argv[argc++] = "program";
1280       argv[argc++] = "donald";
1281       argv[argc++] = "-p";
1282       argv[argc++] = "billy";
1283       argv[argc++] = "duck";
1284       argv[argc++] = "-a";
1285       argv[argc++] = "bar";
1286       argv[argc] = NULL;
1287       optind = start;
1288       opterr = 1;
1289       getopt_loop (argc, argv, "+:abp:q:",
1290                    &a_seen, &b_seen, &p_value, &q_value,
1291                    &non_options_count, non_options, &unrecognized, &output);
1292       ASSERT (strcmp (argv[0], "program") == 0);
1293       ASSERT (strcmp (argv[1], "donald") == 0);
1294       ASSERT (strcmp (argv[2], "-p") == 0);
1295       ASSERT (strcmp (argv[3], "billy") == 0);
1296       ASSERT (strcmp (argv[4], "duck") == 0);
1297       ASSERT (strcmp (argv[5], "-a") == 0);
1298       ASSERT (strcmp (argv[6], "bar") == 0);
1299       ASSERT (argv[7] == NULL);
1300       ASSERT (a_seen == 0);
1301       ASSERT (b_seen == 0);
1302       ASSERT (p_value == NULL);
1303       ASSERT (q_value == NULL);
1304       ASSERT (non_options_count == 0);
1305       ASSERT (unrecognized == 0);
1306       ASSERT (optind == 1);
1307       ASSERT (!output);
1308     }
1309   for (start = OPTIND_MIN; start <= 1; start++)
1310     {
1311       int a_seen = 0;
1312       int b_seen = 0;
1313       const char *p_value = NULL;
1314       const char *q_value = NULL;
1315       int non_options_count = 0;
1316       const char *non_options[10];
1317       int unrecognized = 0;
1318       bool output;
1319       int argc = 0;
1320       const char *argv[10];
1321
1322       argv[argc++] = "program";
1323       argv[argc++] = "-p";
1324       argv[argc] = NULL;
1325       optind = start;
1326       getopt_loop (argc, argv, "+:abp:q:",
1327                    &a_seen, &b_seen, &p_value, &q_value,
1328                    &non_options_count, non_options, &unrecognized, &output);
1329       ASSERT (a_seen == 0);
1330       ASSERT (b_seen == 0);
1331       ASSERT (p_value == NULL);
1332       ASSERT (q_value == NULL);
1333       ASSERT (non_options_count == 0);
1334       ASSERT (unrecognized == 'p');
1335       ASSERT (optind == 2);
1336       ASSERT (!output);
1337     }
1338   for (start = OPTIND_MIN; start <= 1; start++)
1339     {
1340       int a_seen = 0;
1341       int b_seen = 0;
1342       const char *p_value = NULL;
1343       const char *q_value = NULL;
1344       int non_options_count = 0;
1345       const char *non_options[10];
1346       int unrecognized = 0;
1347       bool output;
1348       int argc = 0;
1349       const char *argv[10];
1350
1351       argv[argc++] = "program";
1352       argv[argc++] = "-b";
1353       argv[argc++] = "-p";
1354       argv[argc] = NULL;
1355       optind = start;
1356       getopt_loop (argc, argv, "+:abp:q:",
1357                    &a_seen, &b_seen, &p_value, &q_value,
1358                    &non_options_count, non_options, &unrecognized, &output);
1359       ASSERT (a_seen == 0);
1360       ASSERT (b_seen == 1);
1361       ASSERT (p_value == NULL);
1362       ASSERT (q_value == NULL);
1363       ASSERT (non_options_count == 0);
1364       ASSERT (unrecognized == 'p');
1365       ASSERT (optind == 3);
1366       ASSERT (!output);
1367     }
1368
1369   /* Check that 'W' does not dump core:
1370      http://sourceware.org/bugzilla/show_bug.cgi?id=12922
1371      Technically, POSIX says the presence of ';' in the opt-string
1372      gives unspecified behavior, so we only test this when GNU compliance
1373      is desired.  */
1374   for (start = OPTIND_MIN; start <= 1; start++)
1375     {
1376       int argc = 0;
1377       const char *argv[10];
1378       int pos = ftell (stderr);
1379
1380       argv[argc++] = "program";
1381       argv[argc++] = "-W";
1382       argv[argc++] = "dummy";
1383       argv[argc] = NULL;
1384       optind = start;
1385       opterr = 1;
1386       ASSERT (getopt (argc, (char **) argv, "W;") == 'W');
1387       ASSERT (ftell (stderr) == pos);
1388       ASSERT (optind == 2);
1389     }
1390 #endif /* GNULIB_TEST_GETOPT_GNU */
1391 }