Back to index

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