Line data Source code
1 : /* Test of command line argument processing.
2 : Copyright (C) 2009-2020 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 <https://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 152 : 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 152 : int pos = ftell (stderr);
42 :
43 480 : while ((c = getopt (argc, (char **) argv, options)) != -1)
44 : {
45 328 : switch (c)
46 : {
47 132 : case 'a':
48 132 : (*a_seen)++;
49 132 : break;
50 32 : case 'b':
51 32 : (*b_seen)++;
52 32 : break;
53 84 : case 'p':
54 84 : *p_value = optarg;
55 84 : break;
56 8 : case 'q':
57 8 : *q_value = optarg;
58 8 : break;
59 0 : case '\1':
60 : /* Must only happen with option '-' at the beginning. */
61 0 : ASSERT (options[0] == '-');
62 0 : non_options[(*non_options_count)++] = optarg;
63 0 : break;
64 8 : case ':':
65 : /* Must only happen with option ':' at the beginning. */
66 8 : ASSERT (options[0] == ':'
67 : || ((options[0] == '-' || options[0] == '+')
68 : && options[1] == ':'));
69 : FALLTHROUGH;
70 : case '?':
71 72 : *unrecognized = optopt;
72 72 : break;
73 0 : default:
74 0 : *unrecognized = c;
75 0 : break;
76 : }
77 : }
78 :
79 152 : *message_issued = pos < ftell (stderr);
80 152 : }
81 :
82 : static void
83 4 : test_getopt (void)
84 : {
85 : int start;
86 4 : 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 12 : for (start = OPTIND_MIN; start <= 1; start++)
97 : {
98 8 : int a_seen = 0;
99 8 : int b_seen = 0;
100 8 : const char *p_value = NULL;
101 8 : const char *q_value = NULL;
102 8 : int non_options_count = 0;
103 : const char *non_options[10];
104 8 : int unrecognized = 0;
105 : bool output;
106 8 : int argc = 0;
107 : const char *argv[10];
108 :
109 8 : argv[argc++] = "program";
110 8 : argv[argc++] = "-a";
111 8 : argv[argc++] = "foo";
112 8 : argv[argc++] = "bar";
113 8 : argv[argc] = NULL;
114 8 : optind = start;
115 8 : opterr = 1;
116 8 : getopt_loop (argc, argv, "ab",
117 : &a_seen, &b_seen, &p_value, &q_value,
118 : &non_options_count, non_options, &unrecognized, &output);
119 8 : ASSERT (a_seen == 1);
120 8 : ASSERT (b_seen == 0);
121 8 : ASSERT (p_value == NULL);
122 8 : ASSERT (q_value == NULL);
123 8 : ASSERT (non_options_count == 0);
124 8 : ASSERT (unrecognized == 0);
125 8 : ASSERT (optind == 2);
126 8 : ASSERT (!output);
127 : }
128 12 : for (start = OPTIND_MIN; start <= 1; start++)
129 : {
130 8 : int a_seen = 0;
131 8 : int b_seen = 0;
132 8 : const char *p_value = NULL;
133 8 : const char *q_value = NULL;
134 8 : int non_options_count = 0;
135 : const char *non_options[10];
136 8 : int unrecognized = 0;
137 : bool output;
138 8 : int argc = 0;
139 : const char *argv[10];
140 :
141 8 : argv[argc++] = "program";
142 8 : argv[argc++] = "-b";
143 8 : argv[argc++] = "-a";
144 8 : argv[argc++] = "foo";
145 8 : argv[argc++] = "bar";
146 8 : argv[argc] = NULL;
147 8 : optind = start;
148 8 : opterr = 1;
149 8 : getopt_loop (argc, argv, "ab",
150 : &a_seen, &b_seen, &p_value, &q_value,
151 : &non_options_count, non_options, &unrecognized, &output);
152 8 : ASSERT (a_seen == 1);
153 8 : ASSERT (b_seen == 1);
154 8 : ASSERT (p_value == NULL);
155 8 : ASSERT (q_value == NULL);
156 8 : ASSERT (non_options_count == 0);
157 8 : ASSERT (unrecognized == 0);
158 8 : ASSERT (optind == 3);
159 8 : ASSERT (!output);
160 : }
161 12 : for (start = OPTIND_MIN; start <= 1; start++)
162 : {
163 8 : int a_seen = 0;
164 8 : int b_seen = 0;
165 8 : const char *p_value = NULL;
166 8 : const char *q_value = NULL;
167 8 : int non_options_count = 0;
168 : const char *non_options[10];
169 8 : int unrecognized = 0;
170 : bool output;
171 8 : int argc = 0;
172 : const char *argv[10];
173 :
174 8 : argv[argc++] = "program";
175 8 : argv[argc++] = "-ba";
176 8 : argv[argc++] = "foo";
177 8 : argv[argc++] = "bar";
178 8 : argv[argc] = NULL;
179 8 : optind = start;
180 8 : opterr = 1;
181 8 : getopt_loop (argc, argv, "ab",
182 : &a_seen, &b_seen, &p_value, &q_value,
183 : &non_options_count, non_options, &unrecognized, &output);
184 8 : ASSERT (a_seen == 1);
185 8 : ASSERT (b_seen == 1);
186 8 : ASSERT (p_value == NULL);
187 8 : ASSERT (q_value == NULL);
188 8 : ASSERT (non_options_count == 0);
189 8 : ASSERT (unrecognized == 0);
190 8 : ASSERT (optind == 2);
191 8 : ASSERT (!output);
192 : }
193 12 : for (start = OPTIND_MIN; start <= 1; start++)
194 : {
195 8 : int a_seen = 0;
196 8 : int b_seen = 0;
197 8 : const char *p_value = NULL;
198 8 : const char *q_value = NULL;
199 8 : int non_options_count = 0;
200 : const char *non_options[10];
201 8 : int unrecognized = 0;
202 : bool output;
203 8 : int argc = 0;
204 : const char *argv[10];
205 :
206 8 : argv[argc++] = "program";
207 8 : argv[argc++] = "-ab";
208 8 : argv[argc++] = "-a";
209 8 : argv[argc++] = "foo";
210 8 : argv[argc++] = "bar";
211 8 : argv[argc] = NULL;
212 8 : optind = start;
213 8 : opterr = 1;
214 8 : getopt_loop (argc, argv, "ab",
215 : &a_seen, &b_seen, &p_value, &q_value,
216 : &non_options_count, non_options, &unrecognized, &output);
217 8 : ASSERT (a_seen == 2);
218 8 : ASSERT (b_seen == 1);
219 8 : ASSERT (p_value == NULL);
220 8 : ASSERT (q_value == NULL);
221 8 : ASSERT (non_options_count == 0);
222 8 : ASSERT (unrecognized == 0);
223 8 : ASSERT (optind == 3);
224 8 : ASSERT (!output);
225 : }
226 :
227 : /* Test processing of options with arguments. */
228 12 : for (start = OPTIND_MIN; start <= 1; start++)
229 : {
230 8 : int a_seen = 0;
231 8 : int b_seen = 0;
232 8 : const char *p_value = NULL;
233 8 : const char *q_value = NULL;
234 8 : int non_options_count = 0;
235 : const char *non_options[10];
236 8 : int unrecognized = 0;
237 : bool output;
238 8 : int argc = 0;
239 : const char *argv[10];
240 :
241 8 : argv[argc++] = "program";
242 8 : argv[argc++] = "-pfoo";
243 8 : argv[argc++] = "bar";
244 8 : argv[argc] = NULL;
245 8 : optind = start;
246 8 : opterr = 1;
247 8 : getopt_loop (argc, argv, "p:q:",
248 : &a_seen, &b_seen, &p_value, &q_value,
249 : &non_options_count, non_options, &unrecognized, &output);
250 8 : ASSERT (a_seen == 0);
251 8 : ASSERT (b_seen == 0);
252 8 : ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
253 8 : ASSERT (q_value == NULL);
254 8 : ASSERT (non_options_count == 0);
255 8 : ASSERT (unrecognized == 0);
256 8 : ASSERT (optind == 2);
257 8 : ASSERT (!output);
258 : }
259 12 : for (start = OPTIND_MIN; start <= 1; start++)
260 : {
261 8 : int a_seen = 0;
262 8 : int b_seen = 0;
263 8 : const char *p_value = NULL;
264 8 : const char *q_value = NULL;
265 8 : int non_options_count = 0;
266 : const char *non_options[10];
267 8 : int unrecognized = 0;
268 : bool output;
269 8 : int argc = 0;
270 : const char *argv[10];
271 :
272 8 : argv[argc++] = "program";
273 8 : argv[argc++] = "-p";
274 8 : argv[argc++] = "foo";
275 8 : argv[argc++] = "bar";
276 8 : argv[argc] = NULL;
277 8 : optind = start;
278 8 : opterr = 1;
279 8 : getopt_loop (argc, argv, "p:q:",
280 : &a_seen, &b_seen, &p_value, &q_value,
281 : &non_options_count, non_options, &unrecognized, &output);
282 8 : ASSERT (a_seen == 0);
283 8 : ASSERT (b_seen == 0);
284 8 : ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
285 8 : ASSERT (q_value == NULL);
286 8 : ASSERT (non_options_count == 0);
287 8 : ASSERT (unrecognized == 0);
288 8 : ASSERT (optind == 3);
289 8 : ASSERT (!output);
290 : }
291 12 : for (start = OPTIND_MIN; start <= 1; start++)
292 : {
293 8 : int a_seen = 0;
294 8 : int b_seen = 0;
295 8 : const char *p_value = NULL;
296 8 : const char *q_value = NULL;
297 8 : int non_options_count = 0;
298 : const char *non_options[10];
299 8 : int unrecognized = 0;
300 : bool output;
301 8 : int argc = 0;
302 : const char *argv[10];
303 :
304 8 : argv[argc++] = "program";
305 8 : argv[argc++] = "-ab";
306 8 : argv[argc++] = "-q";
307 8 : argv[argc++] = "baz";
308 8 : argv[argc++] = "-pfoo";
309 8 : argv[argc++] = "bar";
310 8 : argv[argc] = NULL;
311 8 : optind = start;
312 8 : opterr = 1;
313 8 : getopt_loop (argc, argv, "abp:q:",
314 : &a_seen, &b_seen, &p_value, &q_value,
315 : &non_options_count, non_options, &unrecognized, &output);
316 8 : ASSERT (a_seen == 1);
317 8 : ASSERT (b_seen == 1);
318 8 : ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
319 8 : ASSERT (q_value != NULL && strcmp (q_value, "baz") == 0);
320 8 : ASSERT (non_options_count == 0);
321 8 : ASSERT (unrecognized == 0);
322 8 : ASSERT (optind == 5);
323 8 : 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 12 : for (start = OPTIND_MIN; start <= 1; start++)
428 : {
429 8 : int a_seen = 0;
430 8 : int b_seen = 0;
431 8 : const char *p_value = NULL;
432 8 : const char *q_value = NULL;
433 8 : int non_options_count = 0;
434 : const char *non_options[10];
435 8 : int unrecognized = 0;
436 : bool output;
437 8 : int argc = 0;
438 : const char *argv[10];
439 :
440 8 : argv[argc++] = "program";
441 8 : argv[argc++] = "-p";
442 8 : argv[argc++] = "foo";
443 8 : argv[argc++] = "-x";
444 8 : argv[argc++] = "-a";
445 8 : argv[argc++] = "bar";
446 8 : argv[argc] = NULL;
447 8 : optind = start;
448 8 : opterr = 42;
449 8 : getopt_loop (argc, argv, "abp:q:",
450 : &a_seen, &b_seen, &p_value, &q_value,
451 : &non_options_count, non_options, &unrecognized, &output);
452 8 : ASSERT (a_seen == 1);
453 8 : ASSERT (b_seen == 0);
454 8 : ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
455 8 : ASSERT (q_value == NULL);
456 8 : ASSERT (non_options_count == 0);
457 8 : ASSERT (unrecognized == 'x');
458 8 : ASSERT (optind == 5);
459 8 : ASSERT (output);
460 : }
461 12 : for (start = OPTIND_MIN; start <= 1; start++)
462 : {
463 8 : int a_seen = 0;
464 8 : int b_seen = 0;
465 8 : const char *p_value = NULL;
466 8 : const char *q_value = NULL;
467 8 : int non_options_count = 0;
468 : const char *non_options[10];
469 8 : int unrecognized = 0;
470 : bool output;
471 8 : int argc = 0;
472 : const char *argv[10];
473 :
474 8 : argv[argc++] = "program";
475 8 : argv[argc++] = "-p";
476 8 : argv[argc++] = "foo";
477 8 : argv[argc++] = "-x";
478 8 : argv[argc++] = "-a";
479 8 : argv[argc++] = "bar";
480 8 : argv[argc] = NULL;
481 8 : optind = start;
482 8 : opterr = 0;
483 8 : getopt_loop (argc, argv, "abp:q:",
484 : &a_seen, &b_seen, &p_value, &q_value,
485 : &non_options_count, non_options, &unrecognized, &output);
486 8 : ASSERT (a_seen == 1);
487 8 : ASSERT (b_seen == 0);
488 8 : ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
489 8 : ASSERT (q_value == NULL);
490 8 : ASSERT (non_options_count == 0);
491 8 : ASSERT (unrecognized == 'x');
492 8 : ASSERT (optind == 5);
493 8 : ASSERT (!output);
494 : }
495 12 : for (start = OPTIND_MIN; start <= 1; start++)
496 : {
497 8 : int a_seen = 0;
498 8 : int b_seen = 0;
499 8 : const char *p_value = NULL;
500 8 : const char *q_value = NULL;
501 8 : int non_options_count = 0;
502 : const char *non_options[10];
503 8 : int unrecognized = 0;
504 : bool output;
505 8 : int argc = 0;
506 : const char *argv[10];
507 :
508 8 : argv[argc++] = "program";
509 8 : argv[argc++] = "-p";
510 8 : argv[argc++] = "foo";
511 8 : argv[argc++] = "-x";
512 8 : argv[argc++] = "-a";
513 8 : argv[argc++] = "bar";
514 8 : argv[argc] = NULL;
515 8 : optind = start;
516 8 : opterr = 1;
517 8 : getopt_loop (argc, argv, ":abp:q:",
518 : &a_seen, &b_seen, &p_value, &q_value,
519 : &non_options_count, non_options, &unrecognized, &output);
520 8 : ASSERT (a_seen == 1);
521 8 : ASSERT (b_seen == 0);
522 8 : ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
523 8 : ASSERT (q_value == NULL);
524 8 : ASSERT (non_options_count == 0);
525 8 : ASSERT (unrecognized == 'x');
526 8 : ASSERT (optind == 5);
527 8 : ASSERT (!output);
528 : }
529 12 : for (start = OPTIND_MIN; start <= 1; start++)
530 : {
531 8 : int a_seen = 0;
532 8 : int b_seen = 0;
533 8 : const char *p_value = NULL;
534 8 : const char *q_value = NULL;
535 8 : int non_options_count = 0;
536 : const char *non_options[10];
537 8 : int unrecognized = 0;
538 : bool output;
539 8 : int argc = 0;
540 : const char *argv[10];
541 :
542 8 : argv[argc++] = "program";
543 8 : argv[argc++] = "-p";
544 8 : argv[argc++] = "foo";
545 8 : argv[argc++] = "-:";
546 8 : argv[argc++] = "-a";
547 8 : argv[argc++] = "bar";
548 8 : argv[argc] = NULL;
549 8 : optind = start;
550 8 : opterr = 42;
551 8 : getopt_loop (argc, argv, "abp:q:",
552 : &a_seen, &b_seen, &p_value, &q_value,
553 : &non_options_count, non_options, &unrecognized, &output);
554 8 : ASSERT (a_seen == 1);
555 8 : ASSERT (b_seen == 0);
556 8 : ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
557 8 : ASSERT (q_value == NULL);
558 8 : ASSERT (non_options_count == 0);
559 8 : ASSERT (unrecognized == ':');
560 8 : ASSERT (optind == 5);
561 8 : ASSERT (output);
562 : }
563 12 : for (start = OPTIND_MIN; start <= 1; start++)
564 : {
565 8 : int a_seen = 0;
566 8 : int b_seen = 0;
567 8 : const char *p_value = NULL;
568 8 : const char *q_value = NULL;
569 8 : int non_options_count = 0;
570 : const char *non_options[10];
571 8 : int unrecognized = 0;
572 : bool output;
573 8 : int argc = 0;
574 : const char *argv[10];
575 :
576 8 : argv[argc++] = "program";
577 8 : argv[argc++] = "-p";
578 8 : argv[argc++] = "foo";
579 8 : argv[argc++] = "-:";
580 8 : argv[argc++] = "-a";
581 8 : argv[argc++] = "bar";
582 8 : argv[argc] = NULL;
583 8 : optind = start;
584 8 : opterr = 0;
585 8 : getopt_loop (argc, argv, "abp:q:",
586 : &a_seen, &b_seen, &p_value, &q_value,
587 : &non_options_count, non_options, &unrecognized, &output);
588 8 : ASSERT (a_seen == 1);
589 8 : ASSERT (b_seen == 0);
590 8 : ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
591 8 : ASSERT (q_value == NULL);
592 8 : ASSERT (non_options_count == 0);
593 8 : ASSERT (unrecognized == ':');
594 8 : ASSERT (optind == 5);
595 8 : ASSERT (!output);
596 : }
597 12 : for (start = OPTIND_MIN; start <= 1; start++)
598 : {
599 8 : int a_seen = 0;
600 8 : int b_seen = 0;
601 8 : const char *p_value = NULL;
602 8 : const char *q_value = NULL;
603 8 : int non_options_count = 0;
604 : const char *non_options[10];
605 8 : int unrecognized = 0;
606 : bool output;
607 8 : int argc = 0;
608 : const char *argv[10];
609 :
610 8 : argv[argc++] = "program";
611 8 : argv[argc++] = "-p";
612 8 : argv[argc++] = "foo";
613 8 : argv[argc++] = "-:";
614 8 : argv[argc++] = "-a";
615 8 : argv[argc++] = "bar";
616 8 : argv[argc] = NULL;
617 8 : optind = start;
618 8 : opterr = 1;
619 8 : getopt_loop (argc, argv, ":abp:q:",
620 : &a_seen, &b_seen, &p_value, &q_value,
621 : &non_options_count, non_options, &unrecognized, &output);
622 8 : ASSERT (a_seen == 1);
623 8 : ASSERT (b_seen == 0);
624 8 : ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
625 8 : ASSERT (q_value == NULL);
626 8 : ASSERT (non_options_count == 0);
627 8 : ASSERT (unrecognized == ':');
628 8 : ASSERT (optind == 5);
629 8 : ASSERT (!output);
630 : }
631 :
632 : /* Check for missing argument behavior. */
633 12 : for (start = OPTIND_MIN; start <= 1; start++)
634 : {
635 8 : int a_seen = 0;
636 8 : int b_seen = 0;
637 8 : const char *p_value = NULL;
638 8 : const char *q_value = NULL;
639 8 : int non_options_count = 0;
640 : const char *non_options[10];
641 8 : int unrecognized = 0;
642 : bool output;
643 8 : int argc = 0;
644 : const char *argv[10];
645 :
646 8 : argv[argc++] = "program";
647 8 : argv[argc++] = "-ap";
648 8 : argv[argc] = NULL;
649 8 : optind = start;
650 8 : opterr = 1;
651 8 : getopt_loop (argc, argv, "abp:q:",
652 : &a_seen, &b_seen, &p_value, &q_value,
653 : &non_options_count, non_options, &unrecognized, &output);
654 8 : ASSERT (a_seen == 1);
655 8 : ASSERT (b_seen == 0);
656 8 : ASSERT (p_value == NULL);
657 8 : ASSERT (q_value == NULL);
658 8 : ASSERT (non_options_count == 0);
659 8 : ASSERT (unrecognized == 'p');
660 8 : ASSERT (optind == 2);
661 8 : ASSERT (output);
662 : }
663 12 : for (start = OPTIND_MIN; start <= 1; start++)
664 : {
665 8 : int a_seen = 0;
666 8 : int b_seen = 0;
667 8 : const char *p_value = NULL;
668 8 : const char *q_value = NULL;
669 8 : int non_options_count = 0;
670 : const char *non_options[10];
671 8 : int unrecognized = 0;
672 : bool output;
673 8 : int argc = 0;
674 : const char *argv[10];
675 :
676 8 : argv[argc++] = "program";
677 8 : argv[argc++] = "-ap";
678 8 : argv[argc] = NULL;
679 8 : optind = start;
680 8 : opterr = 0;
681 8 : getopt_loop (argc, argv, "abp:q:",
682 : &a_seen, &b_seen, &p_value, &q_value,
683 : &non_options_count, non_options, &unrecognized, &output);
684 8 : ASSERT (a_seen == 1);
685 8 : ASSERT (b_seen == 0);
686 8 : ASSERT (p_value == NULL);
687 8 : ASSERT (q_value == NULL);
688 8 : ASSERT (non_options_count == 0);
689 8 : ASSERT (unrecognized == 'p');
690 8 : ASSERT (optind == 2);
691 8 : ASSERT (!output);
692 : }
693 12 : for (start = OPTIND_MIN; start <= 1; start++)
694 : {
695 8 : int a_seen = 0;
696 8 : int b_seen = 0;
697 8 : const char *p_value = NULL;
698 8 : const char *q_value = NULL;
699 8 : int non_options_count = 0;
700 : const char *non_options[10];
701 8 : int unrecognized = 0;
702 : bool output;
703 8 : int argc = 0;
704 : const char *argv[10];
705 :
706 8 : argv[argc++] = "program";
707 8 : argv[argc++] = "-ap";
708 8 : argv[argc] = NULL;
709 8 : optind = start;
710 8 : opterr = 1;
711 8 : getopt_loop (argc, argv, ":abp:q:",
712 : &a_seen, &b_seen, &p_value, &q_value,
713 : &non_options_count, non_options, &unrecognized, &output);
714 8 : ASSERT (a_seen == 1);
715 8 : ASSERT (b_seen == 0);
716 8 : ASSERT (p_value == NULL);
717 8 : ASSERT (q_value == NULL);
718 8 : ASSERT (non_options_count == 0);
719 8 : ASSERT (unrecognized == 'p');
720 8 : ASSERT (optind == 2);
721 8 : ASSERT (!output);
722 : }
723 :
724 : /* Check that by default, non-options arguments are moved to the end. */
725 12 : for (start = OPTIND_MIN; start <= 1; start++)
726 : {
727 8 : int a_seen = 0;
728 8 : int b_seen = 0;
729 8 : const char *p_value = NULL;
730 8 : const char *q_value = NULL;
731 8 : int non_options_count = 0;
732 : const char *non_options[10];
733 8 : int unrecognized = 0;
734 : bool output;
735 8 : int argc = 0;
736 : const char *argv[10];
737 :
738 8 : argv[argc++] = "program";
739 8 : argv[argc++] = "donald";
740 8 : argv[argc++] = "-p";
741 8 : argv[argc++] = "billy";
742 8 : argv[argc++] = "duck";
743 8 : argv[argc++] = "-a";
744 8 : argv[argc++] = "bar";
745 8 : argv[argc] = NULL;
746 8 : optind = start;
747 8 : opterr = 1;
748 8 : getopt_loop (argc, argv, "abp:q:",
749 : &a_seen, &b_seen, &p_value, &q_value,
750 : &non_options_count, non_options, &unrecognized, &output);
751 8 : if (posixly)
752 : {
753 4 : ASSERT (strcmp (argv[0], "program") == 0);
754 4 : ASSERT (strcmp (argv[1], "donald") == 0);
755 4 : ASSERT (strcmp (argv[2], "-p") == 0);
756 4 : ASSERT (strcmp (argv[3], "billy") == 0);
757 4 : ASSERT (strcmp (argv[4], "duck") == 0);
758 4 : ASSERT (strcmp (argv[5], "-a") == 0);
759 4 : ASSERT (strcmp (argv[6], "bar") == 0);
760 4 : ASSERT (argv[7] == NULL);
761 4 : ASSERT (a_seen == 0);
762 4 : ASSERT (b_seen == 0);
763 4 : ASSERT (p_value == NULL);
764 4 : ASSERT (q_value == NULL);
765 4 : ASSERT (non_options_count == 0);
766 4 : ASSERT (unrecognized == 0);
767 4 : ASSERT (optind == 1);
768 4 : ASSERT (!output);
769 : }
770 : else
771 : {
772 4 : ASSERT (strcmp (argv[0], "program") == 0);
773 4 : ASSERT (strcmp (argv[1], "-p") == 0);
774 4 : ASSERT (strcmp (argv[2], "billy") == 0);
775 4 : ASSERT (strcmp (argv[3], "-a") == 0);
776 4 : ASSERT (strcmp (argv[4], "donald") == 0);
777 4 : ASSERT (strcmp (argv[5], "duck") == 0);
778 4 : ASSERT (strcmp (argv[6], "bar") == 0);
779 4 : ASSERT (argv[7] == NULL);
780 4 : ASSERT (a_seen == 1);
781 4 : ASSERT (b_seen == 0);
782 4 : ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
783 4 : ASSERT (q_value == NULL);
784 4 : ASSERT (non_options_count == 0);
785 4 : ASSERT (unrecognized == 0);
786 4 : ASSERT (optind == 4);
787 4 : ASSERT (!output);
788 : }
789 : }
790 :
791 : /* Check that '--' ends the argument processing. */
792 12 : for (start = OPTIND_MIN; start <= 1; start++)
793 : {
794 8 : int a_seen = 0;
795 8 : int b_seen = 0;
796 8 : const char *p_value = NULL;
797 8 : const char *q_value = NULL;
798 8 : int non_options_count = 0;
799 : const char *non_options[10];
800 8 : int unrecognized = 0;
801 : bool output;
802 8 : int argc = 0;
803 : const char *argv[20];
804 :
805 8 : argv[argc++] = "program";
806 8 : argv[argc++] = "donald";
807 8 : argv[argc++] = "-p";
808 8 : argv[argc++] = "billy";
809 8 : argv[argc++] = "duck";
810 8 : argv[argc++] = "-a";
811 8 : argv[argc++] = "--";
812 8 : argv[argc++] = "-b";
813 8 : argv[argc++] = "foo";
814 8 : argv[argc++] = "-q";
815 8 : argv[argc++] = "johnny";
816 8 : argv[argc++] = "bar";
817 8 : argv[argc] = NULL;
818 8 : optind = start;
819 8 : opterr = 1;
820 8 : getopt_loop (argc, argv, "abp:q:",
821 : &a_seen, &b_seen, &p_value, &q_value,
822 : &non_options_count, non_options, &unrecognized, &output);
823 8 : if (posixly)
824 : {
825 4 : ASSERT (strcmp (argv[0], "program") == 0);
826 4 : ASSERT (strcmp (argv[1], "donald") == 0);
827 4 : ASSERT (strcmp (argv[2], "-p") == 0);
828 4 : ASSERT (strcmp (argv[3], "billy") == 0);
829 4 : ASSERT (strcmp (argv[4], "duck") == 0);
830 4 : ASSERT (strcmp (argv[5], "-a") == 0);
831 4 : ASSERT (strcmp (argv[6], "--") == 0);
832 4 : ASSERT (strcmp (argv[7], "-b") == 0);
833 4 : ASSERT (strcmp (argv[8], "foo") == 0);
834 4 : ASSERT (strcmp (argv[9], "-q") == 0);
835 4 : ASSERT (strcmp (argv[10], "johnny") == 0);
836 4 : ASSERT (strcmp (argv[11], "bar") == 0);
837 4 : ASSERT (argv[12] == NULL);
838 4 : ASSERT (a_seen == 0);
839 4 : ASSERT (b_seen == 0);
840 4 : ASSERT (p_value == NULL);
841 4 : ASSERT (q_value == NULL);
842 4 : ASSERT (non_options_count == 0);
843 4 : ASSERT (unrecognized == 0);
844 4 : ASSERT (optind == 1);
845 4 : ASSERT (!output);
846 : }
847 : else
848 : {
849 4 : ASSERT (strcmp (argv[0], "program") == 0);
850 4 : ASSERT (strcmp (argv[1], "-p") == 0);
851 4 : ASSERT (strcmp (argv[2], "billy") == 0);
852 4 : ASSERT (strcmp (argv[3], "-a") == 0);
853 4 : ASSERT (strcmp (argv[4], "--") == 0);
854 4 : ASSERT (strcmp (argv[5], "donald") == 0);
855 4 : ASSERT (strcmp (argv[6], "duck") == 0);
856 4 : ASSERT (strcmp (argv[7], "-b") == 0);
857 4 : ASSERT (strcmp (argv[8], "foo") == 0);
858 4 : ASSERT (strcmp (argv[9], "-q") == 0);
859 4 : ASSERT (strcmp (argv[10], "johnny") == 0);
860 4 : ASSERT (strcmp (argv[11], "bar") == 0);
861 4 : ASSERT (argv[12] == NULL);
862 4 : ASSERT (a_seen == 1);
863 4 : ASSERT (b_seen == 0);
864 4 : ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
865 4 : ASSERT (q_value == NULL);
866 4 : ASSERT (non_options_count == 0);
867 4 : ASSERT (unrecognized == 0);
868 4 : ASSERT (optind == 5);
869 4 : 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 12 : for (start = OPTIND_MIN; start <= 1; start++)
1197 : {
1198 8 : int a_seen = 0;
1199 8 : int b_seen = 0;
1200 8 : const char *p_value = NULL;
1201 8 : const char *q_value = NULL;
1202 8 : int non_options_count = 0;
1203 : const char *non_options[10];
1204 8 : int unrecognized = 0;
1205 : bool output;
1206 8 : int argc = 0;
1207 : const char *argv[10];
1208 :
1209 8 : argv[argc++] = "program";
1210 8 : argv[argc++] = "donald";
1211 8 : argv[argc++] = "-p";
1212 8 : argv[argc++] = "billy";
1213 8 : argv[argc++] = "duck";
1214 8 : argv[argc++] = "-a";
1215 8 : argv[argc++] = "bar";
1216 8 : argv[argc] = NULL;
1217 8 : optind = start;
1218 8 : opterr = 1;
1219 8 : getopt_loop (argc, argv, "abp:q:+",
1220 : &a_seen, &b_seen, &p_value, &q_value,
1221 : &non_options_count, non_options, &unrecognized, &output);
1222 8 : if (posixly)
1223 : {
1224 4 : ASSERT (strcmp (argv[0], "program") == 0);
1225 4 : ASSERT (strcmp (argv[1], "donald") == 0);
1226 4 : ASSERT (strcmp (argv[2], "-p") == 0);
1227 4 : ASSERT (strcmp (argv[3], "billy") == 0);
1228 4 : ASSERT (strcmp (argv[4], "duck") == 0);
1229 4 : ASSERT (strcmp (argv[5], "-a") == 0);
1230 4 : ASSERT (strcmp (argv[6], "bar") == 0);
1231 4 : ASSERT (argv[7] == NULL);
1232 4 : ASSERT (a_seen == 0);
1233 4 : ASSERT (b_seen == 0);
1234 4 : ASSERT (p_value == NULL);
1235 4 : ASSERT (q_value == NULL);
1236 4 : ASSERT (non_options_count == 0);
1237 4 : ASSERT (unrecognized == 0);
1238 4 : ASSERT (optind == 1);
1239 4 : ASSERT (!output);
1240 : }
1241 : else
1242 : {
1243 4 : ASSERT (strcmp (argv[0], "program") == 0);
1244 4 : ASSERT (strcmp (argv[1], "-p") == 0);
1245 4 : ASSERT (strcmp (argv[2], "billy") == 0);
1246 4 : ASSERT (strcmp (argv[3], "-a") == 0);
1247 4 : ASSERT (strcmp (argv[4], "donald") == 0);
1248 4 : ASSERT (strcmp (argv[5], "duck") == 0);
1249 4 : ASSERT (strcmp (argv[6], "bar") == 0);
1250 4 : ASSERT (argv[7] == NULL);
1251 4 : ASSERT (a_seen == 1);
1252 4 : ASSERT (b_seen == 0);
1253 4 : ASSERT (p_value != NULL && strcmp (p_value, "billy") == 0);
1254 4 : ASSERT (q_value == NULL);
1255 4 : ASSERT (non_options_count == 0);
1256 4 : ASSERT (unrecognized == 0);
1257 4 : ASSERT (optind == 4);
1258 4 : 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 : https://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 4 : }
|