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