common/getopt.cc

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

Documentation for Xapian (version 1.0.20).
Generated on 28 Apr 2010 by Doxygen 1.5.2.