Back to index

tetex-bin  3.0
getopt.c
Go to the documentation of this file.
00001 /* Getopt for GNU.
00002    NOTE: getopt is now part of the C library, so if you don't know what
00003    "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
00004    before changing it!
00005 
00006    Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 2000
00007        Free Software Foundation, Inc.
00008 
00009    This file is part of the GNU C Library.  Its master source is NOT part of
00010    the C library, however.  The master source lives in /gd/gnu/lib.
00011 
00012    The GNU C Library is free software; you can redistribute it and/or
00013    modify it under the terms of the GNU Library General Public License as
00014    published by the Free Software Foundation; either version 2 of the
00015    License, or (at your option) any later version.
00016 
00017    The GNU C Library is distributed in the hope that it will be useful,
00018    but WITHOUT ANY WARRANTY; without even the implied warranty of
00019    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020    Library General Public License for more details.
00021 
00022    You should have received a copy of the GNU Library General Public
00023    License along with the GNU C Library; see the file COPYING.LIB.  If not,
00024    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00025    Boston, MA 02111-1307, USA.  */
00026 
00027 /* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
00028    Ditto for AIX 3.2 and <stdlib.h>.  */
00029 #ifndef _NO_PROTO
00030 #define _NO_PROTO
00031 #endif
00032 
00033 #ifdef HAVE_CONFIG_H
00034 #include <config.h>
00035 #endif
00036 
00037 #if !defined (__STDC__) || !__STDC__
00038 /* This is a separate conditional since some stdc systems
00039    reject `defined (const)'.  */
00040 #ifndef const
00041 #define const
00042 #endif
00043 #endif
00044 
00045 #include <stdio.h>
00046 
00047 /* Comment out all this code if we are using the GNU C Library, and are not
00048    actually compiling the library itself.  This code is part of the GNU C
00049    Library, but also included in many other GNU distributions.  Compiling
00050    and linking in this code is a waste when using the GNU C library
00051    (especially if it is a shared library).  Rather than having every GNU
00052    program understand `configure --with-gnu-libc' and omit the object files,
00053    it is simpler to just do this in the source for each such file.  */
00054 
00055 #define GETOPT_INTERFACE_VERSION 2
00056 #if !defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2
00057 #include <gnu-versions.h>
00058 #if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
00059 #define ELIDE_CODE
00060 #endif
00061 #endif
00062 
00063 #ifndef ELIDE_CODE
00064 
00065 
00066 /* This needs to come after some library #include
00067    to get __GNU_LIBRARY__ defined.  */
00068 #ifdef __GNU_LIBRARY__
00069 /* Don't include stdlib.h for non-GNU C libraries because some of them
00070    contain conflicting prototypes for getopt.  */
00071 #include <stdlib.h>
00072 #include <unistd.h>
00073 #endif /* GNU C library.  */
00074 
00075 #ifdef VMS
00076 #include <unixlib.h>
00077 #if HAVE_STRING_H - 0
00078 #include <string.h>
00079 #endif
00080 #endif
00081 
00082 #if defined (WIN32) && !defined (__CYGWIN32__)
00083 /* It's not Unix, really.  See?  Capital letters.  */
00084 #include <stdlib.h>
00085 #include <windows.h>
00086 #ifdef getpid
00087 #undef getpid
00088 #endif
00089 #define getpid() GetCurrentProcessId()
00090 #endif
00091 
00092 #ifndef _
00093 /* This is for other GNU distributions with internationalized messages.
00094    When compiling libc, the _ macro is predefined.  */
00095 #ifdef HAVE_LIBINTL_H
00096 # include <libintl.h>
00097 # define _(msgid)    gettext (msgid)
00098 #else
00099 # define _(msgid)    (msgid)
00100 #endif
00101 #endif
00102 
00103 /* This version of `getopt' appears to the caller like standard Unix `getopt'
00104    but it behaves differently for the user, since it allows the user
00105    to intersperse the options with the other arguments.
00106 
00107    As `getopt' works, it permutes the elements of ARGV so that,
00108    when it is done, all the options precede everything else.  Thus
00109    all application programs are extended to handle flexible argument order.
00110 
00111    Setting the environment variable POSIXLY_CORRECT disables permutation.
00112    Then the behavior is completely standard.
00113 
00114    GNU application programs can use a third alternative mode in which
00115    they can distinguish the relative order of options and other arguments.  */
00116 
00117 #include "getopt.h"
00118 
00119 /* For communication from `getopt' to the caller.
00120    When `getopt' finds an option that takes an argument,
00121    the argument value is returned here.
00122    Also, when `ordering' is RETURN_IN_ORDER,
00123    each non-option ARGV-element is returned here.  */
00124 
00125 char *optarg = NULL;
00126 
00127 /* Index in ARGV of the next element to be scanned.
00128    This is used for communication to and from the caller
00129    and for communication between successive calls to `getopt'.
00130 
00131    On entry to `getopt', zero means this is the first call; initialize.
00132 
00133    When `getopt' returns -1, this is the index of the first of the
00134    non-option elements that the caller should itself scan.
00135 
00136    Otherwise, `optind' communicates from one call to the next
00137    how much of ARGV has been scanned so far.  */
00138 
00139 /* 1003.2 says this must be 1 before any call.  */
00140 int optind = 1;
00141 
00142 /* Formerly, initialization of getopt depended on optind==0, which
00143    causes problems with re-calling getopt as programs generally don't
00144    know that. */
00145 
00146 int __getopt_initialized = 0;
00147 
00148 /* The next char to be scanned in the option-element
00149    in which the last option character we returned was found.
00150    This allows us to pick up the scan where we left off.
00151 
00152    If this is zero, or a null string, it means resume the scan
00153    by advancing to the next ARGV-element.  */
00154 
00155 static char *nextchar;
00156 
00157 /* Callers store zero here to inhibit the error message
00158    for unrecognized options.  */
00159 
00160 int opterr = 1;
00161 
00162 /* Set to an option character which was unrecognized.
00163    This must be initialized on some systems to avoid linking in the
00164    system's own getopt implementation.  */
00165 
00166 int optopt = '?';
00167 
00168 /* Describe how to deal with options that follow non-option ARGV-elements.
00169 
00170    If the caller did not specify anything,
00171    the default is REQUIRE_ORDER if the environment variable
00172    POSIXLY_CORRECT is defined, PERMUTE otherwise.
00173 
00174    REQUIRE_ORDER means don't recognize them as options;
00175    stop option processing when the first non-option is seen.
00176    This is what Unix does.
00177    This mode of operation is selected by either setting the environment
00178    variable POSIXLY_CORRECT, or using `+' as the first character
00179    of the list of option characters.
00180 
00181    PERMUTE is the default.  We permute the contents of ARGV as we scan,
00182    so that eventually all the non-options are at the end.  This allows options
00183    to be given in any order, even with programs that were not written to
00184    expect this.
00185 
00186    RETURN_IN_ORDER is an option available to programs that were written
00187    to expect options and other ARGV-elements in any order and that care about
00188    the ordering of the two.  We describe each non-option ARGV-element
00189    as if it were the argument of an option with character code 1.
00190    Using `-' as the first character of the list of option characters
00191    selects this mode of operation.
00192 
00193    The special argument `--' forces an end of option-scanning regardless
00194    of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
00195    `--' can cause `getopt' to return -1 with `optind' != ARGC.  */
00196 
00197 static enum
00198 {
00199   REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
00200 } ordering;
00201 
00202 /* Value of POSIXLY_CORRECT environment variable.  */
00203 static char *posixly_correct;
00204 
00205 #if defined(__GNU_LIBRARY__) || defined(WIN32)
00206 /* We want to avoid inclusion of string.h with non-GNU libraries
00207    because there are many ways it can cause trouble.
00208    On some systems, it contains special magic macros that don't work
00209    in GCC.  */
00210 #include <string.h>
00211 #define       my_index      strchr
00212 #else
00213 
00214 /* Avoid depending on library functions or files
00215    whose names are inconsistent.  */
00216 
00217 char *getenv ();
00218 
00219 static char *
00220 my_index (str, chr)
00221      const char *str;
00222      int chr;
00223 {
00224   while (*str)
00225     {
00226       if (*str == chr)
00227        return (char *) str;
00228       str++;
00229     }
00230   return 0;
00231 }
00232 
00233 /* If using GCC, we can safely declare strlen this way.
00234    If not using GCC, it is ok not to declare it.  */
00235 #ifdef __GNUC__
00236 /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
00237    That was relevant to code that was here before.  */
00238 #if !defined (__STDC__) || !__STDC__
00239 /* gcc with -traditional declares the built-in strlen to return int,
00240    and has done so at least since version 2.4.5. -- rms.  */
00241 extern int strlen (const char *);
00242 #endif /* not __STDC__ */
00243 #endif /* __GNUC__ */
00244 
00245 #endif /* not __GNU_LIBRARY__ */
00246 
00247 /* Handle permutation of arguments.  */
00248 
00249 /* Describe the part of ARGV that contains non-options that have
00250    been skipped.  `first_nonopt' is the index in ARGV of the first of them;
00251    `last_nonopt' is the index after the last of them.  */
00252 
00253 static int first_nonopt;
00254 static int last_nonopt;
00255 
00256 #ifdef _LIBC
00257 /* Bash 2.0 gives us an environment variable containing flags
00258    indicating ARGV elements that should not be considered arguments.  */
00259 
00260 static const char *nonoption_flags;
00261 static int nonoption_flags_len;
00262 
00263 static int original_argc;
00264 static char *const *original_argv;
00265 
00266 /* Make sure the environment variable bash 2.0 puts in the environment
00267    is valid for the getopt call we must make sure that the ARGV passed
00268    to getopt is that one passed to the process.  */
00269 static void store_args (int argc, char *const *argv) __attribute__ ((unused));
00270 static void
00271 store_args (int argc, char *const *argv)
00272 {
00273   /* XXX This is no good solution.  We should rather copy the args so
00274      that we can compare them later.  But we must not use malloc(3).  */
00275   original_argc = argc;
00276   original_argv = argv;
00277 }
00278 text_set_element (__libc_subinit, store_args);
00279 #endif
00280 
00281 /* Exchange two adjacent subsequences of ARGV.
00282    One subsequence is elements [first_nonopt,last_nonopt)
00283    which contains all the non-options that have been skipped so far.
00284    The other is elements [last_nonopt,optind), which contains all
00285    the options processed since those non-options were skipped.
00286 
00287    `first_nonopt' and `last_nonopt' are relocated so that they describe
00288    the new indices of the non-options in ARGV after they are moved.  */
00289 
00290 #if defined (__STDC__) && __STDC__
00291 static void exchange (char **);
00292 #endif
00293 
00294 static void
00295 exchange (argv)
00296      char **argv;
00297 {
00298   int bottom = first_nonopt;
00299   int middle = last_nonopt;
00300   int top = optind;
00301   char *tem;
00302 
00303   /* Exchange the shorter segment with the far end of the longer segment.
00304      That puts the shorter segment into the right place.
00305      It leaves the longer segment in the right place overall,
00306      but it consists of two parts that need to be swapped next.  */
00307 
00308   while (top > middle && middle > bottom)
00309     {
00310       if (top - middle > middle - bottom)
00311        {
00312          /* Bottom segment is the short one.  */
00313          int len = middle - bottom;
00314          register int i;
00315 
00316          /* Swap it with the top part of the top segment.  */
00317          for (i = 0; i < len; i++)
00318            {
00319              tem = argv[bottom + i];
00320              argv[bottom + i] = argv[top - (middle - bottom) + i];
00321              argv[top - (middle - bottom) + i] = tem;
00322            }
00323          /* Exclude the moved bottom segment from further swapping.  */
00324          top -= len;
00325        }
00326       else
00327        {
00328          /* Top segment is the short one.  */
00329          int len = top - middle;
00330          register int i;
00331 
00332          /* Swap it with the bottom part of the bottom segment.  */
00333          for (i = 0; i < len; i++)
00334            {
00335              tem = argv[bottom + i];
00336              argv[bottom + i] = argv[middle + i];
00337              argv[middle + i] = tem;
00338            }
00339          /* Exclude the moved top segment from further swapping.  */
00340          bottom += len;
00341        }
00342     }
00343 
00344   /* Update records for the slots the non-options now occupy.  */
00345 
00346   first_nonopt += (optind - last_nonopt);
00347   last_nonopt = optind;
00348 }
00349 
00350 /* Initialize the internal data when the first call is made.  */
00351 
00352 #if defined (__STDC__) && __STDC__
00353 static const char *_getopt_initialize (int, char *const *, const char *);
00354 #endif
00355 static const char *
00356 _getopt_initialize (argc, argv, optstring)
00357      int argc;
00358      char *const *argv;
00359      const char *optstring;
00360 {
00361   /* Start processing options with ARGV-element 1 (since ARGV-element 0
00362      is the program name); the sequence of previously skipped
00363      non-option ARGV-elements is empty.  */
00364 
00365   first_nonopt = last_nonopt = optind = 1;
00366 
00367   nextchar = NULL;
00368 
00369   posixly_correct = getenv ("POSIXLY_CORRECT");
00370 
00371   /* Determine how to handle the ordering of options and nonoptions.  */
00372 
00373   if (optstring[0] == '-')
00374     {
00375       ordering = RETURN_IN_ORDER;
00376       ++optstring;
00377     }
00378   else if (optstring[0] == '+')
00379     {
00380       ordering = REQUIRE_ORDER;
00381       ++optstring;
00382     }
00383   else if (posixly_correct != NULL)
00384     ordering = REQUIRE_ORDER;
00385   else
00386     ordering = PERMUTE;
00387 
00388 #ifdef _LIBC
00389   if (posixly_correct == NULL
00390       && argc == original_argc && argv == original_argv)
00391     {
00392       /* Bash 2.0 puts a special variable in the environment for each
00393         command it runs, specifying which ARGV elements are the results of
00394         file name wildcard expansion and therefore should not be
00395         considered as options.  */
00396       char var[100];
00397       sprintf (var, "_%d_GNU_nonoption_argv_flags_", getpid ());
00398       nonoption_flags = getenv (var);
00399       if (nonoption_flags == NULL)
00400        nonoption_flags_len = 0;
00401       else
00402        nonoption_flags_len = strlen (nonoption_flags);
00403     }
00404   else
00405     nonoption_flags_len = 0;
00406 #endif
00407 
00408   return optstring;
00409 }
00410 
00411 /* Scan elements of ARGV (whose length is ARGC) for option characters
00412    given in OPTSTRING.
00413 
00414    If an element of ARGV starts with '-', and is not exactly "-" or "--",
00415    then it is an option element.  The characters of this element
00416    (aside from the initial '-') are option characters.  If `getopt'
00417    is called repeatedly, it returns successively each of the option characters
00418    from each of the option elements.
00419 
00420    If `getopt' finds another option character, it returns that character,
00421    updating `optind' and `nextchar' so that the next call to `getopt' can
00422    resume the scan with the following option character or ARGV-element.
00423 
00424    If there are no more option characters, `getopt' returns -1.
00425    Then `optind' is the index in ARGV of the first ARGV-element
00426    that is not an option.  (The ARGV-elements have been permuted
00427    so that those that are not options now come last.)
00428 
00429    OPTSTRING is a string containing the legitimate option characters.
00430    If an option character is seen that is not listed in OPTSTRING,
00431    return '?' after printing an error message.  If you set `opterr' to
00432    zero, the error message is suppressed but we still return '?'.
00433 
00434    If a char in OPTSTRING is followed by a colon, that means it wants an arg,
00435    so the following text in the same ARGV-element, or the text of the following
00436    ARGV-element, is returned in `optarg'.  Two colons mean an option that
00437    wants an optional arg; if there is text in the current ARGV-element,
00438    it is returned in `optarg', otherwise `optarg' is set to zero.
00439 
00440    If OPTSTRING starts with `-' or `+', it requests different methods of
00441    handling the non-option ARGV-elements.
00442    See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
00443 
00444    Long-named options begin with `--' instead of `-'.
00445    Their names may be abbreviated as long as the abbreviation is unique
00446    or is an exact match for some defined option.  If they have an
00447    argument, it follows the option name in the same ARGV-element, separated
00448    from the option name by a `=', or else the in next ARGV-element.
00449    When `getopt' finds a long-named option, it returns 0 if that option's
00450    `flag' field is nonzero, the value of the option's `val' field
00451    if the `flag' field is zero.
00452 
00453    The elements of ARGV aren't really const, because we permute them.
00454    But we pretend they're const in the prototype to be compatible
00455    with other systems.
00456 
00457    LONGOPTS is a vector of `struct option' terminated by an
00458    element containing a name which is zero.
00459 
00460    LONGIND returns the index in LONGOPT of the long-named option found.
00461    It is only valid when a long-named option has been found by the most
00462    recent call.
00463 
00464    If LONG_ONLY is nonzero, '-' as well as '--' can introduce
00465    long-named options.  */
00466 
00467 int
00468 _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
00469      int argc;
00470      char *const *argv;
00471      const char *optstring;
00472      const struct option *longopts;
00473      int *longind;
00474      int long_only;
00475 {
00476   optarg = NULL;
00477 
00478   if (!__getopt_initialized || optind == 0)
00479     {
00480       optstring = _getopt_initialize (argc, argv, optstring);
00481       optind = 1;           /* Don't scan ARGV[0], the program name.  */
00482       __getopt_initialized = 1;
00483     }
00484 
00485   /* Test whether ARGV[optind] points to a non-option argument.
00486      Either it does not have option syntax, or there is an environment flag
00487      from the shell indicating it is not an option.  The later information
00488      is only used when the used in the GNU libc.  */
00489 #ifdef _LIBC
00490 #define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'             \
00491                    || (optind < nonoption_flags_len                         \
00492                       && nonoption_flags[optind] == '1'))
00493 #else
00494 #define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
00495 #endif
00496 
00497   if (nextchar == NULL || *nextchar == '\0')
00498     {
00499       /* Advance to the next ARGV-element.  */
00500 
00501       /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
00502         moved back by the user (who may also have changed the arguments).  */
00503       if (last_nonopt > optind)
00504        last_nonopt = optind;
00505       if (first_nonopt > optind)
00506        first_nonopt = optind;
00507 
00508       if (ordering == PERMUTE)
00509        {
00510          /* If we have just processed some options following some non-options,
00511             exchange them so that the options come first.  */
00512 
00513          if (first_nonopt != last_nonopt && last_nonopt != optind)
00514            exchange ((char **) argv);
00515          else if (last_nonopt != optind)
00516            first_nonopt = optind;
00517 
00518          /* Skip any additional non-options
00519             and extend the range of non-options previously skipped.  */
00520 
00521          while (optind < argc && NONOPTION_P)
00522            optind++;
00523          last_nonopt = optind;
00524        }
00525 
00526       /* The special ARGV-element `--' means premature end of options.
00527         Skip it like a null option,
00528         then exchange with previous non-options as if it were an option,
00529         then skip everything else like a non-option.  */
00530 
00531       if (optind != argc && !strcmp (argv[optind], "--"))
00532        {
00533          optind++;
00534 
00535          if (first_nonopt != last_nonopt && last_nonopt != optind)
00536            exchange ((char **) argv);
00537          else if (first_nonopt == last_nonopt)
00538            first_nonopt = optind;
00539          last_nonopt = argc;
00540 
00541          optind = argc;
00542        }
00543 
00544       /* If we have done all the ARGV-elements, stop the scan
00545         and back over any non-options that we skipped and permuted.  */
00546 
00547       if (optind == argc)
00548        {
00549          /* Set the next-arg-index to point at the non-options
00550             that we previously skipped, so the caller will digest them.  */
00551          if (first_nonopt != last_nonopt)
00552            optind = first_nonopt;
00553          return -1;
00554        }
00555 
00556       /* If we have come to a non-option and did not permute it,
00557         either stop the scan or describe it to the caller and pass it by.  */
00558 
00559       if (NONOPTION_P)
00560        {
00561          if (ordering == REQUIRE_ORDER)
00562            return -1;
00563          optarg = argv[optind++];
00564          return 1;
00565        }
00566 
00567       /* We have found another option-ARGV-element.
00568         Skip the initial punctuation.  */
00569 
00570       nextchar = (argv[optind] + 1
00571                 + (longopts != NULL && argv[optind][1] == '-'));
00572     }
00573 
00574   /* Decode the current option-ARGV-element.  */
00575 
00576   /* Check whether the ARGV-element is a long option.
00577 
00578      If long_only and the ARGV-element has the form "-f", where f is
00579      a valid short option, don't consider it an abbreviated form of
00580      a long option that starts with f.  Otherwise there would be no
00581      way to give the -f short option.
00582 
00583      On the other hand, if there's a long option "fubar" and
00584      the ARGV-element is "-fu", do consider that an abbreviation of
00585      the long option, just like "--fu", and not "-f" with arg "u".
00586 
00587      This distinction seems to be the most useful approach.  */
00588 
00589   if (longopts != NULL
00590       && (argv[optind][1] == '-'
00591          || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
00592     {
00593       char *nameend;
00594       const struct option *p;
00595       const struct option *pfound = NULL;
00596       int exact = 0;
00597       int ambig = 0;
00598       int indfound = -1;
00599       int option_index;
00600 
00601       for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
00602        /* Do nothing.  */ ;
00603 
00604       /* Test all long options for either exact match
00605         or abbreviated matches.  */
00606       for (p = longopts, option_index = 0; p->name; p++, option_index++)
00607        if (!strncmp (p->name, nextchar, nameend - nextchar))
00608          {
00609            if ((unsigned int) (nameend - nextchar)
00610               == (unsigned int) strlen (p->name))
00611              {
00612               /* Exact match found.  */
00613               pfound = p;
00614               indfound = option_index;
00615               exact = 1;
00616               break;
00617              }
00618            else if (pfound == NULL)
00619              {
00620               /* First nonexact match found.  */
00621               pfound = p;
00622               indfound = option_index;
00623              }
00624            else
00625              /* Second or later nonexact match found.  */
00626              ambig = 1;
00627          }
00628 
00629       if (ambig && !exact)
00630        {
00631          if (opterr)
00632            fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
00633                    argv[0], argv[optind]);
00634          nextchar += strlen (nextchar);
00635          optind++;
00636          optopt = 0;
00637          return '?';
00638        }
00639 
00640       if (pfound != NULL)
00641        {
00642          option_index = indfound;
00643          optind++;
00644          if (*nameend)
00645            {
00646              /* Don't test has_arg with >, because some C compilers don't
00647                allow it to be used on enums.  */
00648              if (pfound->has_arg)
00649               optarg = nameend + 1;
00650              else
00651               {
00652                 if (opterr)
00653                  if (argv[optind - 1][1] == '-')
00654                   /* --option */
00655                   fprintf (stderr,
00656                    _("%s: option `--%s' doesn't allow an argument\n"),
00657                    argv[0], pfound->name);
00658                  else
00659                   /* +option or -option */
00660                   fprintf (stderr,
00661                    _("%s: option `%c%s' doesn't allow an argument\n"),
00662                    argv[0], argv[optind - 1][0], pfound->name);
00663 
00664                 nextchar += strlen (nextchar);
00665 
00666                 optopt = pfound->val;
00667                 return '?';
00668               }
00669            }
00670          else if (pfound->has_arg == 1)
00671            {
00672              if (optind < argc)
00673               optarg = argv[optind++];
00674              else
00675               {
00676                 if (opterr)
00677                   fprintf (stderr,
00678                         _("%s: option `%s' requires an argument\n"),
00679                         argv[0], argv[optind - 1]);
00680                 nextchar += strlen (nextchar);
00681                 optopt = pfound->val;
00682                 return optstring[0] == ':' ? ':' : '?';
00683               }
00684            }
00685          nextchar += strlen (nextchar);
00686          if (longind != NULL)
00687            *longind = option_index;
00688          if (pfound->flag)
00689            {
00690              *(pfound->flag) = pfound->val;
00691              return 0;
00692            }
00693          return pfound->val;
00694        }
00695 
00696       /* Can't find it as a long option.  If this is not getopt_long_only,
00697         or the option starts with '--' or is not a valid short
00698         option, then it's an error.
00699         Otherwise interpret it as a short option.  */
00700       if (!long_only || argv[optind][1] == '-'
00701          || my_index (optstring, *nextchar) == NULL)
00702        {
00703          if (opterr)
00704            {
00705              if (argv[optind][1] == '-')
00706               /* --option */
00707               fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
00708                       argv[0], nextchar);
00709              else
00710               /* +option or -option */
00711               fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
00712                       argv[0], argv[optind][0], nextchar);
00713            }
00714          nextchar = (char *) "";
00715          optind++;
00716          optopt = 0;
00717          return '?';
00718        }
00719     }
00720 
00721   /* Look at and handle the next short option-character.  */
00722 
00723   {
00724     char c = *nextchar++;
00725     char *temp = my_index (optstring, c);
00726 
00727     /* Increment `optind' when we start to process its last character.  */
00728     if (*nextchar == '\0')
00729       ++optind;
00730 
00731     if (temp == NULL || c == ':')
00732       {
00733        if (opterr)
00734          {
00735            if (posixly_correct)
00736              /* 1003.2 specifies the format of this message.  */
00737              fprintf (stderr, _("%s: illegal option -- %c\n"),
00738                      argv[0], c);
00739            else
00740              fprintf (stderr, _("%s: invalid option -- %c\n"),
00741                      argv[0], c);
00742          }
00743        optopt = c;
00744        return '?';
00745       }
00746     /* Convenience. Treat POSIX -W foo same as long option --foo */
00747     if (temp[0] == 'W' && temp[1] == ';')
00748       {
00749        char *nameend;
00750        const struct option *p;
00751        const struct option *pfound = NULL;
00752        int exact = 0;
00753        int ambig = 0;
00754        int indfound = 0;
00755        int option_index;
00756 
00757        /* This is an option that requires an argument.  */
00758        if (*nextchar != '\0')
00759          {
00760            optarg = nextchar;
00761            /* If we end this ARGV-element by taking the rest as an arg,
00762               we must advance to the next element now.  */
00763            optind++;
00764          }
00765        else if (optind == argc)
00766          {
00767            if (opterr)
00768              {
00769               /* 1003.2 specifies the format of this message.  */
00770               fprintf (stderr, _("%s: option requires an argument -- %c\n"),
00771                       argv[0], c);
00772              }
00773            optopt = c;
00774            if (optstring[0] == ':')
00775              c = ':';
00776            else
00777              c = '?';
00778            return c;
00779          }
00780        else
00781          /* We already incremented `optind' once;
00782             increment it again when taking next ARGV-elt as argument.  */
00783          optarg = argv[optind++];
00784 
00785        /* optarg is now the argument, see if it's in the
00786           table of longopts.  */
00787 
00788        for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
00789          /* Do nothing.  */ ;
00790 
00791        /* Test all long options for either exact match
00792           or abbreviated matches.  */
00793        for (p = longopts, option_index = 0; p->name; p++, option_index++)
00794          if (!strncmp (p->name, nextchar, nameend - nextchar))
00795            {
00796              if ((unsigned int) (nameend - nextchar) == strlen (p->name))
00797               {
00798                 /* Exact match found.  */
00799                 pfound = p;
00800                 indfound = option_index;
00801                 exact = 1;
00802                 break;
00803               }
00804              else if (pfound == NULL)
00805               {
00806                 /* First nonexact match found.  */
00807                 pfound = p;
00808                 indfound = option_index;
00809               }
00810              else
00811               /* Second or later nonexact match found.  */
00812               ambig = 1;
00813            }
00814        if (ambig && !exact)
00815          {
00816            if (opterr)
00817              fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
00818                      argv[0], argv[optind]);
00819            nextchar += strlen (nextchar);
00820            optind++;
00821            return '?';
00822          }
00823        if (pfound != NULL)
00824          {
00825            option_index = indfound;
00826            if (*nameend)
00827              {
00828               /* Don't test has_arg with >, because some C compilers don't
00829                  allow it to be used on enums.  */
00830               if (pfound->has_arg)
00831                 optarg = nameend + 1;
00832               else
00833                 {
00834                   if (opterr)
00835                     fprintf (stderr, _("\
00836 %s: option `-W %s' doesn't allow an argument\n"),
00837                             argv[0], pfound->name);
00838 
00839                   nextchar += strlen (nextchar);
00840                   return '?';
00841                 }
00842              }
00843            else if (pfound->has_arg == 1)
00844              {
00845               if (optind < argc)
00846                 optarg = argv[optind++];
00847               else
00848                 {
00849                   if (opterr)
00850                     fprintf (stderr,
00851                             _("%s: option `%s' requires an argument\n"),
00852                             argv[0], argv[optind - 1]);
00853                   nextchar += strlen (nextchar);
00854                   return optstring[0] == ':' ? ':' : '?';
00855                 }
00856              }
00857            nextchar += strlen (nextchar);
00858            if (longind != NULL)
00859              *longind = option_index;
00860            if (pfound->flag)
00861              {
00862               *(pfound->flag) = pfound->val;
00863               return 0;
00864              }
00865            return pfound->val;
00866          }
00867          nextchar = NULL;
00868          return 'W'; /* Let the application handle it.   */
00869       }
00870     if (temp[1] == ':')
00871       {
00872        if (temp[2] == ':')
00873          {
00874            /* This is an option that accepts an argument optionally.  */
00875            if (*nextchar != '\0')
00876              {
00877               optarg = nextchar;
00878               optind++;
00879              }
00880            else
00881              optarg = NULL;
00882            nextchar = NULL;
00883          }
00884        else
00885          {
00886            /* This is an option that requires an argument.  */
00887            if (*nextchar != '\0')
00888              {
00889               optarg = nextchar;
00890               /* If we end this ARGV-element by taking the rest as an arg,
00891                  we must advance to the next element now.  */
00892               optind++;
00893              }
00894            else if (optind == argc)
00895              {
00896               if (opterr)
00897                 {
00898                   /* 1003.2 specifies the format of this message.  */
00899                   fprintf (stderr,
00900                         _("%s: option requires an argument -- %c\n"),
00901                         argv[0], c);
00902                 }
00903               optopt = c;
00904               if (optstring[0] == ':')
00905                 c = ':';
00906               else
00907                 c = '?';
00908              }
00909            else
00910              /* We already incremented `optind' once;
00911                increment it again when taking next ARGV-elt as argument.  */
00912              optarg = argv[optind++];
00913            nextchar = NULL;
00914          }
00915       }
00916     return c;
00917   }
00918 }
00919 
00920 int
00921 getopt (argc, argv, optstring)
00922      int argc;
00923      char *const *argv;
00924      const char *optstring;
00925 {
00926   return _getopt_internal (argc, argv, optstring,
00927                         (const struct option *) 0,
00928                         (int *) 0,
00929                         0);
00930 }
00931 
00932 #endif /* Not ELIDE_CODE.  */
00933 
00934 #ifdef TEST
00935 
00936 /* Compile with -DTEST to make an executable for use in testing
00937    the above definition of `getopt'.  */
00938 
00939 int
00940 main (argc, argv)
00941      int argc;
00942      char **argv;
00943 {
00944   int c;
00945   int digit_optind = 0;
00946 
00947   while (1)
00948     {
00949       int this_option_optind = optind ? optind : 1;
00950 
00951       c = getopt (argc, argv, "abc:d:0123456789");
00952       if (c == -1)
00953        break;
00954 
00955       switch (c)
00956        {
00957        case '0':
00958        case '1':
00959        case '2':
00960        case '3':
00961        case '4':
00962        case '5':
00963        case '6':
00964        case '7':
00965        case '8':
00966        case '9':
00967          if (digit_optind != 0 && digit_optind != this_option_optind)
00968            printf ("digits occur in two different argv-elements.\n");
00969          digit_optind = this_option_optind;
00970          printf ("option %c\n", c);
00971          break;
00972 
00973        case 'a':
00974          printf ("option a\n");
00975          break;
00976 
00977        case 'b':
00978          printf ("option b\n");
00979          break;
00980 
00981        case 'c':
00982          printf ("option c with value `%s'\n", optarg);
00983          break;
00984 
00985        case '?':
00986          break;
00987 
00988        default:
00989          printf ("?? getopt returned character code 0%o ??\n", c);
00990        }
00991     }
00992 
00993   if (optind < argc)
00994     {
00995       printf ("non-option ARGV-elements: ");
00996       while (optind < argc)
00997        printf ("%s ", argv[optind++]);
00998       printf ("\n");
00999     }
01000 
01001   exit (0);
01002 }
01003 
01004 #endif /* TEST */