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 : }