* getopt_internal -- * Parse argc/argv argument vector. Called by user level routines. */
| 321 | * Parse argc/argv argument vector. Called by user level routines. |
| 322 | */ |
| 323 | static int getopt_internal( |
| 324 | int nargc, char* const* nargv, char const* options, const struct option* long_options, int* idx, int flags) |
| 325 | { |
| 326 | char const* oli; /* option letter list index */ |
| 327 | int optchar, short_too; |
| 328 | static int posixly_correct = -1; |
| 329 | |
| 330 | if (options == NULL) |
| 331 | return (-1); |
| 332 | |
| 333 | /* |
| 334 | * XXX Some GNU programs (like cvs) set optind to 0 instead of |
| 335 | * XXX using optreset. Work around this braindamage. |
| 336 | */ |
| 337 | if (optind == 0) |
| 338 | optind = optreset = 1; |
| 339 | |
| 340 | /* |
| 341 | * Disable GNU extensions if POSIXLY_CORRECT is set or options |
| 342 | * string begins with a '+'. |
| 343 | * |
| 344 | * CV, 2009-12-14: Check POSIXLY_CORRECT anew if optind == 0 or |
| 345 | * optreset != 0 for GNU compatibility. |
| 346 | */ |
| 347 | if (posixly_correct == -1 || optreset != 0) |
| 348 | posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); |
| 349 | if (*options == '-') |
| 350 | flags |= FLAG_ALLARGS; |
| 351 | else if (posixly_correct || *options == '+') |
| 352 | flags &= ~FLAG_PERMUTE; |
| 353 | if (*options == '+' || *options == '-') |
| 354 | options++; |
| 355 | |
| 356 | optarg = NULL; |
| 357 | if (optreset) |
| 358 | nonopt_start = nonopt_end = -1; |
| 359 | start: |
| 360 | if (optreset || !*place) |
| 361 | { /* update scanning pointer */ |
| 362 | optreset = 0; |
| 363 | if (optind >= nargc) |
| 364 | { /* end of argument vector */ |
| 365 | place = EMSG; |
| 366 | if (nonopt_end != -1) |
| 367 | { |
| 368 | /* do permutation, if we have to */ |
| 369 | permute_args(nonopt_start, nonopt_end, optind, nargv); |
| 370 | optind -= nonopt_end - nonopt_start; |
| 371 | } |
| 372 | else if (nonopt_start != -1) |
| 373 | { |
| 374 | /* |
| 375 | * If we skipped non-options, set optind |
| 376 | * to the first of them. |
| 377 | */ |
| 378 | optind = nonopt_start; |
| 379 | } |
| 380 | nonopt_start = nonopt_end = -1; |
no test coverage detected