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 drepper@gnu.org
00004    before changing it!
00005    Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001,2002,2003,2004
00006        Free Software Foundation, Inc.
00007    This file is part of the GNU C Library.
00008 
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; either version 2, or (at your option)
00012    any 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 along
00020    with this program; if not, write to the Free Software Foundation,
00021    Inc., 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 #include <stdio.h>
00034 
00035 /* This needs to come after some library #include
00036    to get __GNU_LIBRARY__ defined.  */
00037 #ifdef __GNU_LIBRARY__
00038 /* Don't include stdlib.h for non-GNU C libraries because some of them
00039    contain conflicting prototypes for getopt.  */
00040 # include <stdlib.h>
00041 # include <unistd.h>
00042 #endif /* GNU C library.  */
00043 
00044 #include <string.h>
00045 
00046 #ifdef VMS
00047 # include <unixlib.h>
00048 #endif
00049 
00050 #ifdef _LIBC
00051 # include <libintl.h>
00052 #else
00053 # include "gettext.h"
00054 # define _(msgid) gettext (msgid)
00055 #endif
00056 
00057 #if defined _LIBC && defined USE_IN_LIBIO
00058 # include <wchar.h>
00059 #endif
00060 
00061 #ifndef attribute_hidden
00062 # define attribute_hidden
00063 #endif
00064 
00065 /* This version of `getopt' appears to the caller like standard Unix `getopt'
00066    but it behaves differently for the user, since it allows the user
00067    to intersperse the options with the other arguments.
00068 
00069    As `getopt' works, it permutes the elements of ARGV so that,
00070    when it is done, all the options precede everything else.  Thus
00071    all application programs are extended to handle flexible argument order.
00072 
00073    Setting the environment variable POSIXLY_CORRECT disables permutation.
00074    Then the behavior is completely standard.
00075 
00076    GNU application programs can use a third alternative mode in which
00077    they can distinguish the relative order of options and other arguments.  */
00078 
00079 #include "getopt.h"
00080 #include "getopt_int.h"
00081 
00082 /* For communication from `getopt' to the caller.
00083    When `getopt' finds an option that takes an argument,
00084    the argument value is returned here.
00085    Also, when `ordering' is RETURN_IN_ORDER,
00086    each non-option ARGV-element is returned here.  */
00087 
00088 char *optarg;
00089 
00090 /* Index in ARGV of the next element to be scanned.
00091    This is used for communication to and from the caller
00092    and for communication between successive calls to `getopt'.
00093 
00094    On entry to `getopt', zero means this is the first call; initialize.
00095 
00096    When `getopt' returns -1, this is the index of the first of the
00097    non-option elements that the caller should itself scan.
00098 
00099    Otherwise, `optind' communicates from one call to the next
00100    how much of ARGV has been scanned so far.  */
00101 
00102 /* 1003.2 says this must be 1 before any call.  */
00103 int optind = 1;
00104 
00105 /* Callers store zero here to inhibit the error message
00106    for unrecognized options.  */
00107 
00108 int opterr = 1;
00109 
00110 /* Set to an option character which was unrecognized.
00111    This must be initialized on some systems to avoid linking in the
00112    system's own getopt implementation.  */
00113 
00114 int optopt = '?';
00115 
00116 /* Keep a global copy of all internal members of getopt_data.  */
00117 
00118 static struct _getopt_data getopt_data;
00119 
00120 
00121 #ifndef __GNU_LIBRARY__
00122 
00123 /* Avoid depending on library functions or files
00124    whose names are inconsistent.  */
00125 
00126 #ifndef getenv
00127 extern char *getenv ();
00128 #endif
00129 
00130 #endif /* not __GNU_LIBRARY__ */
00131 
00132 #ifdef _LIBC
00133 /* Stored original parameters.
00134    XXX This is no good solution.  We should rather copy the args so
00135    that we can compare them later.  But we must not use malloc(3).  */
00136 extern int __libc_argc;
00137 extern char **__libc_argv;
00138 
00139 /* Bash 2.0 gives us an environment variable containing flags
00140    indicating ARGV elements that should not be considered arguments.  */
00141 
00142 # ifdef USE_NONOPTION_FLAGS
00143 /* Defined in getopt_init.c  */
00144 extern char *__getopt_nonoption_flags;
00145 # endif
00146 
00147 # ifdef USE_NONOPTION_FLAGS
00148 #  define SWAP_FLAGS(ch1, ch2) \
00149   if (d->__nonoption_flags_len > 0)                                         \
00150     {                                                                \
00151       char __tmp = __getopt_nonoption_flags[ch1];                           \
00152       __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];        \
00153       __getopt_nonoption_flags[ch2] = __tmp;                                \
00154     }
00155 # else
00156 #  define SWAP_FLAGS(ch1, ch2)
00157 # endif
00158 #else  /* !_LIBC */
00159 # define SWAP_FLAGS(ch1, ch2)
00160 #endif /* _LIBC */
00161 
00162 /* Exchange two adjacent subsequences of ARGV.
00163    One subsequence is elements [first_nonopt,last_nonopt)
00164    which contains all the non-options that have been skipped so far.
00165    The other is elements [last_nonopt,optind), which contains all
00166    the options processed since those non-options were skipped.
00167 
00168    `first_nonopt' and `last_nonopt' are relocated so that they describe
00169    the new indices of the non-options in ARGV after they are moved.  */
00170 
00171 static void
00172 exchange (char **argv, struct _getopt_data *d)
00173 {
00174   int bottom = d->__first_nonopt;
00175   int middle = d->__last_nonopt;
00176   int top = d->optind;
00177   char *tem;
00178 
00179   /* Exchange the shorter segment with the far end of the longer segment.
00180      That puts the shorter segment into the right place.
00181      It leaves the longer segment in the right place overall,
00182      but it consists of two parts that need to be swapped next.  */
00183 
00184 #if defined _LIBC && defined USE_NONOPTION_FLAGS
00185   /* First make sure the handling of the `__getopt_nonoption_flags'
00186      string can work normally.  Our top argument must be in the range
00187      of the string.  */
00188   if (d->__nonoption_flags_len > 0 && top >= d->__nonoption_flags_max_len)
00189     {
00190       /* We must extend the array.  The user plays games with us and
00191         presents new arguments.  */
00192       char *new_str = malloc (top + 1);
00193       if (new_str == NULL)
00194        d->__nonoption_flags_len = d->__nonoption_flags_max_len = 0;
00195       else
00196        {
00197          memset (__mempcpy (new_str, __getopt_nonoption_flags,
00198                           d->__nonoption_flags_max_len),
00199                 '\0', top + 1 - d->__nonoption_flags_max_len);
00200          d->__nonoption_flags_max_len = top + 1;
00201          __getopt_nonoption_flags = new_str;
00202        }
00203     }
00204 #endif
00205 
00206   while (top > middle && middle > bottom)
00207     {
00208       if (top - middle > middle - bottom)
00209        {
00210          /* Bottom segment is the short one.  */
00211          int len = middle - bottom;
00212          register int i;
00213 
00214          /* Swap it with the top part of the top segment.  */
00215          for (i = 0; i < len; i++)
00216            {
00217              tem = argv[bottom + i];
00218              argv[bottom + i] = argv[top - (middle - bottom) + i];
00219              argv[top - (middle - bottom) + i] = tem;
00220              SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
00221            }
00222          /* Exclude the moved bottom segment from further swapping.  */
00223          top -= len;
00224        }
00225       else
00226        {
00227          /* Top segment is the short one.  */
00228          int len = top - middle;
00229          register int i;
00230 
00231          /* Swap it with the bottom part of the bottom segment.  */
00232          for (i = 0; i < len; i++)
00233            {
00234              tem = argv[bottom + i];
00235              argv[bottom + i] = argv[middle + i];
00236              argv[middle + i] = tem;
00237              SWAP_FLAGS (bottom + i, middle + i);
00238            }
00239          /* Exclude the moved top segment from further swapping.  */
00240          bottom += len;
00241        }
00242     }
00243 
00244   /* Update records for the slots the non-options now occupy.  */
00245 
00246   d->__first_nonopt += (d->optind - d->__last_nonopt);
00247   d->__last_nonopt = d->optind;
00248 }
00249 
00250 /* Initialize the internal data when the first call is made.  */
00251 
00252 static const char *
00253 _getopt_initialize (int argc, char *const *argv, const char *optstring,
00254                   struct _getopt_data *d)
00255 {
00256   /* Start processing options with ARGV-element 1 (since ARGV-element 0
00257      is the program name); the sequence of previously skipped
00258      non-option ARGV-elements is empty.  */
00259 
00260   d->__first_nonopt = d->__last_nonopt = d->optind;
00261 
00262   d->__nextchar = NULL;
00263 
00264   d->__posixly_correct = !!getenv ("POSIXLY_CORRECT");
00265 
00266   /* Determine how to handle the ordering of options and nonoptions.  */
00267 
00268   if (optstring[0] == '-')
00269     {
00270       d->__ordering = RETURN_IN_ORDER;
00271       ++optstring;
00272     }
00273   else if (optstring[0] == '+')
00274     {
00275       d->__ordering = REQUIRE_ORDER;
00276       ++optstring;
00277     }
00278   else if (d->__posixly_correct)
00279     d->__ordering = REQUIRE_ORDER;
00280   else
00281     d->__ordering = PERMUTE;
00282 
00283 #if defined _LIBC && defined USE_NONOPTION_FLAGS
00284   if (!d->__posixly_correct
00285       && argc == __libc_argc && argv == __libc_argv)
00286     {
00287       if (d->__nonoption_flags_max_len == 0)
00288        {
00289          if (__getopt_nonoption_flags == NULL
00290              || __getopt_nonoption_flags[0] == '\0')
00291            d->__nonoption_flags_max_len = -1;
00292          else
00293            {
00294              const char *orig_str = __getopt_nonoption_flags;
00295              int len = d->__nonoption_flags_max_len = strlen (orig_str);
00296              if (d->__nonoption_flags_max_len < argc)
00297               d->__nonoption_flags_max_len = argc;
00298              __getopt_nonoption_flags =
00299               (char *) malloc (d->__nonoption_flags_max_len);
00300              if (__getopt_nonoption_flags == NULL)
00301               d->__nonoption_flags_max_len = -1;
00302              else
00303               memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
00304                      '\0', d->__nonoption_flags_max_len - len);
00305            }
00306        }
00307       d->__nonoption_flags_len = d->__nonoption_flags_max_len;
00308     }
00309   else
00310     d->__nonoption_flags_len = 0;
00311 #endif
00312 
00313   return optstring;
00314 }
00315 
00316 /* Scan elements of ARGV (whose length is ARGC) for option characters
00317    given in OPTSTRING.
00318 
00319    If an element of ARGV starts with '-', and is not exactly "-" or "--",
00320    then it is an option element.  The characters of this element
00321    (aside from the initial '-') are option characters.  If `getopt'
00322    is called repeatedly, it returns successively each of the option characters
00323    from each of the option elements.
00324 
00325    If `getopt' finds another option character, it returns that character,
00326    updating `optind' and `nextchar' so that the next call to `getopt' can
00327    resume the scan with the following option character or ARGV-element.
00328 
00329    If there are no more option characters, `getopt' returns -1.
00330    Then `optind' is the index in ARGV of the first ARGV-element
00331    that is not an option.  (The ARGV-elements have been permuted
00332    so that those that are not options now come last.)
00333 
00334    OPTSTRING is a string containing the legitimate option characters.
00335    If an option character is seen that is not listed in OPTSTRING,
00336    return '?' after printing an error message.  If you set `opterr' to
00337    zero, the error message is suppressed but we still return '?'.
00338 
00339    If a char in OPTSTRING is followed by a colon, that means it wants an arg,
00340    so the following text in the same ARGV-element, or the text of the following
00341    ARGV-element, is returned in `optarg'.  Two colons mean an option that
00342    wants an optional arg; if there is text in the current ARGV-element,
00343    it is returned in `optarg', otherwise `optarg' is set to zero.
00344 
00345    If OPTSTRING starts with `-' or `+', it requests different methods of
00346    handling the non-option ARGV-elements.
00347    See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
00348 
00349    Long-named options begin with `--' instead of `-'.
00350    Their names may be abbreviated as long as the abbreviation is unique
00351    or is an exact match for some defined option.  If they have an
00352    argument, it follows the option name in the same ARGV-element, separated
00353    from the option name by a `=', or else the in next ARGV-element.
00354    When `getopt' finds a long-named option, it returns 0 if that option's
00355    `flag' field is nonzero, the value of the option's `val' field
00356    if the `flag' field is zero.
00357 
00358    The elements of ARGV aren't really const, because we permute them.
00359    But we pretend they're const in the prototype to be compatible
00360    with other systems.
00361 
00362    LONGOPTS is a vector of `struct option' terminated by an
00363    element containing a name which is zero.
00364 
00365    LONGIND returns the index in LONGOPT of the long-named option found.
00366    It is only valid when a long-named option has been found by the most
00367    recent call.
00368 
00369    If LONG_ONLY is nonzero, '-' as well as '--' can introduce
00370    long-named options.  */
00371 
00372 int
00373 _getopt_internal_r (int argc, char *const *argv, const char *optstring,
00374                   const struct option *longopts, int *longind,
00375                   int long_only, struct _getopt_data *d)
00376 {
00377   int print_errors = d->opterr;
00378   if (optstring[0] == ':')
00379     print_errors = 0;
00380 
00381   if (argc < 1)
00382     return -1;
00383 
00384   d->optarg = NULL;
00385 
00386   if (d->optind == 0 || !d->__initialized)
00387     {
00388       if (d->optind == 0)
00389        d->optind = 1;       /* Don't scan ARGV[0], the program name.  */
00390       optstring = _getopt_initialize (argc, argv, optstring, d);
00391       d->__initialized = 1;
00392     }
00393 
00394   /* Test whether ARGV[optind] points to a non-option argument.
00395      Either it does not have option syntax, or there is an environment flag
00396      from the shell indicating it is not an option.  The later information
00397      is only used when the used in the GNU libc.  */
00398 #if defined _LIBC && defined USE_NONOPTION_FLAGS
00399 # define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0' \
00400                     || (d->optind < d->__nonoption_flags_len                \
00401                        && __getopt_nonoption_flags[d->optind] == '1'))
00402 #else
00403 # define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0')
00404 #endif
00405 
00406   if (d->__nextchar == NULL || *d->__nextchar == '\0')
00407     {
00408       /* Advance to the next ARGV-element.  */
00409 
00410       /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
00411         moved back by the user (who may also have changed the arguments).  */
00412       if (d->__last_nonopt > d->optind)
00413        d->__last_nonopt = d->optind;
00414       if (d->__first_nonopt > d->optind)
00415        d->__first_nonopt = d->optind;
00416 
00417       if (d->__ordering == PERMUTE)
00418        {
00419          /* If we have just processed some options following some non-options,
00420             exchange them so that the options come first.  */
00421 
00422          if (d->__first_nonopt != d->__last_nonopt
00423              && d->__last_nonopt != d->optind)
00424            exchange ((char **) argv, d);
00425          else if (d->__last_nonopt != d->optind)
00426            d->__first_nonopt = d->optind;
00427 
00428          /* Skip any additional non-options
00429             and extend the range of non-options previously skipped.  */
00430 
00431          while (d->optind < argc && NONOPTION_P)
00432            d->optind++;
00433          d->__last_nonopt = d->optind;
00434        }
00435 
00436       /* The special ARGV-element `--' means premature end of options.
00437         Skip it like a null option,
00438         then exchange with previous non-options as if it were an option,
00439         then skip everything else like a non-option.  */
00440 
00441       if (d->optind != argc && !strcmp (argv[d->optind], "--"))
00442        {
00443          d->optind++;
00444 
00445          if (d->__first_nonopt != d->__last_nonopt
00446              && d->__last_nonopt != d->optind)
00447            exchange ((char **) argv, d);
00448          else if (d->__first_nonopt == d->__last_nonopt)
00449            d->__first_nonopt = d->optind;
00450          d->__last_nonopt = argc;
00451 
00452          d->optind = argc;
00453        }
00454 
00455       /* If we have done all the ARGV-elements, stop the scan
00456         and back over any non-options that we skipped and permuted.  */
00457 
00458       if (d->optind == argc)
00459        {
00460          /* Set the next-arg-index to point at the non-options
00461             that we previously skipped, so the caller will digest them.  */
00462          if (d->__first_nonopt != d->__last_nonopt)
00463            d->optind = d->__first_nonopt;
00464          return -1;
00465        }
00466 
00467       /* If we have come to a non-option and did not permute it,
00468         either stop the scan or describe it to the caller and pass it by.  */
00469 
00470       if (NONOPTION_P)
00471        {
00472          if (d->__ordering == REQUIRE_ORDER)
00473            return -1;
00474          d->optarg = argv[d->optind++];
00475          return 1;
00476        }
00477 
00478       /* We have found another option-ARGV-element.
00479         Skip the initial punctuation.  */
00480 
00481       d->__nextchar = (argv[d->optind] + 1
00482                 + (longopts != NULL && argv[d->optind][1] == '-'));
00483     }
00484 
00485   /* Decode the current option-ARGV-element.  */
00486 
00487   /* Check whether the ARGV-element is a long option.
00488 
00489      If long_only and the ARGV-element has the form "-f", where f is
00490      a valid short option, don't consider it an abbreviated form of
00491      a long option that starts with f.  Otherwise there would be no
00492      way to give the -f short option.
00493 
00494      On the other hand, if there's a long option "fubar" and
00495      the ARGV-element is "-fu", do consider that an abbreviation of
00496      the long option, just like "--fu", and not "-f" with arg "u".
00497 
00498      This distinction seems to be the most useful approach.  */
00499 
00500   if (longopts != NULL
00501       && (argv[d->optind][1] == '-'
00502          || (long_only && (argv[d->optind][2]
00503                          || !strchr (optstring, argv[d->optind][1])))))
00504     {
00505       char *nameend;
00506       const struct option *p;
00507       const struct option *pfound = NULL;
00508       int exact = 0;
00509       int ambig = 0;
00510       int indfound = -1;
00511       int option_index;
00512 
00513       for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++)
00514        /* Do nothing.  */ ;
00515 
00516       /* Test all long options for either exact match
00517         or abbreviated matches.  */
00518       for (p = longopts, option_index = 0; p->name; p++, option_index++)
00519        if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar))
00520          {
00521            if ((unsigned int) (nameend - d->__nextchar)
00522               == (unsigned int) strlen (p->name))
00523              {
00524               /* Exact match found.  */
00525               pfound = p;
00526               indfound = option_index;
00527               exact = 1;
00528               break;
00529              }
00530            else if (pfound == NULL)
00531              {
00532               /* First nonexact match found.  */
00533               pfound = p;
00534               indfound = option_index;
00535              }
00536            else if (long_only
00537                    || pfound->has_arg != p->has_arg
00538                    || pfound->flag != p->flag
00539                    || pfound->val != p->val)
00540              /* Second or later nonexact match found.  */
00541              ambig = 1;
00542          }
00543 
00544       if (ambig && !exact)
00545        {
00546          if (print_errors)
00547            {
00548 #if defined _LIBC && defined USE_IN_LIBIO
00549              char *buf;
00550 
00551              if (__asprintf (&buf, _("%s: option `%s' is ambiguous\n"),
00552                            argv[0], argv[d->optind]) >= 0)
00553               {
00554                 _IO_flockfile (stderr);
00555 
00556                 int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
00557                 ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
00558 
00559                 if (_IO_fwide (stderr, 0) > 0)
00560                   __fwprintf (stderr, L"%s", buf);
00561                 else
00562                   fputs (buf, stderr);
00563 
00564                 ((_IO_FILE *) stderr)->_flags2 = old_flags2;
00565                 _IO_funlockfile (stderr);
00566 
00567                 free (buf);
00568               }
00569 #else
00570              fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
00571                      argv[0], argv[d->optind]);
00572 #endif
00573            }
00574          d->__nextchar += strlen (d->__nextchar);
00575          d->optind++;
00576          d->optopt = 0;
00577          return '?';
00578        }
00579 
00580       if (pfound != NULL)
00581        {
00582          option_index = indfound;
00583          d->optind++;
00584          if (*nameend)
00585            {
00586              /* Don't test has_arg with >, because some C compilers don't
00587                allow it to be used on enums.  */
00588              if (pfound->has_arg)
00589               d->optarg = nameend + 1;
00590              else
00591               {
00592                 if (print_errors)
00593                   {
00594 #if defined _LIBC && defined USE_IN_LIBIO
00595                     char *buf;
00596                     int n;
00597 #endif
00598 
00599                     if (argv[d->optind - 1][1] == '-')
00600                      {
00601                        /* --option */
00602 #if defined _LIBC && defined USE_IN_LIBIO
00603                        n = __asprintf (&buf, _("\
00604 %s: option `--%s' doesn't allow an argument\n"),
00605                                      argv[0], pfound->name);
00606 #else
00607                        fprintf (stderr, _("\
00608 %s: option `--%s' doesn't allow an argument\n"),
00609                                argv[0], pfound->name);
00610 #endif
00611                      }
00612                     else
00613                      {
00614                        /* +option or -option */
00615 #if defined _LIBC && defined USE_IN_LIBIO
00616                        n = __asprintf (&buf, _("\
00617 %s: option `%c%s' doesn't allow an argument\n"),
00618                                      argv[0], argv[d->optind - 1][0],
00619                                      pfound->name);
00620 #else
00621                        fprintf (stderr, _("\
00622 %s: option `%c%s' doesn't allow an argument\n"),
00623                                argv[0], argv[d->optind - 1][0],
00624                                pfound->name);
00625 #endif
00626                      }
00627 
00628 #if defined _LIBC && defined USE_IN_LIBIO
00629                     if (n >= 0)
00630                      {
00631                        _IO_flockfile (stderr);
00632 
00633                        int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
00634                        ((_IO_FILE *) stderr)->_flags2
00635                          |= _IO_FLAGS2_NOTCANCEL;
00636 
00637                        if (_IO_fwide (stderr, 0) > 0)
00638                          __fwprintf (stderr, L"%s", buf);
00639                        else
00640                          fputs (buf, stderr);
00641 
00642                        ((_IO_FILE *) stderr)->_flags2 = old_flags2;
00643                        _IO_funlockfile (stderr);
00644 
00645                        free (buf);
00646                      }
00647 #endif
00648                   }
00649 
00650                 d->__nextchar += strlen (d->__nextchar);
00651 
00652                 d->optopt = pfound->val;
00653                 return '?';
00654               }
00655            }
00656          else if (pfound->has_arg == 1)
00657            {
00658              if (d->optind < argc)
00659               d->optarg = argv[d->optind++];
00660              else
00661               {
00662                 if (print_errors)
00663                   {
00664 #if defined _LIBC && defined USE_IN_LIBIO
00665                     char *buf;
00666 
00667                     if (__asprintf (&buf, _("\
00668 %s: option `%s' requires an argument\n"),
00669                                   argv[0], argv[d->optind - 1]) >= 0)
00670                      {
00671                        _IO_flockfile (stderr);
00672 
00673                        int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
00674                        ((_IO_FILE *) stderr)->_flags2
00675                          |= _IO_FLAGS2_NOTCANCEL;
00676 
00677                        if (_IO_fwide (stderr, 0) > 0)
00678                          __fwprintf (stderr, L"%s", buf);
00679                        else
00680                          fputs (buf, stderr);
00681 
00682                        ((_IO_FILE *) stderr)->_flags2 = old_flags2;
00683                        _IO_funlockfile (stderr);
00684 
00685                        free (buf);
00686                      }
00687 #else
00688                     fprintf (stderr,
00689                             _("%s: option `%s' requires an argument\n"),
00690                             argv[0], argv[d->optind - 1]);
00691 #endif
00692                   }
00693                 d->__nextchar += strlen (d->__nextchar);
00694                 d->optopt = pfound->val;
00695                 return optstring[0] == ':' ? ':' : '?';
00696               }
00697            }
00698          d->__nextchar += strlen (d->__nextchar);
00699          if (longind != NULL)
00700            *longind = option_index;
00701          if (pfound->flag)
00702            {
00703              *(pfound->flag) = pfound->val;
00704              return 0;
00705            }
00706          return pfound->val;
00707        }
00708 
00709       /* Can't find it as a long option.  If this is not getopt_long_only,
00710         or the option starts with '--' or is not a valid short
00711         option, then it's an error.
00712         Otherwise interpret it as a short option.  */
00713       if (!long_only || argv[d->optind][1] == '-'
00714          || strchr (optstring, *d->__nextchar) == NULL)
00715        {
00716          if (print_errors)
00717            {
00718 #if defined _LIBC && defined USE_IN_LIBIO
00719              char *buf;
00720              int n;
00721 #endif
00722 
00723              if (argv[d->optind][1] == '-')
00724               {
00725                 /* --option */
00726 #if defined _LIBC && defined USE_IN_LIBIO
00727                 n = __asprintf (&buf, _("%s: unrecognized option `--%s'\n"),
00728                               argv[0], d->__nextchar);
00729 #else
00730                 fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
00731                         argv[0], d->__nextchar);
00732 #endif
00733               }
00734              else
00735               {
00736                 /* +option or -option */
00737 #if defined _LIBC && defined USE_IN_LIBIO
00738                 n = __asprintf (&buf, _("%s: unrecognized option `%c%s'\n"),
00739                               argv[0], argv[d->optind][0], d->__nextchar);
00740 #else
00741                 fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
00742                         argv[0], argv[d->optind][0], d->__nextchar);
00743 #endif
00744               }
00745 
00746 #if defined _LIBC && defined USE_IN_LIBIO
00747              if (n >= 0)
00748               {
00749                 _IO_flockfile (stderr);
00750 
00751                 int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
00752                 ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
00753 
00754                 if (_IO_fwide (stderr, 0) > 0)
00755                   __fwprintf (stderr, L"%s", buf);
00756                 else
00757                   fputs (buf, stderr);
00758 
00759                 ((_IO_FILE *) stderr)->_flags2 = old_flags2;
00760                 _IO_funlockfile (stderr);
00761 
00762                 free (buf);
00763               }
00764 #endif
00765            }
00766          d->__nextchar = (char *) "";
00767          d->optind++;
00768          d->optopt = 0;
00769          return '?';
00770        }
00771     }
00772 
00773   /* Look at and handle the next short option-character.  */
00774 
00775   {
00776     char c = *d->__nextchar++;
00777     char *temp = strchr (optstring, c);
00778 
00779     /* Increment `optind' when we start to process its last character.  */
00780     if (*d->__nextchar == '\0')
00781       ++d->optind;
00782 
00783     if (temp == NULL || c == ':')
00784       {
00785        if (print_errors)
00786          {
00787 #if defined _LIBC && defined USE_IN_LIBIO
00788              char *buf;
00789              int n;
00790 #endif
00791 
00792            if (d->__posixly_correct)
00793              {
00794               /* 1003.2 specifies the format of this message.  */
00795 #if defined _LIBC && defined USE_IN_LIBIO
00796               n = __asprintf (&buf, _("%s: illegal option -- %c\n"),
00797                             argv[0], c);
00798 #else
00799               fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c);
00800 #endif
00801              }
00802            else
00803              {
00804 #if defined _LIBC && defined USE_IN_LIBIO
00805               n = __asprintf (&buf, _("%s: invalid option -- %c\n"),
00806                             argv[0], c);
00807 #else
00808               fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c);
00809 #endif
00810              }
00811 
00812 #if defined _LIBC && defined USE_IN_LIBIO
00813            if (n >= 0)
00814              {
00815               _IO_flockfile (stderr);
00816 
00817               int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
00818               ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
00819 
00820               if (_IO_fwide (stderr, 0) > 0)
00821                 __fwprintf (stderr, L"%s", buf);
00822               else
00823                 fputs (buf, stderr);
00824 
00825               ((_IO_FILE *) stderr)->_flags2 = old_flags2;
00826               _IO_funlockfile (stderr);
00827 
00828               free (buf);
00829              }
00830 #endif
00831          }
00832        d->optopt = c;
00833        return '?';
00834       }
00835     /* Convenience. Treat POSIX -W foo same as long option --foo */
00836     if (temp[0] == 'W' && temp[1] == ';')
00837       {
00838        char *nameend;
00839        const struct option *p;
00840        const struct option *pfound = NULL;
00841        int exact = 0;
00842        int ambig = 0;
00843        int indfound = 0;
00844        int option_index;
00845 
00846        /* This is an option that requires an argument.  */
00847        if (*d->__nextchar != '\0')
00848          {
00849            d->optarg = d->__nextchar;
00850            /* If we end this ARGV-element by taking the rest as an arg,
00851               we must advance to the next element now.  */
00852            d->optind++;
00853          }
00854        else if (d->optind == argc)
00855          {
00856            if (print_errors)
00857              {
00858               /* 1003.2 specifies the format of this message.  */
00859 #if defined _LIBC && defined USE_IN_LIBIO
00860               char *buf;
00861 
00862               if (__asprintf (&buf,
00863                             _("%s: option requires an argument -- %c\n"),
00864                             argv[0], c) >= 0)
00865                 {
00866                   _IO_flockfile (stderr);
00867 
00868                   int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
00869                   ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
00870 
00871                   if (_IO_fwide (stderr, 0) > 0)
00872                     __fwprintf (stderr, L"%s", buf);
00873                   else
00874                     fputs (buf, stderr);
00875 
00876                   ((_IO_FILE *) stderr)->_flags2 = old_flags2;
00877                   _IO_funlockfile (stderr);
00878 
00879                   free (buf);
00880                 }
00881 #else
00882               fprintf (stderr, _("%s: option requires an argument -- %c\n"),
00883                       argv[0], c);
00884 #endif
00885              }
00886            d->optopt = c;
00887            if (optstring[0] == ':')
00888              c = ':';
00889            else
00890              c = '?';
00891            return c;
00892          }
00893        else
00894          /* We already incremented `d->optind' once;
00895             increment it again when taking next ARGV-elt as argument.  */
00896          d->optarg = argv[d->optind++];
00897 
00898        /* optarg is now the argument, see if it's in the
00899           table of longopts.  */
00900 
00901        for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != '=';
00902             nameend++)
00903          /* Do nothing.  */ ;
00904 
00905        /* Test all long options for either exact match
00906           or abbreviated matches.  */
00907        for (p = longopts, option_index = 0; p->name; p++, option_index++)
00908          if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar))
00909            {
00910              if ((unsigned int) (nameend - d->__nextchar) == strlen (p->name))
00911               {
00912                 /* Exact match found.  */
00913                 pfound = p;
00914                 indfound = option_index;
00915                 exact = 1;
00916                 break;
00917               }
00918              else if (pfound == NULL)
00919               {
00920                 /* First nonexact match found.  */
00921                 pfound = p;
00922                 indfound = option_index;
00923               }
00924              else
00925               /* Second or later nonexact match found.  */
00926               ambig = 1;
00927            }
00928        if (ambig && !exact)
00929          {
00930            if (print_errors)
00931              {
00932 #if defined _LIBC && defined USE_IN_LIBIO
00933               char *buf;
00934 
00935               if (__asprintf (&buf, _("%s: option `-W %s' is ambiguous\n"),
00936                             argv[0], argv[d->optind]) >= 0)
00937                 {
00938                   _IO_flockfile (stderr);
00939 
00940                   int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
00941                   ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
00942 
00943                   if (_IO_fwide (stderr, 0) > 0)
00944                     __fwprintf (stderr, L"%s", buf);
00945                   else
00946                     fputs (buf, stderr);
00947 
00948                   ((_IO_FILE *) stderr)->_flags2 = old_flags2;
00949                   _IO_funlockfile (stderr);
00950 
00951                   free (buf);
00952                 }
00953 #else
00954               fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
00955                       argv[0], argv[d->optind]);
00956 #endif
00957              }
00958            d->__nextchar += strlen (d->__nextchar);
00959            d->optind++;
00960            return '?';
00961          }
00962        if (pfound != NULL)
00963          {
00964            option_index = indfound;
00965            if (*nameend)
00966              {
00967               /* Don't test has_arg with >, because some C compilers don't
00968                  allow it to be used on enums.  */
00969               if (pfound->has_arg)
00970                 d->optarg = nameend + 1;
00971               else
00972                 {
00973                   if (print_errors)
00974                     {
00975 #if defined _LIBC && defined USE_IN_LIBIO
00976                      char *buf;
00977 
00978                      if (__asprintf (&buf, _("\
00979 %s: option `-W %s' doesn't allow an argument\n"),
00980                                    argv[0], pfound->name) >= 0)
00981                        {
00982                          _IO_flockfile (stderr);
00983 
00984                          int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
00985                          ((_IO_FILE *) stderr)->_flags2
00986                            |= _IO_FLAGS2_NOTCANCEL;
00987 
00988                          if (_IO_fwide (stderr, 0) > 0)
00989                            __fwprintf (stderr, L"%s", buf);
00990                          else
00991                            fputs (buf, stderr);
00992 
00993                          ((_IO_FILE *) stderr)->_flags2 = old_flags2;
00994                          _IO_funlockfile (stderr);
00995 
00996                          free (buf);
00997                        }
00998 #else
00999                      fprintf (stderr, _("\
01000 %s: option `-W %s' doesn't allow an argument\n"),
01001                              argv[0], pfound->name);
01002 #endif
01003                     }
01004 
01005                   d->__nextchar += strlen (d->__nextchar);
01006                   return '?';
01007                 }
01008              }
01009            else if (pfound->has_arg == 1)
01010              {
01011               if (d->optind < argc)
01012                 d->optarg = argv[d->optind++];
01013               else
01014                 {
01015                   if (print_errors)
01016                     {
01017 #if defined _LIBC && defined USE_IN_LIBIO
01018                      char *buf;
01019 
01020                      if (__asprintf (&buf, _("\
01021 %s: option `%s' requires an argument\n"),
01022                                    argv[0], argv[d->optind - 1]) >= 0)
01023                        {
01024                          _IO_flockfile (stderr);
01025 
01026                          int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
01027                          ((_IO_FILE *) stderr)->_flags2
01028                            |= _IO_FLAGS2_NOTCANCEL;
01029 
01030                          if (_IO_fwide (stderr, 0) > 0)
01031                            __fwprintf (stderr, L"%s", buf);
01032                          else
01033                            fputs (buf, stderr);
01034 
01035                          ((_IO_FILE *) stderr)->_flags2 = old_flags2;
01036                          _IO_funlockfile (stderr);
01037 
01038                          free (buf);
01039                        }
01040 #else
01041                      fprintf (stderr,
01042                              _("%s: option `%s' requires an argument\n"),
01043                              argv[0], argv[d->optind - 1]);
01044 #endif
01045                     }
01046                   d->__nextchar += strlen (d->__nextchar);
01047                   return optstring[0] == ':' ? ':' : '?';
01048                 }
01049              }
01050            d->__nextchar += strlen (d->__nextchar);
01051            if (longind != NULL)
01052              *longind = option_index;
01053            if (pfound->flag)
01054              {
01055               *(pfound->flag) = pfound->val;
01056               return 0;
01057              }
01058            return pfound->val;
01059          }
01060          d->__nextchar = NULL;
01061          return 'W'; /* Let the application handle it.   */
01062       }
01063     if (temp[1] == ':')
01064       {
01065        if (temp[2] == ':')
01066          {
01067            /* This is an option that accepts an argument optionally.  */
01068            if (*d->__nextchar != '\0')
01069              {
01070               d->optarg = d->__nextchar;
01071               d->optind++;
01072              }
01073            else
01074              d->optarg = NULL;
01075            d->__nextchar = NULL;
01076          }
01077        else
01078          {
01079            /* This is an option that requires an argument.  */
01080            if (*d->__nextchar != '\0')
01081              {
01082               d->optarg = d->__nextchar;
01083               /* If we end this ARGV-element by taking the rest as an arg,
01084                  we must advance to the next element now.  */
01085               d->optind++;
01086              }
01087            else if (d->optind == argc)
01088              {
01089               if (print_errors)
01090                 {
01091                   /* 1003.2 specifies the format of this message.  */
01092 #if defined _LIBC && defined USE_IN_LIBIO
01093                   char *buf;
01094 
01095                   if (__asprintf (&buf, _("\
01096 %s: option requires an argument -- %c\n"),
01097                                 argv[0], c) >= 0)
01098                     {
01099                      _IO_flockfile (stderr);
01100 
01101                      int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
01102                      ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
01103 
01104                      if (_IO_fwide (stderr, 0) > 0)
01105                        __fwprintf (stderr, L"%s", buf);
01106                      else
01107                        fputs (buf, stderr);
01108 
01109                      ((_IO_FILE *) stderr)->_flags2 = old_flags2;
01110                      _IO_funlockfile (stderr);
01111 
01112                      free (buf);
01113                     }
01114 #else
01115                   fprintf (stderr,
01116                           _("%s: option requires an argument -- %c\n"),
01117                           argv[0], c);
01118 #endif
01119                 }
01120               d->optopt = c;
01121               if (optstring[0] == ':')
01122                 c = ':';
01123               else
01124                 c = '?';
01125              }
01126            else
01127              /* We already incremented `optind' once;
01128                increment it again when taking next ARGV-elt as argument.  */
01129              d->optarg = argv[d->optind++];
01130            d->__nextchar = NULL;
01131          }
01132       }
01133     return c;
01134   }
01135 }
01136 
01137 int
01138 _getopt_internal (int argc, char *const *argv, const char *optstring,
01139                 const struct option *longopts, int *longind, int long_only)
01140 {
01141   int result;
01142 
01143   getopt_data.optind = optind;
01144   getopt_data.opterr = opterr;
01145 
01146   result = _getopt_internal_r (argc, argv, optstring, longopts,
01147                             longind, long_only, &getopt_data);
01148 
01149   optind = getopt_data.optind;
01150   optarg = getopt_data.optarg;
01151   optopt = getopt_data.optopt;
01152 
01153   return result;
01154 }
01155 
01156 int
01157 getopt (int argc, char *const *argv, const char *optstring)
01158 {
01159   return _getopt_internal (argc, argv, optstring,
01160                         (const struct option *) 0,
01161                         (int *) 0,
01162                         0);
01163 }
01164 
01165 
01166 #ifdef TEST
01167 
01168 /* Compile with -DTEST to make an executable for use in testing
01169    the above definition of `getopt'.  */
01170 
01171 int
01172 main (int argc, char **argv)
01173 {
01174   int c;
01175   int digit_optind = 0;
01176 
01177   while (1)
01178     {
01179       int this_option_optind = optind ? optind : 1;
01180 
01181       c = getopt (argc, argv, "abc:d:0123456789");
01182       if (c == -1)
01183        break;
01184 
01185       switch (c)
01186        {
01187        case '0':
01188        case '1':
01189        case '2':
01190        case '3':
01191        case '4':
01192        case '5':
01193        case '6':
01194        case '7':
01195        case '8':
01196        case '9':
01197          if (digit_optind != 0 && digit_optind != this_option_optind)
01198            printf ("digits occur in two different argv-elements.\n");
01199          digit_optind = this_option_optind;
01200          printf ("option %c\n", c);
01201          break;
01202 
01203        case 'a':
01204          printf ("option a\n");
01205          break;
01206 
01207        case 'b':
01208          printf ("option b\n");
01209          break;
01210 
01211        case 'c':
01212          printf ("option c with value `%s'\n", optarg);
01213          break;
01214 
01215        case '?':
01216          break;
01217 
01218        default:
01219          printf ("?? getopt returned character code 0%o ??\n", c);
01220        }
01221     }
01222 
01223   if (optind < argc)
01224     {
01225       printf ("non-option ARGV-elements: ");
01226       while (optind < argc)
01227        printf ("%s ", argv[optind++]);
01228       printf ("\n");
01229     }
01230 
01231   exit (0);
01232 }
01233 
01234 #endif /* TEST */