Back to index

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