Merge commit '12319ff4e84ca616a671216d991dd6eaf1c39c47' into stable
[gnulib.git] / tests / test-getopt.h
1 /* Test of command line argument processing.
2    Copyright (C) 2009, 2010 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)
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_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
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_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 #endif
997
998   /* Check that the '-' flag has to come first.  */
999   for (start = OPTIND_MIN; start <= 1; start++)
1000     {
1001       int a_seen = 0;
1002       int b_seen = 0;
1003       const char *p_value = NULL;
1004       const char *q_value = NULL;
1005       int non_options_count = 0;
1006       const char *non_options[10];
1007       int unrecognized = 0;
1008       bool output;
1009       int argc = 0;
1010       const char *argv[10];
1011
1012       argv[argc++] = "program";
1013       argv[argc++] = "donald";
1014       argv[argc++] = "-p";
1015       argv[argc++] = "billy";
1016       argv[argc++] = "duck";
1017       argv[argc++] = "-a";
1018       argv[argc++] = "bar";
1019       argv[argc] = NULL;
1020       optind = start;
1021       opterr = 1;
1022       getopt_loop (argc, argv, "abp:q:-",
1023                    &a_seen, &b_seen, &p_value, &q_value,
1024                    &non_options_count, non_options, &unrecognized, &output);
1025       if (posixly)
1026         {
1027           ASSERT (strcmp (argv[0], "program") == 0);
1028           ASSERT (strcmp (argv[1], "donald") == 0);
1029           ASSERT (strcmp (argv[2], "-p") == 0);
1030           ASSERT (strcmp (argv[3], "billy") == 0);
1031           ASSERT (strcmp (argv[4], "duck") == 0);
1032           ASSERT (strcmp (argv[5], "-a") == 0);
1033           ASSERT (strcmp (argv[6], "bar") == 0);
1034           ASSERT (argv[7] == NULL);
1035           ASSERT (a_seen == 0);
1036           ASSERT (b_seen == 0);
1037           ASSERT (p_value == NULL);
1038           ASSERT (q_value == NULL);
1039           ASSERT (non_options_count == 0);
1040           ASSERT (unrecognized == 0);
1041           ASSERT (optind == 1);
1042           ASSERT (!output);
1043         }
1044       else
1045         {
1046           ASSERT (strcmp (argv[0], "program") == 0);
1047           ASSERT (strcmp (argv[1], "-p") == 0);
1048           ASSERT (strcmp (argv[2], "billy") == 0);
1049           ASSERT (strcmp (argv[3], "-a") == 0);
1050           ASSERT (strcmp (argv[4], "donald") == 0);
1051           ASSERT (strcmp (argv[5], "duck") == 0);
1052           ASSERT (strcmp (argv[6], "bar") == 0);
1053           ASSERT (argv[7] == NULL);
1054           ASSERT (a_seen == 1);
1055           ASSERT (b_seen == 0);
1056           ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
1057           ASSERT (q_value == NULL);
1058           ASSERT (non_options_count == 0);
1059           ASSERT (unrecognized == 0);
1060           ASSERT (optind == 4);
1061           ASSERT (!output);
1062         }
1063     }
1064
1065   /* Check that the '+' flag causes the first non-option to terminate the
1066      loop.  */
1067   for (start = OPTIND_MIN; start <= 1; start++)
1068     {
1069       int a_seen = 0;
1070       int b_seen = 0;
1071       const char *p_value = NULL;
1072       const char *q_value = NULL;
1073       int non_options_count = 0;
1074       const char *non_options[10];
1075       int unrecognized = 0;
1076       bool output;
1077       int argc = 0;
1078       const char *argv[10];
1079
1080       argv[argc++] = "program";
1081       argv[argc++] = "donald";
1082       argv[argc++] = "-p";
1083       argv[argc++] = "billy";
1084       argv[argc++] = "duck";
1085       argv[argc++] = "-a";
1086       argv[argc++] = "bar";
1087       argv[argc] = NULL;
1088       optind = start;
1089       opterr = 1;
1090       getopt_loop (argc, argv, "+abp:q:",
1091                    &a_seen, &b_seen, &p_value, &q_value,
1092                    &non_options_count, non_options, &unrecognized, &output);
1093       ASSERT (strcmp (argv[0], "program") == 0);
1094       ASSERT (strcmp (argv[1], "donald") == 0);
1095       ASSERT (strcmp (argv[2], "-p") == 0);
1096       ASSERT (strcmp (argv[3], "billy") == 0);
1097       ASSERT (strcmp (argv[4], "duck") == 0);
1098       ASSERT (strcmp (argv[5], "-a") == 0);
1099       ASSERT (strcmp (argv[6], "bar") == 0);
1100       ASSERT (argv[7] == NULL);
1101       ASSERT (a_seen == 0);
1102       ASSERT (b_seen == 0);
1103       ASSERT (p_value == NULL);
1104       ASSERT (q_value == NULL);
1105       ASSERT (non_options_count == 0);
1106       ASSERT (unrecognized == 0);
1107       ASSERT (optind == 1);
1108       ASSERT (!output);
1109     }
1110   for (start = OPTIND_MIN; start <= 1; start++)
1111     {
1112       int a_seen = 0;
1113       int b_seen = 0;
1114       const char *p_value = NULL;
1115       const char *q_value = NULL;
1116       int non_options_count = 0;
1117       const char *non_options[10];
1118       int unrecognized = 0;
1119       bool output;
1120       int argc = 0;
1121       const char *argv[10];
1122
1123       argv[argc++] = "program";
1124       argv[argc++] = "-+";
1125       argv[argc] = NULL;
1126       optind = start;
1127       /* Suppress output, since glibc is inconsistent on whether this
1128          prints a message:
1129          http://sources.redhat.com/bugzilla/show_bug.cgi?id=11039 */
1130       opterr = 0;
1131       getopt_loop (argc, argv, "+abp:q:",
1132                    &a_seen, &b_seen, &p_value, &q_value,
1133                    &non_options_count, non_options, &unrecognized, &output);
1134       ASSERT (a_seen == 0);
1135       ASSERT (b_seen == 0);
1136       ASSERT (p_value == NULL);
1137       ASSERT (q_value == NULL);
1138       ASSERT (non_options_count == 0);
1139       ASSERT (unrecognized == '+');
1140       ASSERT (optind == 2);
1141       ASSERT (!output);
1142     }
1143
1144   /* Check that '--' ends the argument processing.  */
1145   for (start = OPTIND_MIN; start <= 1; start++)
1146     {
1147       int a_seen = 0;
1148       int b_seen = 0;
1149       const char *p_value = NULL;
1150       const char *q_value = NULL;
1151       int non_options_count = 0;
1152       const char *non_options[10];
1153       int unrecognized = 0;
1154       bool output;
1155       int argc = 0;
1156       const char *argv[20];
1157
1158       argv[argc++] = "program";
1159       argv[argc++] = "donald";
1160       argv[argc++] = "-p";
1161       argv[argc++] = "billy";
1162       argv[argc++] = "duck";
1163       argv[argc++] = "-a";
1164       argv[argc++] = "--";
1165       argv[argc++] = "-b";
1166       argv[argc++] = "foo";
1167       argv[argc++] = "-q";
1168       argv[argc++] = "johnny";
1169       argv[argc++] = "bar";
1170       argv[argc] = NULL;
1171       optind = start;
1172       opterr = 1;
1173       getopt_loop (argc, argv, "+abp:q:",
1174                    &a_seen, &b_seen, &p_value, &q_value,
1175                    &non_options_count, non_options, &unrecognized, &output);
1176       ASSERT (strcmp (argv[0], "program") == 0);
1177       ASSERT (strcmp (argv[1], "donald") == 0);
1178       ASSERT (strcmp (argv[2], "-p") == 0);
1179       ASSERT (strcmp (argv[3], "billy") == 0);
1180       ASSERT (strcmp (argv[4], "duck") == 0);
1181       ASSERT (strcmp (argv[5], "-a") == 0);
1182       ASSERT (strcmp (argv[6], "--") == 0);
1183       ASSERT (strcmp (argv[7], "-b") == 0);
1184       ASSERT (strcmp (argv[8], "foo") == 0);
1185       ASSERT (strcmp (argv[9], "-q") == 0);
1186       ASSERT (strcmp (argv[10], "johnny") == 0);
1187       ASSERT (strcmp (argv[11], "bar") == 0);
1188       ASSERT (argv[12] == NULL);
1189       ASSERT (a_seen == 0);
1190       ASSERT (b_seen == 0);
1191       ASSERT (p_value == NULL);
1192       ASSERT (q_value == NULL);
1193       ASSERT (non_options_count == 0);
1194       ASSERT (unrecognized == 0);
1195       ASSERT (optind = 1);
1196       ASSERT (!output);
1197     }
1198
1199   /* Check that the '+' flag has to come first.  */
1200   for (start = OPTIND_MIN; start <= 1; start++)
1201     {
1202       int a_seen = 0;
1203       int b_seen = 0;
1204       const char *p_value = NULL;
1205       const char *q_value = NULL;
1206       int non_options_count = 0;
1207       const char *non_options[10];
1208       int unrecognized = 0;
1209       bool output;
1210       int argc = 0;
1211       const char *argv[10];
1212
1213       argv[argc++] = "program";
1214       argv[argc++] = "donald";
1215       argv[argc++] = "-p";
1216       argv[argc++] = "billy";
1217       argv[argc++] = "duck";
1218       argv[argc++] = "-a";
1219       argv[argc++] = "bar";
1220       argv[argc] = NULL;
1221       optind = start;
1222       opterr = 1;
1223       getopt_loop (argc, argv, "abp:q:+",
1224                    &a_seen, &b_seen, &p_value, &q_value,
1225                    &non_options_count, non_options, &unrecognized, &output);
1226       if (posixly)
1227         {
1228           ASSERT (strcmp (argv[0], "program") == 0);
1229           ASSERT (strcmp (argv[1], "donald") == 0);
1230           ASSERT (strcmp (argv[2], "-p") == 0);
1231           ASSERT (strcmp (argv[3], "billy") == 0);
1232           ASSERT (strcmp (argv[4], "duck") == 0);
1233           ASSERT (strcmp (argv[5], "-a") == 0);
1234           ASSERT (strcmp (argv[6], "bar") == 0);
1235           ASSERT (argv[7] == NULL);
1236           ASSERT (a_seen == 0);
1237           ASSERT (b_seen == 0);
1238           ASSERT (p_value == NULL);
1239           ASSERT (q_value == NULL);
1240           ASSERT (non_options_count == 0);
1241           ASSERT (unrecognized == 0);
1242           ASSERT (optind == 1);
1243           ASSERT (!output);
1244         }
1245       else
1246         {
1247           ASSERT (strcmp (argv[0], "program") == 0);
1248           ASSERT (strcmp (argv[1], "-p") == 0);
1249           ASSERT (strcmp (argv[2], "billy") == 0);
1250           ASSERT (strcmp (argv[3], "-a") == 0);
1251           ASSERT (strcmp (argv[4], "donald") == 0);
1252           ASSERT (strcmp (argv[5], "duck") == 0);
1253           ASSERT (strcmp (argv[6], "bar") == 0);
1254           ASSERT (argv[7] == NULL);
1255           ASSERT (a_seen == 1);
1256           ASSERT (b_seen == 0);
1257           ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
1258           ASSERT (q_value == NULL);
1259           ASSERT (non_options_count == 0);
1260           ASSERT (unrecognized == 0);
1261           ASSERT (optind == 4);
1262           ASSERT (!output);
1263         }
1264     }
1265
1266   /* No tests of "-:..." or "+:...", due to glibc bug:
1267      http://sources.redhat.com/bugzilla/show_bug.cgi?id=11039 */
1268 }