nico@215: nico@215: nico@215: CanFestival: examples/TestMasterMicroMod/getopt.c Source File nico@215: nico@215: nico@215: nico@215: nico@215:
nico@215:
nico@215:
nico@215:
nico@215: nico@215:

getopt.c

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

Generated on Mon Jul 2 19:10:16 2007 for CanFestival by  nico@215: nico@215: doxygen 1.5.1
nico@215: nico@215: