|
|
1.1 ! root 1: /* Getopt for GNU. ! 2: NOTE: getopt is now part of the C library, so if you don't know what ! 3: "Keep this file name-space clean" means, talk to [email protected] ! 4: before changing it! ! 5: ! 6: Copyright (C) 1987, 88, 89, 90, 91, 1992 Free Software Foundation, Inc. ! 7: ! 8: This file is part of the libiberty library. ! 9: Libiberty is free software; you can redistribute it and/or ! 10: modify it under the terms of the GNU Library General Public ! 11: License as published by the Free Software Foundation; either ! 12: version 2 of the License, or (at your option) any later version. ! 13: ! 14: Libiberty is distributed in the hope that it will be useful, ! 15: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 16: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 17: Library General Public License for more details. ! 18: ! 19: You should have received a copy of the GNU Library General Public ! 20: License along with libiberty; see the file COPYING.LIB. If ! 21: not, write to the Free Software Foundation, Inc., 675 Mass Ave, ! 22: Cambridge, MA 02139, USA. */ ! 23: ! 24: /* AIX requires this to be the first thing in the file. */ ! 25: #ifdef __GNUC__ ! 26: #define alloca __builtin_alloca ! 27: #else /* not __GNUC__ */ ! 28: #if defined (HAVE_ALLOCA_H) || (defined(sparc) && (defined(sun) || (!defined(USG) && !defined(SVR4) && !defined(__svr4__)))) ! 29: #include <alloca.h> ! 30: #else ! 31: #ifdef _AIX ! 32: #pragma alloca ! 33: #else ! 34: char *alloca (); ! 35: #endif ! 36: #endif /* alloca.h */ ! 37: #endif /* not __GNUC__ */ ! 38: ! 39: #include <stdio.h> ! 40: ! 41: /* This needs to come after some library #include ! 42: to get __GNU_LIBRARY__ defined. */ ! 43: #ifdef __GNU_LIBRARY__ ! 44: #undef alloca ! 45: #include <stdlib.h> ! 46: #include <string.h> ! 47: #else /* Not GNU C library. */ ! 48: #define __alloca alloca ! 49: #endif /* GNU C library. */ ! 50: ! 51: ! 52: #ifndef __STDC__ ! 53: #define const ! 54: #endif ! 55: ! 56: /* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a ! 57: long-named option. Because this is not POSIX.2 compliant, it is ! 58: being phased out. */ ! 59: #define GETOPT_COMPAT ! 60: ! 61: /* This version of `getopt' appears to the caller like standard Unix `getopt' ! 62: but it behaves differently for the user, since it allows the user ! 63: to intersperse the options with the other arguments. ! 64: ! 65: As `getopt' works, it permutes the elements of ARGV so that, ! 66: when it is done, all the options precede everything else. Thus ! 67: all application programs are extended to handle flexible argument order. ! 68: ! 69: Setting the environment variable POSIXLY_CORRECT disables permutation. ! 70: Then the behavior is completely standard. ! 71: ! 72: GNU application programs can use a third alternative mode in which ! 73: they can distinguish the relative order of options and other arguments. */ ! 74: ! 75: #include "getopt.h" ! 76: ! 77: /* For communication from `getopt' to the caller. ! 78: When `getopt' finds an option that takes an argument, ! 79: the argument value is returned here. ! 80: Also, when `ordering' is RETURN_IN_ORDER, ! 81: each non-option ARGV-element is returned here. */ ! 82: ! 83: char *optarg = 0; ! 84: ! 85: /* Index in ARGV of the next element to be scanned. ! 86: This is used for communication to and from the caller ! 87: and for communication between successive calls to `getopt'. ! 88: ! 89: On entry to `getopt', zero means this is the first call; initialize. ! 90: ! 91: When `getopt' returns EOF, this is the index of the first of the ! 92: non-option elements that the caller should itself scan. ! 93: ! 94: Otherwise, `optind' communicates from one call to the next ! 95: how much of ARGV has been scanned so far. */ ! 96: ! 97: int optind = 0; ! 98: ! 99: /* The next char to be scanned in the option-element ! 100: in which the last option character we returned was found. ! 101: This allows us to pick up the scan where we left off. ! 102: ! 103: If this is zero, or a null string, it means resume the scan ! 104: by advancing to the next ARGV-element. */ ! 105: ! 106: static char *nextchar; ! 107: ! 108: /* Callers store zero here to inhibit the error message ! 109: for unrecognized options. */ ! 110: ! 111: int opterr = 1; ! 112: ! 113: /* Describe how to deal with options that follow non-option ARGV-elements. ! 114: ! 115: If the caller did not specify anything, ! 116: the default is REQUIRE_ORDER if the environment variable ! 117: POSIXLY_CORRECT is defined, PERMUTE otherwise. ! 118: ! 119: REQUIRE_ORDER means don't recognize them as options; ! 120: stop option processing when the first non-option is seen. ! 121: This is what Unix does. ! 122: This mode of operation is selected by either setting the environment ! 123: variable POSIXLY_CORRECT, or using `+' as the first character ! 124: of the list of option characters. ! 125: ! 126: PERMUTE is the default. We permute the contents of ARGV as we scan, ! 127: so that eventually all the non-options are at the end. This allows options ! 128: to be given in any order, even with programs that were not written to ! 129: expect this. ! 130: ! 131: RETURN_IN_ORDER is an option available to programs that were written ! 132: to expect options and other ARGV-elements in any order and that care about ! 133: the ordering of the two. We describe each non-option ARGV-element ! 134: as if it were the argument of an option with character code 1. ! 135: Using `-' as the first character of the list of option characters ! 136: selects this mode of operation. ! 137: ! 138: The special argument `--' forces an end of option-scanning regardless ! 139: of the value of `ordering'. In the case of RETURN_IN_ORDER, only ! 140: `--' can cause `getopt' to return EOF with `optind' != ARGC. */ ! 141: ! 142: static enum ! 143: { ! 144: REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER ! 145: } ordering; ! 146: ! 147: #ifdef __GNU_LIBRARY__ ! 148: #include <string.h> ! 149: #define my_index strchr ! 150: #define my_bcopy(src, dst, n) memcpy ((dst), (src), (n)) ! 151: #else ! 152: ! 153: /* Avoid depending on library functions or files ! 154: whose names are inconsistent. */ ! 155: ! 156: char *getenv (); ! 157: ! 158: static char * ! 159: my_index (string, chr) ! 160: const char *string; ! 161: int chr; ! 162: { ! 163: while (*string) ! 164: { ! 165: if (*string == chr) ! 166: return (char *) string; ! 167: string++; ! 168: } ! 169: return 0; ! 170: } ! 171: ! 172: static void ! 173: my_bcopy (from, to, size) ! 174: char *from, *to; ! 175: int size; ! 176: { ! 177: int i; ! 178: for (i = 0; i < size; i++) ! 179: to[i] = from[i]; ! 180: } ! 181: #endif /* GNU C library. */ ! 182: ! 183: /* Handle permutation of arguments. */ ! 184: ! 185: /* Describe the part of ARGV that contains non-options that have ! 186: been skipped. `first_nonopt' is the index in ARGV of the first of them; ! 187: `last_nonopt' is the index after the last of them. */ ! 188: ! 189: static int first_nonopt; ! 190: static int last_nonopt; ! 191: ! 192: /* Exchange two adjacent subsequences of ARGV. ! 193: One subsequence is elements [first_nonopt,last_nonopt) ! 194: which contains all the non-options that have been skipped so far. ! 195: The other is elements [last_nonopt,optind), which contains all ! 196: the options processed since those non-options were skipped. ! 197: ! 198: `first_nonopt' and `last_nonopt' are relocated so that they describe ! 199: the new indices of the non-options in ARGV after they are moved. */ ! 200: ! 201: static void ! 202: exchange (argv) ! 203: char **argv; ! 204: { ! 205: int nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *); ! 206: char **temp = (char **) __alloca (nonopts_size); ! 207: ! 208: /* Interchange the two blocks of data in ARGV. */ ! 209: ! 210: my_bcopy ((char *)&argv[first_nonopt], (char *)temp, ! 211: nonopts_size); ! 212: my_bcopy ((char *)&argv[last_nonopt], (char *)&argv[first_nonopt], ! 213: (optind - last_nonopt) * sizeof (char *)); ! 214: my_bcopy ((char *)temp, (char *)&argv[first_nonopt + optind - last_nonopt], ! 215: nonopts_size); ! 216: ! 217: /* Update records for the slots the non-options now occupy. */ ! 218: ! 219: first_nonopt += (optind - last_nonopt); ! 220: last_nonopt = optind; ! 221: } ! 222: ! 223: /* Scan elements of ARGV (whose length is ARGC) for option characters ! 224: given in OPTSTRING. ! 225: ! 226: If an element of ARGV starts with '-', and is not exactly "-" or "--", ! 227: then it is an option element. The characters of this element ! 228: (aside from the initial '-') are option characters. If `getopt' ! 229: is called repeatedly, it returns successively each of the option characters ! 230: from each of the option elements. ! 231: ! 232: If `getopt' finds another option character, it returns that character, ! 233: updating `optind' and `nextchar' so that the next call to `getopt' can ! 234: resume the scan with the following option character or ARGV-element. ! 235: ! 236: If there are no more option characters, `getopt' returns `EOF'. ! 237: Then `optind' is the index in ARGV of the first ARGV-element ! 238: that is not an option. (The ARGV-elements have been permuted ! 239: so that those that are not options now come last.) ! 240: ! 241: OPTSTRING is a string containing the legitimate option characters. ! 242: If an option character is seen that is not listed in OPTSTRING, ! 243: return '?' after printing an error message. If you set `opterr' to ! 244: zero, the error message is suppressed but we still return '?'. ! 245: ! 246: If a char in OPTSTRING is followed by a colon, that means it wants an arg, ! 247: so the following text in the same ARGV-element, or the text of the following ! 248: ARGV-element, is returned in `optarg'. Two colons mean an option that ! 249: wants an optional arg; if there is text in the current ARGV-element, ! 250: it is returned in `optarg', otherwise `optarg' is set to zero. ! 251: ! 252: If OPTSTRING starts with `-' or `+', it requests different methods of ! 253: handling the non-option ARGV-elements. ! 254: See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. ! 255: ! 256: Long-named options begin with `--' instead of `-'. ! 257: Their names may be abbreviated as long as the abbreviation is unique ! 258: or is an exact match for some defined option. If they have an ! 259: argument, it follows the option name in the same ARGV-element, separated ! 260: from the option name by a `=', or else the in next ARGV-element. ! 261: When `getopt' finds a long-named option, it returns 0 if that option's ! 262: `flag' field is nonzero, the value of the option's `val' field ! 263: if the `flag' field is zero. ! 264: ! 265: The elements of ARGV aren't really const, because we permute them. ! 266: But we pretend they're const in the prototype to be compatible ! 267: with other systems. ! 268: ! 269: LONGOPTS is a vector of `struct option' terminated by an ! 270: element containing a name which is zero. ! 271: ! 272: LONGIND returns the index in LONGOPT of the long-named option found. ! 273: It is only valid when a long-named option has been found by the most ! 274: recent call. ! 275: ! 276: If LONG_ONLY is nonzero, '-' as well as '--' can introduce ! 277: long-named options. */ ! 278: ! 279: int ! 280: _getopt_internal (argc, argv, optstring, longopts, longind, long_only) ! 281: int argc; ! 282: char *const *argv; ! 283: const char *optstring; ! 284: const struct option *longopts; ! 285: int *longind; ! 286: int long_only; ! 287: { ! 288: int option_index; ! 289: ! 290: optarg = 0; ! 291: ! 292: /* Initialize the internal data when the first call is made. ! 293: Start processing options with ARGV-element 1 (since ARGV-element 0 ! 294: is the program name); the sequence of previously skipped ! 295: non-option ARGV-elements is empty. */ ! 296: ! 297: if (optind == 0) ! 298: { ! 299: first_nonopt = last_nonopt = optind = 1; ! 300: ! 301: nextchar = NULL; ! 302: ! 303: /* Determine how to handle the ordering of options and nonoptions. */ ! 304: ! 305: if (optstring[0] == '-') ! 306: { ! 307: ordering = RETURN_IN_ORDER; ! 308: ++optstring; ! 309: } ! 310: else if (optstring[0] == '+') ! 311: { ! 312: ordering = REQUIRE_ORDER; ! 313: ++optstring; ! 314: } ! 315: else if (getenv ("POSIXLY_CORRECT") != NULL) ! 316: ordering = REQUIRE_ORDER; ! 317: else ! 318: ordering = PERMUTE; ! 319: } ! 320: ! 321: if (nextchar == NULL || *nextchar == '\0') ! 322: { ! 323: if (ordering == PERMUTE) ! 324: { ! 325: /* If we have just processed some options following some non-options, ! 326: exchange them so that the options come first. */ ! 327: ! 328: if (first_nonopt != last_nonopt && last_nonopt != optind) ! 329: exchange ((char **) argv); ! 330: else if (last_nonopt != optind) ! 331: first_nonopt = optind; ! 332: ! 333: /* Now skip any additional non-options ! 334: and extend the range of non-options previously skipped. */ ! 335: ! 336: while (optind < argc ! 337: && (argv[optind][0] != '-' || argv[optind][1] == '\0') ! 338: #ifdef GETOPT_COMPAT ! 339: && (longopts == NULL ! 340: || argv[optind][0] != '+' || argv[optind][1] == '\0') ! 341: #endif /* GETOPT_COMPAT */ ! 342: ) ! 343: optind++; ! 344: last_nonopt = optind; ! 345: } ! 346: ! 347: /* Special ARGV-element `--' means premature end of options. ! 348: Skip it like a null option, ! 349: then exchange with previous non-options as if it were an option, ! 350: then skip everything else like a non-option. */ ! 351: ! 352: if (optind != argc && !strcmp (argv[optind], "--")) ! 353: { ! 354: optind++; ! 355: ! 356: if (first_nonopt != last_nonopt && last_nonopt != optind) ! 357: exchange ((char **) argv); ! 358: else if (first_nonopt == last_nonopt) ! 359: first_nonopt = optind; ! 360: last_nonopt = argc; ! 361: ! 362: optind = argc; ! 363: } ! 364: ! 365: /* If we have done all the ARGV-elements, stop the scan ! 366: and back over any non-options that we skipped and permuted. */ ! 367: ! 368: if (optind == argc) ! 369: { ! 370: /* Set the next-arg-index to point at the non-options ! 371: that we previously skipped, so the caller will digest them. */ ! 372: if (first_nonopt != last_nonopt) ! 373: optind = first_nonopt; ! 374: return EOF; ! 375: } ! 376: ! 377: /* If we have come to a non-option and did not permute it, ! 378: either stop the scan or describe it to the caller and pass it by. */ ! 379: ! 380: if ((argv[optind][0] != '-' || argv[optind][1] == '\0') ! 381: #ifdef GETOPT_COMPAT ! 382: && (longopts == NULL ! 383: || argv[optind][0] != '+' || argv[optind][1] == '\0') ! 384: #endif /* GETOPT_COMPAT */ ! 385: ) ! 386: { ! 387: if (ordering == REQUIRE_ORDER) ! 388: return EOF; ! 389: optarg = argv[optind++]; ! 390: return 1; ! 391: } ! 392: ! 393: /* We have found another option-ARGV-element. ! 394: Start decoding its characters. */ ! 395: ! 396: nextchar = (argv[optind] + 1 ! 397: + (longopts != NULL && argv[optind][1] == '-')); ! 398: } ! 399: ! 400: if (longopts != NULL ! 401: && ((argv[optind][0] == '-' ! 402: && (argv[optind][1] == '-' || long_only)) ! 403: #ifdef GETOPT_COMPAT ! 404: || argv[optind][0] == '+' ! 405: #endif /* GETOPT_COMPAT */ ! 406: )) ! 407: { ! 408: const struct option *p; ! 409: char *s = nextchar; ! 410: int exact = 0; ! 411: int ambig = 0; ! 412: const struct option *pfound = NULL; ! 413: int indfound; ! 414: ! 415: while (*s && *s != '=') ! 416: s++; ! 417: ! 418: /* Test all options for either exact match or abbreviated matches. */ ! 419: for (p = longopts, option_index = 0; p->name; ! 420: p++, option_index++) ! 421: if (!strncmp (p->name, nextchar, s - nextchar)) ! 422: { ! 423: if (s - nextchar == strlen (p->name)) ! 424: { ! 425: /* Exact match found. */ ! 426: pfound = p; ! 427: indfound = option_index; ! 428: exact = 1; ! 429: break; ! 430: } ! 431: else if (pfound == NULL) ! 432: { ! 433: /* First nonexact match found. */ ! 434: pfound = p; ! 435: indfound = option_index; ! 436: } ! 437: else ! 438: /* Second nonexact match found. */ ! 439: ambig = 1; ! 440: } ! 441: ! 442: if (ambig && !exact) ! 443: { ! 444: if (opterr) ! 445: fprintf (stderr, "%s: option `%s' is ambiguous\n", ! 446: argv[0], argv[optind]); ! 447: nextchar += strlen (nextchar); ! 448: optind++; ! 449: return '?'; ! 450: } ! 451: ! 452: if (pfound != NULL) ! 453: { ! 454: option_index = indfound; ! 455: optind++; ! 456: if (*s) ! 457: { ! 458: /* Don't test has_arg with >, because some C compilers don't ! 459: allow it to be used on enums. */ ! 460: if (pfound->has_arg) ! 461: optarg = s + 1; ! 462: else ! 463: { ! 464: if (opterr) ! 465: { ! 466: if (argv[optind - 1][1] == '-') ! 467: /* --option */ ! 468: fprintf (stderr, ! 469: "%s: option `--%s' doesn't allow an argument\n", ! 470: argv[0], pfound->name); ! 471: else ! 472: /* +option or -option */ ! 473: fprintf (stderr, ! 474: "%s: option `%c%s' doesn't allow an argument\n", ! 475: argv[0], argv[optind - 1][0], pfound->name); ! 476: } ! 477: nextchar += strlen (nextchar); ! 478: return '?'; ! 479: } ! 480: } ! 481: else if (pfound->has_arg == 1) ! 482: { ! 483: if (optind < argc) ! 484: optarg = argv[optind++]; ! 485: else ! 486: { ! 487: if (opterr) ! 488: fprintf (stderr, "%s: option `%s' requires an argument\n", ! 489: argv[0], argv[optind - 1]); ! 490: nextchar += strlen (nextchar); ! 491: return '?'; ! 492: } ! 493: } ! 494: nextchar += strlen (nextchar); ! 495: if (longind != NULL) ! 496: *longind = option_index; ! 497: if (pfound->flag) ! 498: { ! 499: *(pfound->flag) = pfound->val; ! 500: return 0; ! 501: } ! 502: return pfound->val; ! 503: } ! 504: /* Can't find it as a long option. If this is not getopt_long_only, ! 505: or the option starts with '--' or is not a valid short ! 506: option, then it's an error. ! 507: Otherwise interpret it as a short option. */ ! 508: if (!long_only || argv[optind][1] == '-' ! 509: #ifdef GETOPT_COMPAT ! 510: || argv[optind][0] == '+' ! 511: #endif /* GETOPT_COMPAT */ ! 512: || my_index (optstring, *nextchar) == NULL) ! 513: { ! 514: if (opterr) ! 515: { ! 516: if (argv[optind][1] == '-') ! 517: /* --option */ ! 518: fprintf (stderr, "%s: unrecognized option `--%s'\n", ! 519: argv[0], nextchar); ! 520: else ! 521: /* +option or -option */ ! 522: fprintf (stderr, "%s: unrecognized option `%c%s'\n", ! 523: argv[0], argv[optind][0], nextchar); ! 524: } ! 525: nextchar = (char *) ""; ! 526: optind++; ! 527: return '?'; ! 528: } ! 529: } ! 530: ! 531: /* Look at and handle the next option-character. */ ! 532: ! 533: { ! 534: char c = *nextchar++; ! 535: char *temp = my_index (optstring, c); ! 536: ! 537: /* Increment `optind' when we start to process its last character. */ ! 538: if (*nextchar == '\0') ! 539: ++optind; ! 540: ! 541: if (temp == NULL || c == ':') ! 542: { ! 543: if (opterr) ! 544: { ! 545: if (c < 040 || c >= 0177) ! 546: fprintf (stderr, "%s: unrecognized option, character code 0%o\n", ! 547: argv[0], c); ! 548: else ! 549: fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c); ! 550: } ! 551: return '?'; ! 552: } ! 553: if (temp[1] == ':') ! 554: { ! 555: if (temp[2] == ':') ! 556: { ! 557: /* This is an option that accepts an argument optionally. */ ! 558: if (*nextchar != '\0') ! 559: { ! 560: optarg = nextchar; ! 561: optind++; ! 562: } ! 563: else ! 564: optarg = 0; ! 565: nextchar = NULL; ! 566: } ! 567: else ! 568: { ! 569: /* This is an option that requires an argument. */ ! 570: if (*nextchar != '\0') ! 571: { ! 572: optarg = nextchar; ! 573: /* If we end this ARGV-element by taking the rest as an arg, ! 574: we must advance to the next element now. */ ! 575: optind++; ! 576: } ! 577: else if (optind == argc) ! 578: { ! 579: if (opterr) ! 580: fprintf (stderr, "%s: option `-%c' requires an argument\n", ! 581: argv[0], c); ! 582: c = '?'; ! 583: } ! 584: else ! 585: /* We already incremented `optind' once; ! 586: increment it again when taking next ARGV-elt as argument. */ ! 587: optarg = argv[optind++]; ! 588: nextchar = NULL; ! 589: } ! 590: } ! 591: return c; ! 592: } ! 593: } ! 594: ! 595: int ! 596: getopt (argc, argv, optstring) ! 597: int argc; ! 598: char *const *argv; ! 599: const char *optstring; ! 600: { ! 601: return _getopt_internal (argc, argv, optstring, ! 602: (const struct option *) 0, ! 603: (int *) 0, ! 604: 0); ! 605: } ! 606: ! 607: #ifdef TEST ! 608: ! 609: /* Compile with -DTEST to make an executable for use in testing ! 610: the above definition of `getopt'. */ ! 611: ! 612: int ! 613: main (argc, argv) ! 614: int argc; ! 615: char **argv; ! 616: { ! 617: int c; ! 618: int digit_optind = 0; ! 619: ! 620: while (1) ! 621: { ! 622: int this_option_optind = optind ? optind : 1; ! 623: ! 624: c = getopt (argc, argv, "abc:d:0123456789"); ! 625: if (c == EOF) ! 626: break; ! 627: ! 628: switch (c) ! 629: { ! 630: case '0': ! 631: case '1': ! 632: case '2': ! 633: case '3': ! 634: case '4': ! 635: case '5': ! 636: case '6': ! 637: case '7': ! 638: case '8': ! 639: case '9': ! 640: if (digit_optind != 0 && digit_optind != this_option_optind) ! 641: printf ("digits occur in two different argv-elements.\n"); ! 642: digit_optind = this_option_optind; ! 643: printf ("option %c\n", c); ! 644: break; ! 645: ! 646: case 'a': ! 647: printf ("option a\n"); ! 648: break; ! 649: ! 650: case 'b': ! 651: printf ("option b\n"); ! 652: break; ! 653: ! 654: case 'c': ! 655: printf ("option c with value `%s'\n", optarg); ! 656: break; ! 657: ! 658: case '?': ! 659: break; ! 660: ! 661: default: ! 662: printf ("?? getopt returned character code 0%o ??\n", c); ! 663: } ! 664: } ! 665: ! 666: if (optind < argc) ! 667: { ! 668: printf ("non-option ARGV-elements: "); ! 669: while (optind < argc) ! 670: printf ("%s ", argv[optind++]); ! 671: printf ("\n"); ! 672: } ! 673: ! 674: exit (0); ! 675: } ! 676: ! 677: #endif /* TEST */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.