getopt_long_only.c

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

Generated on Tue Nov 4 13:27:39 2008 for libspf2 by  doxygen 1.5.4