メインページ   クラス階層   構成   ファイル一覧   構成メンバ   ファイルメンバ  

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

Wed Dec 29 11:51:36 2004に生成されました。 doxygen1.2.18
SEO [PR] 爆速!無料ブログ 無料ホームページ開設 無料ライブ放送