"Fossies" - the Fresh Open Source Software Archive

Member "httperf-0.9.0/src/lib/getopt.c" (26 Jan 2007, 24221 Bytes) of package /linux/www/old/httperf-0.9.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "getopt.c" see the Fossies "Dox" file reference documentation.

    1 /* Getopt for GNU.
    2    NOTE: getopt is now part of the C library, so if you don't know what
    3    "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
    4    before changing it!
    5 
    6    Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 1996
    7     Free Software Foundation, Inc.
    8 
    9 This file is part of the GNU C Library.  Its master source is NOT part of
   10 the C library, however.  The master source lives in /gd/gnu/lib.
   11 
   12 The GNU C Library is free software; you can redistribute it and/or
   13 modify it under the terms of the GNU Library General Public License as
   14 published by the Free Software Foundation; either version 2 of the
   15 License, or (at your option) any later version.
   16 
   17 The GNU C Library is distributed in the hope that it will be useful,
   18 but WITHOUT ANY WARRANTY; without even the implied warranty of
   19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   20 Library General Public License for more details.
   21 
   22 You should have received a copy of the GNU Library General Public
   23 License along with the GNU C Library; see the file COPYING.LIB.  If
   24 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
   25 Cambridge, MA 02139, USA.  */
   26 
   27 /* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
   28    Ditto for AIX 3.2 and <stdlib.h>.  */
   29 #ifndef _NO_PROTO
   30 #define _NO_PROTO
   31 #endif
   32 
   33 #include "config.h"
   34 
   35 #ifndef HAVE_GETOPT_LONG
   36 
   37 #if !defined (__STDC__) || !__STDC__
   38 /* This is a separate conditional since some stdc systems
   39    reject `defined (const)'.  */
   40 #ifndef const
   41 #define const
   42 #endif
   43 #endif
   44 
   45 #include <stdio.h>
   46 
   47 /* Comment out all this code if we are using the GNU C Library, and are not
   48    actually compiling the library itself.  This code is part of the GNU C
   49    Library, but also included in many other GNU distributions.  Compiling
   50    and linking in this code is a waste when using the GNU C library
   51    (especially if it is a shared library).  Rather than having every GNU
   52    program understand `configure --with-gnu-libc' and omit the object files,
   53    it is simpler to just do this in the source for each such file.  */
   54 
   55 #if defined (_LIBC) || !defined (__GNU_LIBRARY__)
   56 
   57 
   58 /* This needs to come after some library #include
   59    to get __GNU_LIBRARY__ defined.  */
   60 #ifdef  __GNU_LIBRARY__
   61 /* Don't include stdlib.h for non-GNU C libraries because some of them
   62    contain conflicting prototypes for getopt.  */
   63 #include <stdlib.h>
   64 #include <unistd.h>
   65 #endif  /* GNU C library.  */
   66 
   67 #ifdef VMS
   68 #include <unixlib.h>
   69 #if HAVE_STRING_H - 0
   70 #include <string.h>
   71 #endif
   72 #endif
   73 
   74 #if defined (WIN32) && !defined (__CYGWIN32__)
   75 /* It's not Unix, really.  See?  Capital letters.  */
   76 #include <windows.h>
   77 #define getpid() GetCurrentProcessId()
   78 #endif
   79 
   80 #ifndef _
   81 /* This is for other GNU distributions with internationalized messages.
   82    When compiling libc, the _ macro is predefined.  */
   83 #if defined(HAVE_LIBINTL_H) && defined(ENABLE_NLS)
   84 # include <libintl.h>
   85 # define _(msgid)   gettext (msgid)
   86 #else
   87 # define _(msgid)   (msgid)
   88 #endif
   89 #endif
   90 
   91 /* This version of `getopt' appears to the caller like standard Unix `getopt'
   92    but it behaves differently for the user, since it allows the user
   93    to intersperse the options with the other arguments.
   94 
   95    As `getopt' works, it permutes the elements of ARGV so that,
   96    when it is done, all the options precede everything else.  Thus
   97    all application programs are extended to handle flexible argument order.
   98 
   99    Setting the environment variable POSIXLY_CORRECT disables permutation.
  100    Then the behavior is completely standard.
  101 
  102    GNU application programs can use a third alternative mode in which
  103    they can distinguish the relative order of options and other arguments.  */
  104 
  105 #include "getopt.h"
  106 
  107 /* For communication from `getopt' to the caller.
  108    When `getopt' finds an option that takes an argument,
  109    the argument value is returned here.
  110    Also, when `ordering' is RETURN_IN_ORDER,
  111    each non-option ARGV-element is returned here.  */
  112 
  113 char *optarg = NULL;
  114 
  115 /* Index in ARGV of the next element to be scanned.
  116    This is used for communication to and from the caller
  117    and for communication between successive calls to `getopt'.
  118 
  119    On entry to `getopt', zero means this is the first call; initialize.
  120 
  121    When `getopt' returns EOF, this is the index of the first of the
  122    non-option elements that the caller should itself scan.
  123 
  124    Otherwise, `optind' communicates from one call to the next
  125    how much of ARGV has been scanned so far.  */
  126 
  127 /* XXX 1003.2 says this must be 1 before any call.  */
  128 int optind = 0;
  129 
  130 /* The next char to be scanned in the option-element
  131    in which the last option character we returned was found.
  132    This allows us to pick up the scan where we left off.
  133 
  134    If this is zero, or a null string, it means resume the scan
  135    by advancing to the next ARGV-element.  */
  136 
  137 static char *nextchar;
  138 
  139 /* Callers store zero here to inhibit the error message
  140    for unrecognized options.  */
  141 
  142 int opterr = 1;
  143 
  144 /* Set to an option character which was unrecognized.
  145    This must be initialized on some systems to avoid linking in the
  146    system's own getopt implementation.  */
  147 
  148 int optopt = '?';
  149 
  150 /* Describe how to deal with options that follow non-option ARGV-elements.
  151 
  152    If the caller did not specify anything,
  153    the default is REQUIRE_ORDER if the environment variable
  154    POSIXLY_CORRECT is defined, PERMUTE otherwise.
  155 
  156    REQUIRE_ORDER means don't recognize them as options;
  157    stop option processing when the first non-option is seen.
  158    This is what Unix does.
  159    This mode of operation is selected by either setting the environment
  160    variable POSIXLY_CORRECT, or using `+' as the first character
  161    of the list of option characters.
  162 
  163    PERMUTE is the default.  We permute the contents of ARGV as we scan,
  164    so that eventually all the non-options are at the end.  This allows options
  165    to be given in any order, even with programs that were not written to
  166    expect this.
  167 
  168    RETURN_IN_ORDER is an option available to programs that were written
  169    to expect options and other ARGV-elements in any order and that care about
  170    the ordering of the two.  We describe each non-option ARGV-element
  171    as if it were the argument of an option with character code 1.
  172    Using `-' as the first character of the list of option characters
  173    selects this mode of operation.
  174 
  175    The special argument `--' forces an end of option-scanning regardless
  176    of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
  177    `--' can cause `getopt' to return EOF with `optind' != ARGC.  */
  178 
  179 static enum
  180 {
  181   REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
  182 } ordering;
  183 
  184 /* Value of POSIXLY_CORRECT environment variable.  */
  185 static char *posixly_correct;
  186 
  187 #ifdef  __GNU_LIBRARY__
  188 /* We want to avoid inclusion of string.h with non-GNU libraries
  189    because there are many ways it can cause trouble.
  190    On some systems, it contains special magic macros that don't work
  191    in GCC.  */
  192 #include <string.h>
  193 #define my_index    strchr
  194 #else
  195 
  196 /* Avoid depending on library functions or files
  197    whose names are inconsistent.  */
  198 
  199 char *getenv ();
  200 
  201 static char *
  202 my_index (str, chr)
  203      const char *str;
  204      int chr;
  205 {
  206   while (*str)
  207     {
  208       if (*str == chr)
  209     return (char *) str;
  210       str++;
  211     }
  212   return 0;
  213 }
  214 
  215 /* If using GCC, we can safely declare strlen this way.
  216    If not using GCC, it is ok not to declare it.  */
  217 #ifdef __GNUC__
  218 /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
  219    That was relevant to code that was here before.  */
  220 #if !defined (__STDC__) || !__STDC__
  221 /* gcc with -traditional declares the built-in strlen to return int,
  222    and has done so at least since version 2.4.5. -- rms.  */
  223 extern int strlen (const char *);
  224 #endif /* not __STDC__ */
  225 #endif /* __GNUC__ */
  226 
  227 #endif /* not __GNU_LIBRARY__ */
  228 
  229 /* Handle permutation of arguments.  */
  230 
  231 /* Describe the part of ARGV that contains non-options that have
  232    been skipped.  `first_nonopt' is the index in ARGV of the first of them;
  233    `last_nonopt' is the index after the last of them.  */
  234 
  235 static int first_nonopt;
  236 static int last_nonopt;
  237 
  238 /* Bash 2.0 gives us an environment variable containing flags
  239    indicating ARGV elements that should not be considered arguments.  */
  240 
  241 static const char *nonoption_flags;
  242 static int nonoption_flags_len;
  243 
  244 /* Exchange two adjacent subsequences of ARGV.
  245    One subsequence is elements [first_nonopt,last_nonopt)
  246    which contains all the non-options that have been skipped so far.
  247    The other is elements [last_nonopt,optind), which contains all
  248    the options processed since those non-options were skipped.
  249 
  250    `first_nonopt' and `last_nonopt' are relocated so that they describe
  251    the new indices of the non-options in ARGV after they are moved.  */
  252 
  253 #if defined (__STDC__) && __STDC__
  254 static void exchange (char **);
  255 #endif
  256 
  257 static void
  258 exchange (argv)
  259      char **argv;
  260 {
  261   int bottom = first_nonopt;
  262   int middle = last_nonopt;
  263   int top = optind;
  264   char *tem;
  265 
  266   /* Exchange the shorter segment with the far end of the longer segment.
  267      That puts the shorter segment into the right place.
  268      It leaves the longer segment in the right place overall,
  269      but it consists of two parts that need to be swapped next.  */
  270 
  271   while (top > middle && middle > bottom)
  272     {
  273       if (top - middle > middle - bottom)
  274     {
  275       /* Bottom segment is the short one.  */
  276       int len = middle - bottom;
  277       register int i;
  278 
  279       /* Swap it with the top part of the top segment.  */
  280       for (i = 0; i < len; i++)
  281         {
  282           tem = argv[bottom + i];
  283           argv[bottom + i] = argv[top - (middle - bottom) + i];
  284           argv[top - (middle - bottom) + i] = tem;
  285         }
  286       /* Exclude the moved bottom segment from further swapping.  */
  287       top -= len;
  288     }
  289       else
  290     {
  291       /* Top segment is the short one.  */
  292       int len = top - middle;
  293       register int i;
  294 
  295       /* Swap it with the bottom part of the bottom segment.  */
  296       for (i = 0; i < len; i++)
  297         {
  298           tem = argv[bottom + i];
  299           argv[bottom + i] = argv[middle + i];
  300           argv[middle + i] = tem;
  301         }
  302       /* Exclude the moved top segment from further swapping.  */
  303       bottom += len;
  304     }
  305     }
  306 
  307   /* Update records for the slots the non-options now occupy.  */
  308 
  309   first_nonopt += (optind - last_nonopt);
  310   last_nonopt = optind;
  311 }
  312 
  313 /* Initialize the internal data when the first call is made.  */
  314 
  315 #if defined (__STDC__) && __STDC__
  316 static const char *_getopt_initialize (const char *);
  317 #endif
  318 static const char *
  319 _getopt_initialize (optstring)
  320      const char *optstring;
  321 {
  322   /* Start processing options with ARGV-element 1 (since ARGV-element 0
  323      is the program name); the sequence of previously skipped
  324      non-option ARGV-elements is empty.  */
  325 
  326   first_nonopt = last_nonopt = optind = 1;
  327 
  328   nextchar = NULL;
  329 
  330   posixly_correct = getenv ("POSIXLY_CORRECT");
  331 
  332   /* Determine how to handle the ordering of options and nonoptions.  */
  333 
  334   if (optstring[0] == '-')
  335     {
  336       ordering = RETURN_IN_ORDER;
  337       ++optstring;
  338     }
  339   else if (optstring[0] == '+')
  340     {
  341       ordering = REQUIRE_ORDER;
  342       ++optstring;
  343     }
  344   else if (posixly_correct != NULL)
  345     ordering = REQUIRE_ORDER;
  346   else
  347     ordering = PERMUTE;
  348 
  349   if (posixly_correct == NULL)
  350     {
  351       /* Bash 2.0 puts a special variable in the environment for each
  352      command it runs, specifying which ARGV elements are the results of
  353      file name wildcard expansion and therefore should not be
  354      considered as options.  */
  355       char var[100];
  356       snprintf (var, sizeof(var), "_%d_GNU_nonoption_argv_flags_", getpid ());
  357       nonoption_flags = getenv (var);
  358       if (nonoption_flags == NULL)
  359     nonoption_flags_len = 0;
  360       else
  361     nonoption_flags_len = strlen (nonoption_flags);
  362     }
  363 
  364   return optstring;
  365 }
  366 
  367 /* Scan elements of ARGV (whose length is ARGC) for option characters
  368    given in OPTSTRING.
  369 
  370    If an element of ARGV starts with '-', and is not exactly "-" or "--",
  371    then it is an option element.  The characters of this element
  372    (aside from the initial '-') are option characters.  If `getopt'
  373    is called repeatedly, it returns successively each of the option characters
  374    from each of the option elements.
  375 
  376    If `getopt' finds another option character, it returns that character,
  377    updating `optind' and `nextchar' so that the next call to `getopt' can
  378    resume the scan with the following option character or ARGV-element.
  379 
  380    If there are no more option characters, `getopt' returns `EOF'.
  381    Then `optind' is the index in ARGV of the first ARGV-element
  382    that is not an option.  (The ARGV-elements have been permuted
  383    so that those that are not options now come last.)
  384 
  385    OPTSTRING is a string containing the legitimate option characters.
  386    If an option character is seen that is not listed in OPTSTRING,
  387    return '?' after printing an error message.  If you set `opterr' to
  388    zero, the error message is suppressed but we still return '?'.
  389 
  390    If a char in OPTSTRING is followed by a colon, that means it wants an arg,
  391    so the following text in the same ARGV-element, or the text of the following
  392    ARGV-element, is returned in `optarg'.  Two colons mean an option that
  393    wants an optional arg; if there is text in the current ARGV-element,
  394    it is returned in `optarg', otherwise `optarg' is set to zero.
  395 
  396    If OPTSTRING starts with `-' or `+', it requests different methods of
  397    handling the non-option ARGV-elements.
  398    See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
  399 
  400    Long-named options begin with `--' instead of `-'.
  401    Their names may be abbreviated as long as the abbreviation is unique
  402    or is an exact match for some defined option.  If they have an
  403    argument, it follows the option name in the same ARGV-element, separated
  404    from the option name by a `=', or else the in next ARGV-element.
  405    When `getopt' finds a long-named option, it returns 0 if that option's
  406    `flag' field is nonzero, the value of the option's `val' field
  407    if the `flag' field is zero.
  408 
  409    The elements of ARGV aren't really const, because we permute them.
  410    But we pretend they're const in the prototype to be compatible
  411    with other systems.
  412 
  413    LONGOPTS is a vector of `struct option' terminated by an
  414    element containing a name which is zero.
  415 
  416    LONGIND returns the index in LONGOPT of the long-named option found.
  417    It is only valid when a long-named option has been found by the most
  418    recent call.
  419 
  420    If LONG_ONLY is nonzero, '-' as well as '--' can introduce
  421    long-named options.  */
  422 
  423 int
  424 _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
  425      int argc;
  426      char *const *argv;
  427      const char *optstring;
  428      const struct option *longopts;
  429      int *longind;
  430      int long_only;
  431 {
  432   optarg = NULL;
  433 
  434   if (optind == 0)
  435     {
  436       optstring = _getopt_initialize (optstring);
  437       optind = 1;       /* Don't scan ARGV[0], the program name.  */
  438     }
  439 
  440   /* Test whether ARGV[optind] points to a non-option argument.
  441      Either it does not have option syntax, or there is an environment flag
  442      from the shell indicating it is not an option.  */
  443 #define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'        \
  444              || (optind < nonoption_flags_len                 \
  445              && nonoption_flags[optind] == '1'))
  446 
  447   if (nextchar == NULL || *nextchar == '\0')
  448     {
  449       /* Advance to the next ARGV-element.  */
  450 
  451       /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
  452      moved back by the user (who may also have changed the arguments).  */
  453       if (last_nonopt > optind)
  454     last_nonopt = optind;
  455       if (first_nonopt > optind)
  456     first_nonopt = optind;
  457 
  458       if (ordering == PERMUTE)
  459     {
  460       /* If we have just processed some options following some non-options,
  461          exchange them so that the options come first.  */
  462 
  463       if (first_nonopt != last_nonopt && last_nonopt != optind)
  464         exchange ((char **) argv);
  465       else if (last_nonopt != optind)
  466         first_nonopt = optind;
  467 
  468       /* Skip any additional non-options
  469          and extend the range of non-options previously skipped.  */
  470 
  471       while (optind < argc && NONOPTION_P)
  472         optind++;
  473       last_nonopt = optind;
  474     }
  475 
  476       /* The special ARGV-element `--' means premature end of options.
  477      Skip it like a null option,
  478      then exchange with previous non-options as if it were an option,
  479      then skip everything else like a non-option.  */
  480 
  481       if (optind != argc && !strcmp (argv[optind], "--"))
  482     {
  483       optind++;
  484 
  485       if (first_nonopt != last_nonopt && last_nonopt != optind)
  486         exchange ((char **) argv);
  487       else if (first_nonopt == last_nonopt)
  488         first_nonopt = optind;
  489       last_nonopt = argc;
  490 
  491       optind = argc;
  492     }
  493 
  494       /* If we have done all the ARGV-elements, stop the scan
  495      and back over any non-options that we skipped and permuted.  */
  496 
  497       if (optind == argc)
  498     {
  499       /* Set the next-arg-index to point at the non-options
  500          that we previously skipped, so the caller will digest them.  */
  501       if (first_nonopt != last_nonopt)
  502         optind = first_nonopt;
  503       return EOF;
  504     }
  505 
  506       /* If we have come to a non-option and did not permute it,
  507      either stop the scan or describe it to the caller and pass it by.  */
  508 
  509       if (NONOPTION_P)
  510     {
  511       if (ordering == REQUIRE_ORDER)
  512         return EOF;
  513       optarg = argv[optind++];
  514       return 1;
  515     }
  516 
  517       /* We have found another option-ARGV-element.
  518      Skip the initial punctuation.  */
  519 
  520       nextchar = (argv[optind] + 1
  521           + (longopts != NULL && argv[optind][1] == '-'));
  522     }
  523 
  524   /* Decode the current option-ARGV-element.  */
  525 
  526   /* Check whether the ARGV-element is a long option.
  527 
  528      If long_only and the ARGV-element has the form "-f", where f is
  529      a valid short option, don't consider it an abbreviated form of
  530      a long option that starts with f.  Otherwise there would be no
  531      way to give the -f short option.
  532 
  533      On the other hand, if there's a long option "fubar" and
  534      the ARGV-element is "-fu", do consider that an abbreviation of
  535      the long option, just like "--fu", and not "-f" with arg "u".
  536 
  537      This distinction seems to be the most useful approach.  */
  538 
  539   if (longopts != NULL
  540       && (argv[optind][1] == '-'
  541       || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
  542     {
  543       char *nameend;
  544       const struct option *p;
  545       const struct option *pfound = NULL;
  546       int exact = 0;
  547       int ambig = 0;
  548       int indfound;
  549       int option_index;
  550 
  551       for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
  552     /* Do nothing.  */ ;
  553 
  554       /* Test all long options for either exact match
  555      or abbreviated matches.  */
  556       for (p = longopts, option_index = 0; p->name; p++, option_index++)
  557     if (!strncmp (p->name, nextchar, nameend - nextchar))
  558       {
  559         if (nameend - nextchar == strlen (p->name))
  560           {
  561         /* Exact match found.  */
  562         pfound = p;
  563         indfound = option_index;
  564         exact = 1;
  565         break;
  566           }
  567         else if (pfound == NULL)
  568           {
  569         /* First nonexact match found.  */
  570         pfound = p;
  571         indfound = option_index;
  572           }
  573         else
  574           /* Second or later nonexact match found.  */
  575           ambig = 1;
  576       }
  577 
  578       if (ambig && !exact)
  579     {
  580       if (opterr)
  581         fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
  582              argv[0], argv[optind]);
  583       nextchar += strlen (nextchar);
  584       optind++;
  585       optopt = 0;
  586       return '?';
  587     }
  588 
  589       if (pfound != NULL)
  590     {
  591       option_index = indfound;
  592       optind++;
  593       if (*nameend)
  594         {
  595           /* Don't test has_arg with >, because some C compilers don't
  596          allow it to be used on enums.  */
  597           if (pfound->has_arg)
  598         optarg = nameend + 1;
  599           else
  600         {
  601           if (opterr)
  602            if (argv[optind - 1][1] == '-')
  603             /* --option */
  604             fprintf (stderr,
  605              _("%s: option `--%s' doesn't allow an argument\n"),
  606              argv[0], pfound->name);
  607            else
  608             /* +option or -option */
  609             fprintf (stderr,
  610              _("%s: option `%c%s' doesn't allow an argument\n"),
  611              argv[0], argv[optind - 1][0], pfound->name);
  612 
  613           nextchar += strlen (nextchar);
  614 
  615           optopt = pfound->val;
  616           return '?';
  617         }
  618         }
  619       else if (pfound->has_arg == 1)
  620         {
  621           if (optind < argc)
  622         optarg = argv[optind++];
  623           else
  624         {
  625           if (opterr)
  626             fprintf (stderr,
  627                _("%s: option `%s' requires an argument\n"),
  628                argv[0], argv[optind - 1]);
  629           nextchar += strlen (nextchar);
  630           optopt = pfound->val;
  631           return optstring[0] == ':' ? ':' : '?';
  632         }
  633         }
  634       nextchar += strlen (nextchar);
  635       if (longind != NULL)
  636         *longind = option_index;
  637       if (pfound->flag)
  638         {
  639           *(pfound->flag) = pfound->val;
  640           return 0;
  641         }
  642       return pfound->val;
  643     }
  644 
  645       /* Can't find it as a long option.  If this is not getopt_long_only,
  646      or the option starts with '--' or is not a valid short
  647      option, then it's an error.
  648      Otherwise interpret it as a short option.  */
  649       if (!long_only || argv[optind][1] == '-'
  650       || my_index (optstring, *nextchar) == NULL)
  651     {
  652       if (opterr)
  653         {
  654           if (argv[optind][1] == '-')
  655         /* --option */
  656         fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
  657              argv[0], nextchar);
  658           else
  659         /* +option or -option */
  660         fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
  661              argv[0], argv[optind][0], nextchar);
  662         }
  663       nextchar = (char *) "";
  664       optind++;
  665       optopt = 0;
  666       return '?';
  667     }
  668     }
  669 
  670   /* Look at and handle the next short option-character.  */
  671 
  672   {
  673     char c = *nextchar++;
  674     char *temp = my_index (optstring, c);
  675 
  676     /* Increment `optind' when we start to process its last character.  */
  677     if (*nextchar == '\0')
  678       ++optind;
  679 
  680     if (temp == NULL || c == ':')
  681       {
  682     if (opterr)
  683       {
  684         if (posixly_correct)
  685           /* 1003.2 specifies the format of this message.  */
  686           fprintf (stderr, _("%s: illegal option -- %c\n"),
  687                argv[0], c);
  688         else
  689           fprintf (stderr, _("%s: invalid option -- %c\n"),
  690                argv[0], c);
  691       }
  692     optopt = c;
  693     return '?';
  694       }
  695     if (temp[1] == ':')
  696       {
  697     if (temp[2] == ':')
  698       {
  699         /* This is an option that accepts an argument optionally.  */
  700         if (*nextchar != '\0')
  701           {
  702         optarg = nextchar;
  703         optind++;
  704           }
  705         else
  706           optarg = NULL;
  707         nextchar = NULL;
  708       }
  709     else
  710       {
  711         /* This is an option that requires an argument.  */
  712         if (*nextchar != '\0')
  713           {
  714         optarg = nextchar;
  715         /* If we end this ARGV-element by taking the rest as an arg,
  716            we must advance to the next element now.  */
  717         optind++;
  718           }
  719         else if (optind == argc)
  720           {
  721         if (opterr)
  722           {
  723             /* 1003.2 specifies the format of this message.  */
  724             fprintf (stderr,
  725                _("%s: option requires an argument -- %c\n"),
  726                argv[0], c);
  727           }
  728         optopt = c;
  729         if (optstring[0] == ':')
  730           c = ':';
  731         else
  732           c = '?';
  733           }
  734         else
  735           /* We already incremented `optind' once;
  736          increment it again when taking next ARGV-elt as argument.  */
  737           optarg = argv[optind++];
  738         nextchar = NULL;
  739       }
  740       }
  741     return c;
  742   }
  743 }
  744 
  745 int
  746 getopt (argc, argv, optstring)
  747      int argc;
  748      char *const *argv;
  749      const char *optstring;
  750 {
  751   return _getopt_internal (argc, argv, optstring,
  752                (const struct option *) 0,
  753                (int *) 0,
  754                0);
  755 }
  756 
  757 #endif  /* _LIBC or not __GNU_LIBRARY__.  */
  758 
  759 #ifdef TEST
  760 
  761 /* Compile with -DTEST to make an executable for use in testing
  762    the above definition of `getopt'.  */
  763 
  764 int
  765 main (argc, argv)
  766      int argc;
  767      char **argv;
  768 {
  769   int c;
  770   int digit_optind = 0;
  771 
  772   while (1)
  773     {
  774       int this_option_optind = optind ? optind : 1;
  775 
  776       c = getopt (argc, argv, "abc:d:0123456789");
  777       if (c == EOF)
  778     break;
  779 
  780       switch (c)
  781     {
  782     case '0':
  783     case '1':
  784     case '2':
  785     case '3':
  786     case '4':
  787     case '5':
  788     case '6':
  789     case '7':
  790     case '8':
  791     case '9':
  792       if (digit_optind != 0 && digit_optind != this_option_optind)
  793         printf ("digits occur in two different argv-elements.\n");
  794       digit_optind = this_option_optind;
  795       printf ("option %c\n", c);
  796       break;
  797 
  798     case 'a':
  799       printf ("option a\n");
  800       break;
  801 
  802     case 'b':
  803       printf ("option b\n");
  804       break;
  805 
  806     case 'c':
  807       printf ("option c with value `%s'\n", optarg);
  808       break;
  809 
  810     case '?':
  811       break;
  812 
  813     default:
  814       printf ("?? getopt returned character code 0%o ??\n", c);
  815     }
  816     }
  817 
  818   if (optind < argc)
  819     {
  820       printf ("non-option ARGV-elements: ");
  821       while (optind < argc)
  822     printf ("%s ", argv[optind++]);
  823       printf ("\n");
  824     }
  825 
  826   exit (0);
  827 }
  828 
  829 #endif /* TEST */
  830 #endif /* HAVE_GETOPT_LONG */