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