Annotation of embedaddon/quagga/lib/getopt.c, revision 1.1
1.1 ! misho 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 drepper@gnu.org
! 4: before changing it!
! 5:
! 6: Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98
! 7: Free Software Foundation, Inc.
! 8:
! 9: NOTE: The canonical source of this file is maintained with the GNU C Library.
! 10: Bugs can be reported to bug-glibc@gnu.org.
! 11:
! 12: This program is free software; you can redistribute it and/or modify it
! 13: under the terms of the GNU General Public License as published by the
! 14: Free Software Foundation; either version 2, or (at your option) any
! 15: later version.
! 16:
! 17: This program is distributed in the hope that it will be useful,
! 18: but WITHOUT ANY WARRANTY; without even the implied warranty of
! 19: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! 20: GNU General Public License for more details.
! 21:
! 22: You should have received a copy of the GNU General Public License
! 23: along with this program; if not, write to the Free Software
! 24: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
! 25: USA. */
! 26:
! 27: /* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
! 28: Ditto for AIX 3.2 and <stdlib.h>. */
! 29: #ifndef _NO_PROTO
! 30: # define _NO_PROTO
! 31: #endif
! 32:
! 33: #ifdef HAVE_CONFIG_H
! 34: # include <config.h>
! 35: #endif
! 36:
! 37: #include <zebra.h>
! 38:
! 39: #if !defined __STDC__ || !__STDC__
! 40: /* This is a separate conditional since some stdc systems
! 41: reject `defined (const)'. */
! 42: # ifndef const
! 43: # define const
! 44: # endif
! 45: #endif
! 46:
! 47: #include <stdio.h>
! 48:
! 49: /* Comment out all this code if we are using the GNU C Library, and are not
! 50: actually compiling the library itself. This code is part of the GNU C
! 51: Library, but also included in many other GNU distributions. Compiling
! 52: and linking in this code is a waste when using the GNU C library
! 53: (especially if it is a shared library). Rather than having every GNU
! 54: program understand `configure --with-gnu-libc' and omit the object files,
! 55: it is simpler to just do this in the source for each such file. */
! 56:
! 57: #define GETOPT_INTERFACE_VERSION 2
! 58: #if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
! 59: # include <gnu-versions.h>
! 60: # if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
! 61: # define ELIDE_CODE
! 62: # endif
! 63: #endif
! 64:
! 65: #ifndef ELIDE_CODE
! 66:
! 67:
! 68: /* This needs to come after some library #include
! 69: to get __GNU_LIBRARY__ defined. */
! 70: #ifdef __GNU_LIBRARY__
! 71: /* Don't include stdlib.h for non-GNU C libraries because some of them
! 72: contain conflicting prototypes for getopt. */
! 73: # include <stdlib.h>
! 74: # include <unistd.h>
! 75: #endif /* GNU C library. */
! 76:
! 77: #ifdef VMS
! 78: # include <unixlib.h>
! 79: # if HAVE_STRING_H - 0
! 80: # include <string.h>
! 81: # endif
! 82: #endif
! 83:
! 84: #ifndef _
! 85: /* This is for other GNU distributions with internationalized messages.
! 86: When compiling libc, the _ macro is predefined. */
! 87: # ifdef HAVE_LIBINTL_H
! 88: # include <libintl.h>
! 89: # define _(msgid) gettext (msgid)
! 90: # else
! 91: # define _(msgid) (msgid)
! 92: # endif
! 93: #endif
! 94:
! 95: /* This version of `getopt' appears to the caller like standard Unix `getopt'
! 96: but it behaves differently for the user, since it allows the user
! 97: to intersperse the options with the other arguments.
! 98:
! 99: As `getopt' works, it permutes the elements of ARGV so that,
! 100: when it is done, all the options precede everything else. Thus
! 101: all application programs are extended to handle flexible argument order.
! 102:
! 103: Setting the environment variable POSIXLY_CORRECT disables permutation.
! 104: Then the behavior is completely standard.
! 105:
! 106: GNU application programs can use a third alternative mode in which
! 107: they can distinguish the relative order of options and other arguments. */
! 108:
! 109: #include "getopt.h"
! 110:
! 111: /* For communication from `getopt' to the caller.
! 112: When `getopt' finds an option that takes an argument,
! 113: the argument value is returned here.
! 114: Also, when `ordering' is RETURN_IN_ORDER,
! 115: each non-option ARGV-element is returned here. */
! 116:
! 117: char *optarg = NULL;
! 118:
! 119: /* Index in ARGV of the next element to be scanned.
! 120: This is used for communication to and from the caller
! 121: and for communication between successive calls to `getopt'.
! 122:
! 123: On entry to `getopt', zero means this is the first call; initialize.
! 124:
! 125: When `getopt' returns -1, this is the index of the first of the
! 126: non-option elements that the caller should itself scan.
! 127:
! 128: Otherwise, `optind' communicates from one call to the next
! 129: how much of ARGV has been scanned so far. */
! 130:
! 131: /* 1003.2 says this must be 1 before any call. */
! 132: int optind = 1;
! 133:
! 134: /* Formerly, initialization of getopt depended on optind==0, which
! 135: causes problems with re-calling getopt as programs generally don't
! 136: know that. */
! 137:
! 138: int __getopt_initialized = 0;
! 139:
! 140: /* The next char to be scanned in the option-element
! 141: in which the last option character we returned was found.
! 142: This allows us to pick up the scan where we left off.
! 143:
! 144: If this is zero, or a null string, it means resume the scan
! 145: by advancing to the next ARGV-element. */
! 146:
! 147: static char *nextchar;
! 148:
! 149: /* Callers store zero here to inhibit the error message
! 150: for unrecognized options. */
! 151:
! 152: int opterr = 1;
! 153:
! 154: /* Set to an option character which was unrecognized.
! 155: This must be initialized on some systems to avoid linking in the
! 156: system's own getopt implementation. */
! 157:
! 158: int optopt = '?';
! 159:
! 160: /* Describe how to deal with options that follow non-option ARGV-elements.
! 161:
! 162: If the caller did not specify anything,
! 163: the default is REQUIRE_ORDER if the environment variable
! 164: POSIXLY_CORRECT is defined, PERMUTE otherwise.
! 165:
! 166: REQUIRE_ORDER means don't recognize them as options;
! 167: stop option processing when the first non-option is seen.
! 168: This is what Unix does.
! 169: This mode of operation is selected by either setting the environment
! 170: variable POSIXLY_CORRECT, or using `+' as the first character
! 171: of the list of option characters.
! 172:
! 173: PERMUTE is the default. We permute the contents of ARGV as we scan,
! 174: so that eventually all the non-options are at the end. This allows options
! 175: to be given in any order, even with programs that were not written to
! 176: expect this.
! 177:
! 178: RETURN_IN_ORDER is an option available to programs that were written
! 179: to expect options and other ARGV-elements in any order and that care about
! 180: the ordering of the two. We describe each non-option ARGV-element
! 181: as if it were the argument of an option with character code 1.
! 182: Using `-' as the first character of the list of option characters
! 183: selects this mode of operation.
! 184:
! 185: The special argument `--' forces an end of option-scanning regardless
! 186: of the value of `ordering'. In the case of RETURN_IN_ORDER, only
! 187: `--' can cause `getopt' to return -1 with `optind' != ARGC. */
! 188:
! 189: static enum
! 190: {
! 191: REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
! 192: } ordering;
! 193:
! 194: /* Value of POSIXLY_CORRECT environment variable. */
! 195: static char *posixly_correct;
! 196:
! 197: #ifdef __GNU_LIBRARY__
! 198: /* We want to avoid inclusion of string.h with non-GNU libraries
! 199: because there are many ways it can cause trouble.
! 200: On some systems, it contains special magic macros that don't work
! 201: in GCC. */
! 202: # include <string.h>
! 203: # define my_index strchr
! 204: #else
! 205:
! 206: # if HAVE_STRING_H
! 207: # include <string.h>
! 208: # else
! 209: # include <strings.h>
! 210: # endif
! 211:
! 212: /* Avoid depending on library functions or files
! 213: whose names are inconsistent. */
! 214:
! 215: #ifndef getenv
! 216: extern char *getenv ();
! 217: #endif
! 218:
! 219: static char *
! 220: my_index (str, chr)
! 221: const char *str;
! 222: int chr;
! 223: {
! 224: while (*str)
! 225: {
! 226: if (*str == chr)
! 227: return (char *) str;
! 228: str++;
! 229: }
! 230: return 0;
! 231: }
! 232:
! 233: /* If using GCC, we can safely declare strlen this way.
! 234: If not using GCC, it is ok not to declare it. */
! 235: #ifdef __GNUC__
! 236: /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
! 237: That was relevant to code that was here before. */
! 238: # if (!defined __STDC__ || !__STDC__) && !defined strlen
! 239: /* gcc with -traditional declares the built-in strlen to return int,
! 240: and has done so at least since version 2.4.5. -- rms. */
! 241: extern int strlen (const char *);
! 242: # endif /* not __STDC__ */
! 243: #endif /* __GNUC__ */
! 244:
! 245: #endif /* not __GNU_LIBRARY__ */
! 246:
! 247: /* Handle permutation of arguments. */
! 248:
! 249: /* Describe the part of ARGV that contains non-options that have
! 250: been skipped. `first_nonopt' is the index in ARGV of the first of them;
! 251: `last_nonopt' is the index after the last of them. */
! 252:
! 253: static int first_nonopt;
! 254: static int last_nonopt;
! 255:
! 256: #ifdef _LIBC
! 257: /* Bash 2.0 gives us an environment variable containing flags
! 258: indicating ARGV elements that should not be considered arguments. */
! 259:
! 260: /* Defined in getopt_init.c */
! 261: extern char *__getopt_nonoption_flags;
! 262:
! 263: static int nonoption_flags_max_len;
! 264: static int nonoption_flags_len;
! 265:
! 266: static int original_argc;
! 267: static char *const *original_argv;
! 268:
! 269: /* Make sure the environment variable bash 2.0 puts in the environment
! 270: is valid for the getopt call we must make sure that the ARGV passed
! 271: to getopt is that one passed to the process. */
! 272: static void
! 273: __attribute__ ((unused))
! 274: store_args_and_env (int argc, char *const *argv)
! 275: {
! 276: /* XXX This is no good solution. We should rather copy the args so
! 277: that we can compare them later. But we must not use malloc(3). */
! 278: original_argc = argc;
! 279: original_argv = argv;
! 280: }
! 281: # ifdef text_set_element
! 282: text_set_element (__libc_subinit, store_args_and_env);
! 283: # endif /* text_set_element */
! 284:
! 285: # define SWAP_FLAGS(ch1, ch2) \
! 286: if (nonoption_flags_len > 0) \
! 287: { \
! 288: char __tmp = __getopt_nonoption_flags[ch1]; \
! 289: __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
! 290: __getopt_nonoption_flags[ch2] = __tmp; \
! 291: }
! 292: #else /* !_LIBC */
! 293: # define SWAP_FLAGS(ch1, ch2)
! 294: #endif /* _LIBC */
! 295:
! 296: /* Exchange two adjacent subsequences of ARGV.
! 297: One subsequence is elements [first_nonopt,last_nonopt)
! 298: which contains all the non-options that have been skipped so far.
! 299: The other is elements [last_nonopt,optind), which contains all
! 300: the options processed since those non-options were skipped.
! 301:
! 302: `first_nonopt' and `last_nonopt' are relocated so that they describe
! 303: the new indices of the non-options in ARGV after they are moved. */
! 304:
! 305: #if defined __STDC__ && __STDC__
! 306: static void exchange (char **);
! 307: #endif
! 308:
! 309: static void
! 310: exchange (argv)
! 311: char **argv;
! 312: {
! 313: int bottom = first_nonopt;
! 314: int middle = last_nonopt;
! 315: int top = optind;
! 316: char *tem;
! 317:
! 318: /* Exchange the shorter segment with the far end of the longer segment.
! 319: That puts the shorter segment into the right place.
! 320: It leaves the longer segment in the right place overall,
! 321: but it consists of two parts that need to be swapped next. */
! 322:
! 323: #ifdef _LIBC
! 324: /* First make sure the handling of the `__getopt_nonoption_flags'
! 325: string can work normally. Our top argument must be in the range
! 326: of the string. */
! 327: if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
! 328: {
! 329: /* We must extend the array. The user plays games with us and
! 330: presents new arguments. */
! 331: char *new_str = malloc (top + 1);
! 332: if (new_str == NULL)
! 333: nonoption_flags_len = nonoption_flags_max_len = 0;
! 334: else
! 335: {
! 336: memset (__mempcpy (new_str, __getopt_nonoption_flags,
! 337: nonoption_flags_max_len),
! 338: '\0', top + 1 - nonoption_flags_max_len);
! 339: nonoption_flags_max_len = top + 1;
! 340: __getopt_nonoption_flags = new_str;
! 341: }
! 342: }
! 343: #endif
! 344:
! 345: while (top > middle && middle > bottom)
! 346: {
! 347: if (top - middle > middle - bottom)
! 348: {
! 349: /* Bottom segment is the short one. */
! 350: int len = middle - bottom;
! 351: register int i;
! 352:
! 353: /* Swap it with the top part of the top segment. */
! 354: for (i = 0; i < len; i++)
! 355: {
! 356: tem = argv[bottom + i];
! 357: argv[bottom + i] = argv[top - (middle - bottom) + i];
! 358: argv[top - (middle - bottom) + i] = tem;
! 359: SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
! 360: }
! 361: /* Exclude the moved bottom segment from further swapping. */
! 362: top -= len;
! 363: }
! 364: else
! 365: {
! 366: /* Top segment is the short one. */
! 367: int len = top - middle;
! 368: register int i;
! 369:
! 370: /* Swap it with the bottom part of the bottom segment. */
! 371: for (i = 0; i < len; i++)
! 372: {
! 373: tem = argv[bottom + i];
! 374: argv[bottom + i] = argv[middle + i];
! 375: argv[middle + i] = tem;
! 376: SWAP_FLAGS (bottom + i, middle + i);
! 377: }
! 378: /* Exclude the moved top segment from further swapping. */
! 379: bottom += len;
! 380: }
! 381: }
! 382:
! 383: /* Update records for the slots the non-options now occupy. */
! 384:
! 385: first_nonopt += (optind - last_nonopt);
! 386: last_nonopt = optind;
! 387: }
! 388:
! 389: /* Initialize the internal data when the first call is made. */
! 390:
! 391: #if defined __STDC__ && __STDC__
! 392: static const char *_getopt_initialize (int, char *const *, const char *);
! 393: #endif
! 394: static const char *
! 395: _getopt_initialize (argc, argv, optstring)
! 396: int argc;
! 397: char *const *argv;
! 398: const char *optstring;
! 399: {
! 400: /* Start processing options with ARGV-element 1 (since ARGV-element 0
! 401: is the program name); the sequence of previously skipped
! 402: non-option ARGV-elements is empty. */
! 403:
! 404: first_nonopt = last_nonopt = optind;
! 405:
! 406: nextchar = NULL;
! 407:
! 408: posixly_correct = getenv ("POSIXLY_CORRECT");
! 409:
! 410: /* Determine how to handle the ordering of options and nonoptions. */
! 411:
! 412: if (optstring[0] == '-')
! 413: {
! 414: ordering = RETURN_IN_ORDER;
! 415: ++optstring;
! 416: }
! 417: else if (optstring[0] == '+')
! 418: {
! 419: ordering = REQUIRE_ORDER;
! 420: ++optstring;
! 421: }
! 422: else if (posixly_correct != NULL)
! 423: ordering = REQUIRE_ORDER;
! 424: else
! 425: ordering = PERMUTE;
! 426:
! 427: #ifdef _LIBC
! 428: if (posixly_correct == NULL
! 429: && argc == original_argc && argv == original_argv)
! 430: {
! 431: if (nonoption_flags_max_len == 0)
! 432: {
! 433: if (__getopt_nonoption_flags == NULL
! 434: || __getopt_nonoption_flags[0] == '\0')
! 435: nonoption_flags_max_len = -1;
! 436: else
! 437: {
! 438: const char *orig_str = __getopt_nonoption_flags;
! 439: int len = nonoption_flags_max_len = strlen (orig_str);
! 440: if (nonoption_flags_max_len < argc)
! 441: nonoption_flags_max_len = argc;
! 442: __getopt_nonoption_flags =
! 443: (char *) malloc (nonoption_flags_max_len);
! 444: if (__getopt_nonoption_flags == NULL)
! 445: nonoption_flags_max_len = -1;
! 446: else
! 447: memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
! 448: '\0', nonoption_flags_max_len - len);
! 449: }
! 450: }
! 451: nonoption_flags_len = nonoption_flags_max_len;
! 452: }
! 453: else
! 454: nonoption_flags_len = 0;
! 455: #endif
! 456:
! 457: return optstring;
! 458: }
! 459:
! 460: /* Scan elements of ARGV (whose length is ARGC) for option characters
! 461: given in OPTSTRING.
! 462:
! 463: If an element of ARGV starts with '-', and is not exactly "-" or "--",
! 464: then it is an option element. The characters of this element
! 465: (aside from the initial '-') are option characters. If `getopt'
! 466: is called repeatedly, it returns successively each of the option characters
! 467: from each of the option elements.
! 468:
! 469: If `getopt' finds another option character, it returns that character,
! 470: updating `optind' and `nextchar' so that the next call to `getopt' can
! 471: resume the scan with the following option character or ARGV-element.
! 472:
! 473: If there are no more option characters, `getopt' returns -1.
! 474: Then `optind' is the index in ARGV of the first ARGV-element
! 475: that is not an option. (The ARGV-elements have been permuted
! 476: so that those that are not options now come last.)
! 477:
! 478: OPTSTRING is a string containing the legitimate option characters.
! 479: If an option character is seen that is not listed in OPTSTRING,
! 480: return '?' after printing an error message. If you set `opterr' to
! 481: zero, the error message is suppressed but we still return '?'.
! 482:
! 483: If a char in OPTSTRING is followed by a colon, that means it wants an arg,
! 484: so the following text in the same ARGV-element, or the text of the following
! 485: ARGV-element, is returned in `optarg'. Two colons mean an option that
! 486: wants an optional arg; if there is text in the current ARGV-element,
! 487: it is returned in `optarg', otherwise `optarg' is set to zero.
! 488:
! 489: If OPTSTRING starts with `-' or `+', it requests different methods of
! 490: handling the non-option ARGV-elements.
! 491: See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
! 492:
! 493: Long-named options begin with `--' instead of `-'.
! 494: Their names may be abbreviated as long as the abbreviation is unique
! 495: or is an exact match for some defined option. If they have an
! 496: argument, it follows the option name in the same ARGV-element, separated
! 497: from the option name by a `=', or else the in next ARGV-element.
! 498: When `getopt' finds a long-named option, it returns 0 if that option's
! 499: `flag' field is nonzero, the value of the option's `val' field
! 500: if the `flag' field is zero.
! 501:
! 502: The elements of ARGV aren't really const, because we permute them.
! 503: But we pretend they're const in the prototype to be compatible
! 504: with other systems.
! 505:
! 506: LONGOPTS is a vector of `struct option' terminated by an
! 507: element containing a name which is zero.
! 508:
! 509: LONGIND returns the index in LONGOPT of the long-named option found.
! 510: It is only valid when a long-named option has been found by the most
! 511: recent call.
! 512:
! 513: If LONG_ONLY is nonzero, '-' as well as '--' can introduce
! 514: long-named options. */
! 515:
! 516: int
! 517: _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
! 518: int argc;
! 519: char *const *argv;
! 520: const char *optstring;
! 521: const struct option *longopts;
! 522: int *longind;
! 523: int long_only;
! 524: {
! 525: optarg = NULL;
! 526:
! 527: if (optind == 0 || !__getopt_initialized)
! 528: {
! 529: if (optind == 0)
! 530: optind = 1; /* Don't scan ARGV[0], the program name. */
! 531: optstring = _getopt_initialize (argc, argv, optstring);
! 532: __getopt_initialized = 1;
! 533: }
! 534:
! 535: /* Test whether ARGV[optind] points to a non-option argument.
! 536: Either it does not have option syntax, or there is an environment flag
! 537: from the shell indicating it is not an option. The later information
! 538: is only used when the used in the GNU libc. */
! 539: #ifdef _LIBC
! 540: # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
! 541: || (optind < nonoption_flags_len \
! 542: && __getopt_nonoption_flags[optind] == '1'))
! 543: #else
! 544: # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
! 545: #endif
! 546:
! 547: if (nextchar == NULL || *nextchar == '\0')
! 548: {
! 549: /* Advance to the next ARGV-element. */
! 550:
! 551: /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
! 552: moved back by the user (who may also have changed the arguments). */
! 553: if (last_nonopt > optind)
! 554: last_nonopt = optind;
! 555: if (first_nonopt > optind)
! 556: first_nonopt = optind;
! 557:
! 558: if (ordering == PERMUTE)
! 559: {
! 560: /* If we have just processed some options following some non-options,
! 561: exchange them so that the options come first. */
! 562:
! 563: if (first_nonopt != last_nonopt && last_nonopt != optind)
! 564: exchange ((char **) argv);
! 565: else if (last_nonopt != optind)
! 566: first_nonopt = optind;
! 567:
! 568: /* Skip any additional non-options
! 569: and extend the range of non-options previously skipped. */
! 570:
! 571: while (optind < argc && NONOPTION_P)
! 572: optind++;
! 573: last_nonopt = optind;
! 574: }
! 575:
! 576: /* The special ARGV-element `--' means premature end of options.
! 577: Skip it like a null option,
! 578: then exchange with previous non-options as if it were an option,
! 579: then skip everything else like a non-option. */
! 580:
! 581: if (optind != argc && !strcmp (argv[optind], "--"))
! 582: {
! 583: optind++;
! 584:
! 585: if (first_nonopt != last_nonopt && last_nonopt != optind)
! 586: exchange ((char **) argv);
! 587: else if (first_nonopt == last_nonopt)
! 588: first_nonopt = optind;
! 589: last_nonopt = argc;
! 590:
! 591: optind = argc;
! 592: }
! 593:
! 594: /* If we have done all the ARGV-elements, stop the scan
! 595: and back over any non-options that we skipped and permuted. */
! 596:
! 597: if (optind == argc)
! 598: {
! 599: /* Set the next-arg-index to point at the non-options
! 600: that we previously skipped, so the caller will digest them. */
! 601: if (first_nonopt != last_nonopt)
! 602: optind = first_nonopt;
! 603: return -1;
! 604: }
! 605:
! 606: /* If we have come to a non-option and did not permute it,
! 607: either stop the scan or describe it to the caller and pass it by. */
! 608:
! 609: if (NONOPTION_P)
! 610: {
! 611: if (ordering == REQUIRE_ORDER)
! 612: return -1;
! 613: optarg = argv[optind++];
! 614: return 1;
! 615: }
! 616:
! 617: /* We have found another option-ARGV-element.
! 618: Skip the initial punctuation. */
! 619:
! 620: nextchar = (argv[optind] + 1
! 621: + (longopts != NULL && argv[optind][1] == '-'));
! 622: }
! 623:
! 624: /* Decode the current option-ARGV-element. */
! 625:
! 626: /* Check whether the ARGV-element is a long option.
! 627:
! 628: If long_only and the ARGV-element has the form "-f", where f is
! 629: a valid short option, don't consider it an abbreviated form of
! 630: a long option that starts with f. Otherwise there would be no
! 631: way to give the -f short option.
! 632:
! 633: On the other hand, if there's a long option "fubar" and
! 634: the ARGV-element is "-fu", do consider that an abbreviation of
! 635: the long option, just like "--fu", and not "-f" with arg "u".
! 636:
! 637: This distinction seems to be the most useful approach. */
! 638:
! 639: if (longopts != NULL
! 640: && (argv[optind][1] == '-'
! 641: || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
! 642: {
! 643: char *nameend;
! 644: const struct option *p;
! 645: const struct option *pfound = NULL;
! 646: int exact = 0;
! 647: int ambig = 0;
! 648: int indfound = -1;
! 649: int option_index;
! 650:
! 651: for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
! 652: /* Do nothing. */ ;
! 653:
! 654: /* Test all long options for either exact match
! 655: or abbreviated matches. */
! 656: for (p = longopts, option_index = 0; p->name; p++, option_index++)
! 657: if (!strncmp (p->name, nextchar, nameend - nextchar))
! 658: {
! 659: if ((unsigned int) (nameend - nextchar)
! 660: == (unsigned int) strlen (p->name))
! 661: {
! 662: /* Exact match found. */
! 663: pfound = p;
! 664: indfound = option_index;
! 665: exact = 1;
! 666: break;
! 667: }
! 668: else if (pfound == NULL)
! 669: {
! 670: /* First nonexact match found. */
! 671: pfound = p;
! 672: indfound = option_index;
! 673: }
! 674: else
! 675: /* Second or later nonexact match found. */
! 676: ambig = 1;
! 677: }
! 678:
! 679: if (ambig && !exact)
! 680: {
! 681: if (opterr)
! 682: fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
! 683: argv[0], argv[optind]);
! 684: nextchar += strlen (nextchar);
! 685: optind++;
! 686: optopt = 0;
! 687: return '?';
! 688: }
! 689:
! 690: if (pfound != NULL)
! 691: {
! 692: option_index = indfound;
! 693: optind++;
! 694: if (*nameend)
! 695: {
! 696: /* Don't test has_arg with >, because some C compilers don't
! 697: allow it to be used on enums. */
! 698: if (pfound->has_arg)
! 699: optarg = nameend + 1;
! 700: else
! 701: {
! 702: if (opterr)
! 703: {
! 704: if (argv[optind - 1][1] == '-')
! 705: /* --option */
! 706: fprintf (stderr,
! 707: _("%s: option `--%s' doesn't allow an argument\n"),
! 708: argv[0], pfound->name);
! 709: else
! 710: /* +option or -option */
! 711: fprintf (stderr,
! 712: _("%s: option `%c%s' doesn't allow an argument\n"),
! 713: argv[0], argv[optind - 1][0], pfound->name);
! 714: }
! 715:
! 716: nextchar += strlen (nextchar);
! 717:
! 718: optopt = pfound->val;
! 719: return '?';
! 720: }
! 721: }
! 722: else if (pfound->has_arg == 1)
! 723: {
! 724: if (optind < argc)
! 725: optarg = argv[optind++];
! 726: else
! 727: {
! 728: if (opterr)
! 729: fprintf (stderr,
! 730: _("%s: option `%s' requires an argument\n"),
! 731: argv[0], argv[optind - 1]);
! 732: nextchar += strlen (nextchar);
! 733: optopt = pfound->val;
! 734: return optstring[0] == ':' ? ':' : '?';
! 735: }
! 736: }
! 737: nextchar += strlen (nextchar);
! 738: if (longind != NULL)
! 739: *longind = option_index;
! 740: if (pfound->flag)
! 741: {
! 742: *(pfound->flag) = pfound->val;
! 743: return 0;
! 744: }
! 745: return pfound->val;
! 746: }
! 747:
! 748: /* Can't find it as a long option. If this is not getopt_long_only,
! 749: or the option starts with '--' or is not a valid short
! 750: option, then it's an error.
! 751: Otherwise interpret it as a short option. */
! 752: if (!long_only || argv[optind][1] == '-'
! 753: || my_index (optstring, *nextchar) == NULL)
! 754: {
! 755: if (opterr)
! 756: {
! 757: if (argv[optind][1] == '-')
! 758: /* --option */
! 759: fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
! 760: argv[0], nextchar);
! 761: else
! 762: /* +option or -option */
! 763: fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
! 764: argv[0], argv[optind][0], nextchar);
! 765: }
! 766: nextchar = (char *) "";
! 767: optind++;
! 768: optopt = 0;
! 769: return '?';
! 770: }
! 771: }
! 772:
! 773: /* Look at and handle the next short option-character. */
! 774:
! 775: {
! 776: char c = *nextchar++;
! 777: char *temp = my_index (optstring, c);
! 778:
! 779: /* Increment `optind' when we start to process its last character. */
! 780: if (*nextchar == '\0')
! 781: ++optind;
! 782:
! 783: if (temp == NULL || c == ':')
! 784: {
! 785: if (opterr)
! 786: {
! 787: if (posixly_correct)
! 788: /* 1003.2 specifies the format of this message. */
! 789: fprintf (stderr, _("%s: illegal option -- %c\n"),
! 790: argv[0], c);
! 791: else
! 792: fprintf (stderr, _("%s: invalid option -- %c\n"),
! 793: argv[0], c);
! 794: }
! 795: optopt = c;
! 796: return '?';
! 797: }
! 798: /* Convenience. Treat POSIX -W foo same as long option --foo */
! 799: if (temp[0] == 'W' && temp[1] == ';')
! 800: {
! 801: char *nameend;
! 802: const struct option *p;
! 803: const struct option *pfound = NULL;
! 804: int exact = 0;
! 805: int ambig = 0;
! 806: int indfound = 0;
! 807: int option_index;
! 808:
! 809: /* This is an option that requires an argument. */
! 810: if (*nextchar != '\0')
! 811: {
! 812: optarg = nextchar;
! 813: /* If we end this ARGV-element by taking the rest as an arg,
! 814: we must advance to the next element now. */
! 815: optind++;
! 816: }
! 817: else if (optind == argc)
! 818: {
! 819: if (opterr)
! 820: {
! 821: /* 1003.2 specifies the format of this message. */
! 822: fprintf (stderr, _("%s: option requires an argument -- %c\n"),
! 823: argv[0], c);
! 824: }
! 825: optopt = c;
! 826: if (optstring[0] == ':')
! 827: c = ':';
! 828: else
! 829: c = '?';
! 830: return c;
! 831: }
! 832: else
! 833: /* We already incremented `optind' once;
! 834: increment it again when taking next ARGV-elt as argument. */
! 835: optarg = argv[optind++];
! 836:
! 837: /* optarg is now the argument, see if it's in the
! 838: table of longopts. */
! 839:
! 840: for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
! 841: /* Do nothing. */ ;
! 842:
! 843: /* Test all long options for either exact match
! 844: or abbreviated matches. */
! 845: for (p = longopts, option_index = 0; p->name; p++, option_index++)
! 846: if (!strncmp (p->name, nextchar, nameend - nextchar))
! 847: {
! 848: if ((unsigned int) (nameend - nextchar) == strlen (p->name))
! 849: {
! 850: /* Exact match found. */
! 851: pfound = p;
! 852: indfound = option_index;
! 853: exact = 1;
! 854: break;
! 855: }
! 856: else if (pfound == NULL)
! 857: {
! 858: /* First nonexact match found. */
! 859: pfound = p;
! 860: indfound = option_index;
! 861: }
! 862: else
! 863: /* Second or later nonexact match found. */
! 864: ambig = 1;
! 865: }
! 866: if (ambig && !exact)
! 867: {
! 868: if (opterr)
! 869: fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
! 870: argv[0], argv[optind]);
! 871: nextchar += strlen (nextchar);
! 872: optind++;
! 873: return '?';
! 874: }
! 875: if (pfound != NULL)
! 876: {
! 877: option_index = indfound;
! 878: if (*nameend)
! 879: {
! 880: /* Don't test has_arg with >, because some C compilers don't
! 881: allow it to be used on enums. */
! 882: if (pfound->has_arg)
! 883: optarg = nameend + 1;
! 884: else
! 885: {
! 886: if (opterr)
! 887: fprintf (stderr, _("\
! 888: %s: option `-W %s' doesn't allow an argument\n"),
! 889: argv[0], pfound->name);
! 890:
! 891: nextchar += strlen (nextchar);
! 892: return '?';
! 893: }
! 894: }
! 895: else if (pfound->has_arg == 1)
! 896: {
! 897: if (optind < argc)
! 898: optarg = argv[optind++];
! 899: else
! 900: {
! 901: if (opterr)
! 902: fprintf (stderr,
! 903: _("%s: option `%s' requires an argument\n"),
! 904: argv[0], argv[optind - 1]);
! 905: nextchar += strlen (nextchar);
! 906: return optstring[0] == ':' ? ':' : '?';
! 907: }
! 908: }
! 909: nextchar += strlen (nextchar);
! 910: if (longind != NULL)
! 911: *longind = option_index;
! 912: if (pfound->flag)
! 913: {
! 914: *(pfound->flag) = pfound->val;
! 915: return 0;
! 916: }
! 917: return pfound->val;
! 918: }
! 919: nextchar = NULL;
! 920: return 'W'; /* Let the application handle it. */
! 921: }
! 922: if (temp[1] == ':')
! 923: {
! 924: if (temp[2] == ':')
! 925: {
! 926: /* This is an option that accepts an argument optionally. */
! 927: if (*nextchar != '\0')
! 928: {
! 929: optarg = nextchar;
! 930: optind++;
! 931: }
! 932: else
! 933: optarg = NULL;
! 934: nextchar = NULL;
! 935: }
! 936: else
! 937: {
! 938: /* This is an option that requires an argument. */
! 939: if (*nextchar != '\0')
! 940: {
! 941: optarg = nextchar;
! 942: /* If we end this ARGV-element by taking the rest as an arg,
! 943: we must advance to the next element now. */
! 944: optind++;
! 945: }
! 946: else if (optind == argc)
! 947: {
! 948: if (opterr)
! 949: {
! 950: /* 1003.2 specifies the format of this message. */
! 951: fprintf (stderr,
! 952: _("%s: option requires an argument -- %c\n"),
! 953: argv[0], c);
! 954: }
! 955: optopt = c;
! 956: if (optstring[0] == ':')
! 957: c = ':';
! 958: else
! 959: c = '?';
! 960: }
! 961: else
! 962: /* We already incremented `optind' once;
! 963: increment it again when taking next ARGV-elt as argument. */
! 964: optarg = argv[optind++];
! 965: nextchar = NULL;
! 966: }
! 967: }
! 968: return c;
! 969: }
! 970: }
! 971:
! 972: #ifdef REALLY_NEED_PLAIN_GETOPT
! 973:
! 974: int
! 975: getopt (argc, argv, optstring)
! 976: int argc;
! 977: char *const *argv;
! 978: const char *optstring;
! 979: {
! 980: return _getopt_internal (argc, argv, optstring,
! 981: (const struct option *) 0,
! 982: (int *) 0,
! 983: 0);
! 984: }
! 985:
! 986: #endif /* REALLY_NEED_PLAIN_GETOPT */
! 987:
! 988: #endif /* Not ELIDE_CODE. */
! 989:
! 990: #ifdef TEST
! 991:
! 992: /* Compile with -DTEST to make an executable for use in testing
! 993: the above definition of `getopt'. */
! 994:
! 995: int
! 996: main (argc, argv)
! 997: int argc;
! 998: char **argv;
! 999: {
! 1000: int c;
! 1001: int digit_optind = 0;
! 1002:
! 1003: while (1)
! 1004: {
! 1005: int this_option_optind = optind ? optind : 1;
! 1006:
! 1007: c = getopt (argc, argv, "abc:d:0123456789");
! 1008: if (c == -1)
! 1009: break;
! 1010:
! 1011: switch (c)
! 1012: {
! 1013: case '0':
! 1014: case '1':
! 1015: case '2':
! 1016: case '3':
! 1017: case '4':
! 1018: case '5':
! 1019: case '6':
! 1020: case '7':
! 1021: case '8':
! 1022: case '9':
! 1023: if (digit_optind != 0 && digit_optind != this_option_optind)
! 1024: printf ("digits occur in two different argv-elements.\n");
! 1025: digit_optind = this_option_optind;
! 1026: printf ("option %c\n", c);
! 1027: break;
! 1028:
! 1029: case 'a':
! 1030: printf ("option a\n");
! 1031: break;
! 1032:
! 1033: case 'b':
! 1034: printf ("option b\n");
! 1035: break;
! 1036:
! 1037: case 'c':
! 1038: printf ("option c with value `%s'\n", optarg);
! 1039: break;
! 1040:
! 1041: case '?':
! 1042: break;
! 1043:
! 1044: default:
! 1045: printf ("?? getopt returned character code 0%o ??\n", c);
! 1046: }
! 1047: }
! 1048:
! 1049: if (optind < argc)
! 1050: {
! 1051: printf ("non-option ARGV-elements: ");
! 1052: while (optind < argc)
! 1053: printf ("%s ", argv[optind++]);
! 1054: printf ("\n");
! 1055: }
! 1056:
! 1057: exit (0);
! 1058: }
! 1059:
! 1060: #endif /* TEST */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>