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

Documentation for Xapian (version 1.0.10).
Generated on 24 Dec 2008 by Doxygen 1.5.2.