Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

getopt.c

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

Generated on Tue Dec 20 10:14:59 2005 for vlc-0.8.4a by  doxygen 1.4.2