"Fossies" - the Fresh Open Source Software Archive

Member "xzgv-0.9.2/src/getopt.c" (3 Sep 2017, 30146 Bytes) of package /linux/misc/old/xzgv-0.9.2.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 /* assume non-glibc systems are at least ANSI :-) -rjm */
    2 #define HAVE_STRING_H   1
    3 
    4 /* Getopt for GNU.
    5    NOTE: getopt is now part of the C library, so if you don't know what
    6    "Keep this file name-space clean" means, talk to drepper@gnu.org
    7    before changing it!
    8 
    9    Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99
   10     Free Software Foundation, Inc.
   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 not,
   24    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   25    Boston, MA 02111-1307, 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 #ifdef HAVE_CONFIG_H
   34 # include <config.h>
   35 #endif
   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 #define GETOPT_INTERFACE_VERSION 2
   56 #if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
   57 # include <gnu-versions.h>
   58 # if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
   59 #  define ELIDE_CODE
   60 # endif
   61 #endif
   62 
   63 #ifndef ELIDE_CODE
   64 
   65 
   66 /* This needs to come after some library #include
   67    to get __GNU_LIBRARY__ defined.  */
   68 #ifdef  __GNU_LIBRARY__
   69 /* Don't include stdlib.h for non-GNU C libraries because some of them
   70    contain conflicting prototypes for getopt.  */
   71 # include <stdlib.h>
   72 # include <unistd.h>
   73 #endif  /* GNU C library.  */
   74 
   75 #ifdef VMS
   76 # include <unixlib.h>
   77 # if HAVE_STRING_H - 0
   78 #  include <string.h>
   79 # endif
   80 #endif
   81 
   82 #ifndef _
   83 /* This is for other GNU distributions with internationalized messages.
   84    When compiling libc, the _ macro is predefined.  */
   85 # ifdef HAVE_LIBINTL_H
   86 #  include <libintl.h>
   87 #  define _(msgid)  gettext (msgid)
   88 # else
   89 #  define _(msgid)  (msgid)
   90 # endif
   91 #endif
   92 
   93 /* This version of `getopt' appears to the caller like standard Unix `getopt'
   94    but it behaves differently for the user, since it allows the user
   95    to intersperse the options with the other arguments.
   96 
   97    As `getopt' works, it permutes the elements of ARGV so that,
   98    when it is done, all the options precede everything else.  Thus
   99    all application programs are extended to handle flexible argument order.
  100 
  101    Setting the environment variable POSIXLY_CORRECT disables permutation.
  102    Then the behavior is completely standard.
  103 
  104    GNU application programs can use a third alternative mode in which
  105    they can distinguish the relative order of options and other arguments.  */
  106 
  107 #include "getopt.h"
  108 
  109 /* For communication from `getopt' to the caller.
  110    When `getopt' finds an option that takes an argument,
  111    the argument value is returned here.
  112    Also, when `ordering' is RETURN_IN_ORDER,
  113    each non-option ARGV-element is returned here.  */
  114 
  115 char *optarg;
  116 
  117 /* Index in ARGV of the next element to be scanned.
  118    This is used for communication to and from the caller
  119    and for communication between successive calls to `getopt'.
  120 
  121    On entry to `getopt', zero means this is the first call; initialize.
  122 
  123    When `getopt' returns -1, this is the index of the first of the
  124    non-option elements that the caller should itself scan.
  125 
  126    Otherwise, `optind' communicates from one call to the next
  127    how much of ARGV has been scanned so far.  */
  128 
  129 /* 1003.2 says this must be 1 before any call.  */
  130 int optind = 1;
  131 
  132 /* Formerly, initialization of getopt depended on optind==0, which
  133    causes problems with re-calling getopt as programs generally don't
  134    know that. */
  135 
  136 int __getopt_initialized;
  137 
  138 /* The next char to be scanned in the option-element
  139    in which the last option character we returned was found.
  140    This allows us to pick up the scan where we left off.
  141 
  142    If this is zero, or a null string, it means resume the scan
  143    by advancing to the next ARGV-element.  */
  144 
  145 static char *nextchar;
  146 
  147 /* Callers store zero here to inhibit the error message
  148    for unrecognized options.  */
  149 
  150 int opterr = 1;
  151 
  152 /* Set to an option character which was unrecognized.
  153    This must be initialized on some systems to avoid linking in the
  154    system's own getopt implementation.  */
  155 
  156 int optopt = '?';
  157 
  158 /* Describe how to deal with options that follow non-option ARGV-elements.
  159 
  160    If the caller did not specify anything,
  161    the default is REQUIRE_ORDER if the environment variable
  162    POSIXLY_CORRECT is defined, PERMUTE otherwise.
  163 
  164    REQUIRE_ORDER means don't recognize them as options;
  165    stop option processing when the first non-option is seen.
  166    This is what Unix does.
  167    This mode of operation is selected by either setting the environment
  168    variable POSIXLY_CORRECT, or using `+' as the first character
  169    of the list of option characters.
  170 
  171    PERMUTE is the default.  We permute the contents of ARGV as we scan,
  172    so that eventually all the non-options are at the end.  This allows options
  173    to be given in any order, even with programs that were not written to
  174    expect this.
  175 
  176    RETURN_IN_ORDER is an option available to programs that were written
  177    to expect options and other ARGV-elements in any order and that care about
  178    the ordering of the two.  We describe each non-option ARGV-element
  179    as if it were the argument of an option with character code 1.
  180    Using `-' as the first character of the list of option characters
  181    selects this mode of operation.
  182 
  183    The special argument `--' forces an end of option-scanning regardless
  184    of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
  185    `--' can cause `getopt' to return -1 with `optind' != ARGC.  */
  186 
  187 static enum
  188 {
  189   REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
  190 } ordering;
  191 
  192 /* Value of POSIXLY_CORRECT environment variable.  */
  193 static char *posixly_correct;
  194 
  195 #ifdef  __GNU_LIBRARY__
  196 /* We want to avoid inclusion of string.h with non-GNU libraries
  197    because there are many ways it can cause trouble.
  198    On some systems, it contains special magic macros that don't work
  199    in GCC.  */
  200 # include <string.h>
  201 # define my_index   strchr
  202 #else
  203 
  204 # if HAVE_STRING_H
  205 #  include <string.h>
  206 # else
  207 #  include <strings.h>
  208 # endif
  209 
  210 /* Avoid depending on library functions or files
  211    whose names are inconsistent.  */
  212 
  213 #ifndef getenv
  214 extern char *getenv ();
  215 #endif
  216 
  217 static char *
  218 my_index (str, chr)
  219      const char *str;
  220      int chr;
  221 {
  222   while (*str)
  223     {
  224       if (*str == chr)
  225     return (char *) str;
  226       str++;
  227     }
  228   return 0;
  229 }
  230 
  231 /* If using GCC, we can safely declare strlen this way.
  232    If not using GCC, it is ok not to declare it.  */
  233 #ifdef __GNUC__
  234 /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
  235    That was relevant to code that was here before.  */
  236 # if (!defined __STDC__ || !__STDC__) && !defined strlen
  237 /* gcc with -traditional declares the built-in strlen to return int,
  238    and has done so at least since version 2.4.5. -- rms.  */
  239 extern int strlen (const char *);
  240 # endif /* not __STDC__ */
  241 #endif /* __GNUC__ */
  242 
  243 #endif /* not __GNU_LIBRARY__ */
  244 
  245 /* Handle permutation of arguments.  */
  246 
  247 /* Describe the part of ARGV that contains non-options that have
  248    been skipped.  `first_nonopt' is the index in ARGV of the first of them;
  249    `last_nonopt' is the index after the last of them.  */
  250 
  251 static int first_nonopt;
  252 static int last_nonopt;
  253 
  254 #ifdef _LIBC
  255 /* Bash 2.0 gives us an environment variable containing flags
  256    indicating ARGV elements that should not be considered arguments.  */
  257 
  258 /* Defined in getopt_init.c  */
  259 extern char *__getopt_nonoption_flags;
  260 
  261 static int nonoption_flags_max_len;
  262 static int nonoption_flags_len;
  263 
  264 static int original_argc;
  265 static char *const *original_argv;
  266 
  267 /* Make sure the environment variable bash 2.0 puts in the environment
  268    is valid for the getopt call we must make sure that the ARGV passed
  269    to getopt is that one passed to the process.  */
  270 static void
  271 __attribute__ ((unused))
  272 store_args_and_env (int argc, char *const *argv)
  273 {
  274   /* XXX This is no good solution.  We should rather copy the args so
  275      that we can compare them later.  But we must not use malloc(3).  */
  276   original_argc = argc;
  277   original_argv = argv;
  278 }
  279 # ifdef text_set_element
  280 text_set_element (__libc_subinit, store_args_and_env);
  281 # endif /* text_set_element */
  282 
  283 # define SWAP_FLAGS(ch1, ch2) \
  284   if (nonoption_flags_len > 0)                            \
  285     {                                         \
  286       char __tmp = __getopt_nonoption_flags[ch1];                 \
  287       __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];          \
  288       __getopt_nonoption_flags[ch2] = __tmp;                      \
  289     }
  290 #else   /* !_LIBC */
  291 # define SWAP_FLAGS(ch1, ch2)
  292 #endif  /* _LIBC */
  293 
  294 /* Exchange two adjacent subsequences of ARGV.
  295    One subsequence is elements [first_nonopt,last_nonopt)
  296    which contains all the non-options that have been skipped so far.
  297    The other is elements [last_nonopt,optind), which contains all
  298    the options processed since those non-options were skipped.
  299 
  300    `first_nonopt' and `last_nonopt' are relocated so that they describe
  301    the new indices of the non-options in ARGV after they are moved.  */
  302 
  303 #if defined __STDC__ && __STDC__
  304 static void exchange (char **);
  305 #endif
  306 
  307 static void
  308 exchange (argv)
  309      char **argv;
  310 {
  311   int bottom = first_nonopt;
  312   int middle = last_nonopt;
  313   int top = optind;
  314   char *tem;
  315 
  316   /* Exchange the shorter segment with the far end of the longer segment.
  317      That puts the shorter segment into the right place.
  318      It leaves the longer segment in the right place overall,
  319      but it consists of two parts that need to be swapped next.  */
  320 
  321 #ifdef _LIBC
  322   /* First make sure the handling of the `__getopt_nonoption_flags'
  323      string can work normally.  Our top argument must be in the range
  324      of the string.  */
  325   if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
  326     {
  327       /* We must extend the array.  The user plays games with us and
  328      presents new arguments.  */
  329       char *new_str = malloc (top + 1);
  330       if (new_str == NULL)
  331     nonoption_flags_len = nonoption_flags_max_len = 0;
  332       else
  333     {
  334       memset (__mempcpy (new_str, __getopt_nonoption_flags,
  335                  nonoption_flags_max_len),
  336           '\0', top + 1 - nonoption_flags_max_len);
  337       nonoption_flags_max_len = top + 1;
  338       __getopt_nonoption_flags = new_str;
  339     }
  340     }
  341 #endif
  342 
  343   while (top > middle && middle > bottom)
  344     {
  345       if (top - middle > middle - bottom)
  346     {
  347       /* Bottom segment is the short one.  */
  348       int len = middle - bottom;
  349       register int i;
  350 
  351       /* Swap it with the top part of the top segment.  */
  352       for (i = 0; i < len; i++)
  353         {
  354           tem = argv[bottom + i];
  355           argv[bottom + i] = argv[top - (middle - bottom) + i];
  356           argv[top - (middle - bottom) + i] = tem;
  357           SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
  358         }
  359       /* Exclude the moved bottom segment from further swapping.  */
  360       top -= len;
  361     }
  362       else
  363     {
  364       /* Top segment is the short one.  */
  365       int len = top - middle;
  366       register int i;
  367 
  368       /* Swap it with the bottom part of the bottom segment.  */
  369       for (i = 0; i < len; i++)
  370         {
  371           tem = argv[bottom + i];
  372           argv[bottom + i] = argv[middle + i];
  373           argv[middle + i] = tem;
  374           SWAP_FLAGS (bottom + i, middle + i);
  375         }
  376       /* Exclude the moved top segment from further swapping.  */
  377       bottom += len;
  378     }
  379     }
  380 
  381   /* Update records for the slots the non-options now occupy.  */
  382 
  383   first_nonopt += (optind - last_nonopt);
  384   last_nonopt = optind;
  385 }
  386 
  387 /* Initialize the internal data when the first call is made.  */
  388 
  389 #if defined __STDC__ && __STDC__
  390 static const char *_getopt_initialize (int, char *const *, const char *);
  391 #endif
  392 static const char *
  393 _getopt_initialize (argc, argv, optstring)
  394      int argc;
  395      char *const *argv;
  396      const char *optstring;
  397 {
  398   /* Start processing options with ARGV-element 1 (since ARGV-element 0
  399      is the program name); the sequence of previously skipped
  400      non-option ARGV-elements is empty.  */
  401 
  402   first_nonopt = last_nonopt = optind;
  403 
  404   nextchar = NULL;
  405 
  406   posixly_correct = getenv ("POSIXLY_CORRECT");
  407 
  408   /* Determine how to handle the ordering of options and nonoptions.  */
  409 
  410   if (optstring[0] == '-')
  411     {
  412       ordering = RETURN_IN_ORDER;
  413       ++optstring;
  414     }
  415   else if (optstring[0] == '+')
  416     {
  417       ordering = REQUIRE_ORDER;
  418       ++optstring;
  419     }
  420   else if (posixly_correct != NULL)
  421     ordering = REQUIRE_ORDER;
  422   else
  423     ordering = PERMUTE;
  424 
  425 #ifdef _LIBC
  426   if (posixly_correct == NULL
  427       && argc == original_argc && argv == original_argv)
  428     {
  429       if (nonoption_flags_max_len == 0)
  430     {
  431       if (__getopt_nonoption_flags == NULL
  432           || __getopt_nonoption_flags[0] == '\0')
  433         nonoption_flags_max_len = -1;
  434       else
  435         {
  436           const char *orig_str = __getopt_nonoption_flags;
  437           int len = nonoption_flags_max_len = strlen (orig_str);
  438           if (nonoption_flags_max_len < argc)
  439         nonoption_flags_max_len = argc;
  440           __getopt_nonoption_flags =
  441         (char *) malloc (nonoption_flags_max_len);
  442           if (__getopt_nonoption_flags == NULL)
  443         nonoption_flags_max_len = -1;
  444           else
  445         memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
  446             '\0', nonoption_flags_max_len - len);
  447         }
  448     }
  449       nonoption_flags_len = nonoption_flags_max_len;
  450     }
  451   else
  452     nonoption_flags_len = 0;
  453 #endif
  454 
  455   return optstring;
  456 }
  457 
  458 /* Scan elements of ARGV (whose length is ARGC) for option characters
  459    given in OPTSTRING.
  460 
  461    If an element of ARGV starts with '-', and is not exactly "-" or "--",
  462    then it is an option element.  The characters of this element
  463    (aside from the initial '-') are option characters.  If `getopt'
  464    is called repeatedly, it returns successively each of the option characters
  465    from each of the option elements.
  466 
  467    If `getopt' finds another option character, it returns that character,
  468    updating `optind' and `nextchar' so that the next call to `getopt' can
  469    resume the scan with the following option character or ARGV-element.
  470 
  471    If there are no more option characters, `getopt' returns -1.
  472    Then `optind' is the index in ARGV of the first ARGV-element
  473    that is not an option.  (The ARGV-elements have been permuted
  474    so that those that are not options now come last.)
  475 
  476    OPTSTRING is a string containing the legitimate option characters.
  477    If an option character is seen that is not listed in OPTSTRING,
  478    return '?' after printing an error message.  If you set `opterr' to
  479    zero, the error message is suppressed but we still return '?'.
  480 
  481    If a char in OPTSTRING is followed by a colon, that means it wants an arg,
  482    so the following text in the same ARGV-element, or the text of the following
  483    ARGV-element, is returned in `optarg'.  Two colons mean an option that
  484    wants an optional arg; if there is text in the current ARGV-element,
  485    it is returned in `optarg', otherwise `optarg' is set to zero.
  486 
  487    If OPTSTRING starts with `-' or `+', it requests different methods of
  488    handling the non-option ARGV-elements.
  489    See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
  490 
  491    Long-named options begin with `--' instead of `-'.
  492    Their names may be abbreviated as long as the abbreviation is unique
  493    or is an exact match for some defined option.  If they have an
  494    argument, it follows the option name in the same ARGV-element, separated
  495    from the option name by a `=', or else the in next ARGV-element.
  496    When `getopt' finds a long-named option, it returns 0 if that option's
  497    `flag' field is nonzero, the value of the option's `val' field
  498    if the `flag' field is zero.
  499 
  500    The elements of ARGV aren't really const, because we permute them.
  501    But we pretend they're const in the prototype to be compatible
  502    with other systems.
  503 
  504    LONGOPTS is a vector of `struct option' terminated by an
  505    element containing a name which is zero.
  506 
  507    LONGIND returns the index in LONGOPT of the long-named option found.
  508    It is only valid when a long-named option has been found by the most
  509    recent call.
  510 
  511    If LONG_ONLY is nonzero, '-' as well as '--' can introduce
  512    long-named options.  */
  513 
  514 int
  515 _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
  516      int argc;
  517      char *const *argv;
  518      const char *optstring;
  519      const struct option *longopts;
  520      int *longind;
  521      int long_only;
  522 {
  523   optarg = NULL;
  524 
  525   if (optind == 0 || !__getopt_initialized)
  526     {
  527       if (optind == 0)
  528     optind = 1; /* Don't scan ARGV[0], the program name.  */
  529       optstring = _getopt_initialize (argc, argv, optstring);
  530       __getopt_initialized = 1;
  531     }
  532 
  533   /* Test whether ARGV[optind] points to a non-option argument.
  534      Either it does not have option syntax, or there is an environment flag
  535      from the shell indicating it is not an option.  The later information
  536      is only used when the used in the GNU libc.  */
  537 #ifdef _LIBC
  538 # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'       \
  539               || (optind < nonoption_flags_len                \
  540               && __getopt_nonoption_flags[optind] == '1'))
  541 #else
  542 # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
  543 #endif
  544 
  545   if (nextchar == NULL || *nextchar == '\0')
  546     {
  547       /* Advance to the next ARGV-element.  */
  548 
  549       /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
  550      moved back by the user (who may also have changed the arguments).  */
  551       if (last_nonopt > optind)
  552     last_nonopt = optind;
  553       if (first_nonopt > optind)
  554     first_nonopt = optind;
  555 
  556       if (ordering == PERMUTE)
  557     {
  558       /* If we have just processed some options following some non-options,
  559          exchange them so that the options come first.  */
  560 
  561       if (first_nonopt != last_nonopt && last_nonopt != optind)
  562         exchange ((char **) argv);
  563       else if (last_nonopt != optind)
  564         first_nonopt = optind;
  565 
  566       /* Skip any additional non-options
  567          and extend the range of non-options previously skipped.  */
  568 
  569       while (optind < argc && NONOPTION_P)
  570         optind++;
  571       last_nonopt = optind;
  572     }
  573 
  574       /* The special ARGV-element `--' means premature end of options.
  575      Skip it like a null option,
  576      then exchange with previous non-options as if it were an option,
  577      then skip everything else like a non-option.  */
  578 
  579       if (optind != argc && !strcmp (argv[optind], "--"))
  580     {
  581       optind++;
  582 
  583       if (first_nonopt != last_nonopt && last_nonopt != optind)
  584         exchange ((char **) argv);
  585       else if (first_nonopt == last_nonopt)
  586         first_nonopt = optind;
  587       last_nonopt = argc;
  588 
  589       optind = argc;
  590     }
  591 
  592       /* If we have done all the ARGV-elements, stop the scan
  593      and back over any non-options that we skipped and permuted.  */
  594 
  595       if (optind == argc)
  596     {
  597       /* Set the next-arg-index to point at the non-options
  598          that we previously skipped, so the caller will digest them.  */
  599       if (first_nonopt != last_nonopt)
  600         optind = first_nonopt;
  601       return -1;
  602     }
  603 
  604       /* If we have come to a non-option and did not permute it,
  605      either stop the scan or describe it to the caller and pass it by.  */
  606 
  607       if (NONOPTION_P)
  608     {
  609       if (ordering == REQUIRE_ORDER)
  610         return -1;
  611       optarg = argv[optind++];
  612       return 1;
  613     }
  614 
  615       /* We have found another option-ARGV-element.
  616      Skip the initial punctuation.  */
  617 
  618       nextchar = (argv[optind] + 1
  619           + (longopts != NULL && argv[optind][1] == '-'));
  620     }
  621 
  622   /* Decode the current option-ARGV-element.  */
  623 
  624   /* Check whether the ARGV-element is a long option.
  625 
  626      If long_only and the ARGV-element has the form "-f", where f is
  627      a valid short option, don't consider it an abbreviated form of
  628      a long option that starts with f.  Otherwise there would be no
  629      way to give the -f short option.
  630 
  631      On the other hand, if there's a long option "fubar" and
  632      the ARGV-element is "-fu", do consider that an abbreviation of
  633      the long option, just like "--fu", and not "-f" with arg "u".
  634 
  635      This distinction seems to be the most useful approach.  */
  636 
  637   if (longopts != NULL
  638       && (argv[optind][1] == '-'
  639       || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
  640     {
  641       char *nameend;
  642       const struct option *p;
  643       const struct option *pfound = NULL;
  644       int exact = 0;
  645       int ambig = 0;
  646       int indfound = -1;
  647       int option_index;
  648 
  649       for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
  650     /* Do nothing.  */ ;
  651 
  652       /* Test all long options for either exact match
  653      or abbreviated matches.  */
  654       for (p = longopts, option_index = 0; p->name; p++, option_index++)
  655     if (!strncmp (p->name, nextchar, nameend - nextchar))
  656       {
  657         if ((unsigned int) (nameend - nextchar)
  658         == (unsigned int) strlen (p->name))
  659           {
  660         /* Exact match found.  */
  661         pfound = p;
  662         indfound = option_index;
  663         exact = 1;
  664         break;
  665           }
  666         else if (pfound == NULL)
  667           {
  668         /* First nonexact match found.  */
  669         pfound = p;
  670         indfound = option_index;
  671           }
  672         else
  673           /* Second or later nonexact match found.  */
  674           ambig = 1;
  675       }
  676 
  677       if (ambig && !exact)
  678     {
  679       if (opterr)
  680         fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
  681              argv[0], argv[optind]);
  682       nextchar += strlen (nextchar);
  683       optind++;
  684       optopt = 0;
  685       return '?';
  686     }
  687 
  688       if (pfound != NULL)
  689     {
  690       option_index = indfound;
  691       optind++;
  692       if (*nameend)
  693         {
  694           /* Don't test has_arg with >, because some C compilers don't
  695          allow it to be used on enums.  */
  696           if (pfound->has_arg)
  697         optarg = nameend + 1;
  698           else
  699         {
  700           if (opterr)
  701             {
  702               if (argv[optind - 1][1] == '-')
  703             /* --option */
  704             fprintf (stderr,
  705                  _("%s: option `--%s' doesn't allow an argument\n"),
  706                  argv[0], pfound->name);
  707               else
  708             /* +option or -option */
  709             fprintf (stderr,
  710                  _("%s: option `%c%s' doesn't allow an argument\n"),
  711                  argv[0], argv[optind - 1][0], pfound->name);
  712             }
  713 
  714           nextchar += strlen (nextchar);
  715 
  716           optopt = pfound->val;
  717           return '?';
  718         }
  719         }
  720       else if (pfound->has_arg == 1)
  721         {
  722           if (optind < argc)
  723         optarg = argv[optind++];
  724           else
  725         {
  726           if (opterr)
  727             fprintf (stderr,
  728                _("%s: option `%s' requires an argument\n"),
  729                argv[0], argv[optind - 1]);
  730           nextchar += strlen (nextchar);
  731           optopt = pfound->val;
  732           return optstring[0] == ':' ? ':' : '?';
  733         }
  734         }
  735       nextchar += strlen (nextchar);
  736       if (longind != NULL)
  737         *longind = option_index;
  738       if (pfound->flag)
  739         {
  740           *(pfound->flag) = pfound->val;
  741           return 0;
  742         }
  743       return pfound->val;
  744     }
  745 
  746       /* Can't find it as a long option.  If this is not getopt_long_only,
  747      or the option starts with '--' or is not a valid short
  748      option, then it's an error.
  749      Otherwise interpret it as a short option.  */
  750       if (!long_only || argv[optind][1] == '-'
  751       || my_index (optstring, *nextchar) == NULL)
  752     {
  753       if (opterr)
  754         {
  755           if (argv[optind][1] == '-')
  756         /* --option */
  757         fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
  758              argv[0], nextchar);
  759           else
  760         /* +option or -option */
  761         fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
  762              argv[0], argv[optind][0], nextchar);
  763         }
  764       nextchar = (char *) "";
  765       optind++;
  766       optopt = 0;
  767       return '?';
  768     }
  769     }
  770 
  771   /* Look at and handle the next short option-character.  */
  772 
  773   {
  774     char c = *nextchar++;
  775     char *temp = my_index (optstring, c);
  776 
  777     /* Increment `optind' when we start to process its last character.  */
  778     if (*nextchar == '\0')
  779       ++optind;
  780 
  781     if (temp == NULL || c == ':')
  782       {
  783     if (opterr)
  784       {
  785         if (posixly_correct)
  786           /* 1003.2 specifies the format of this message.  */
  787           fprintf (stderr, _("%s: illegal option -- %c\n"),
  788                argv[0], c);
  789         else
  790           fprintf (stderr, _("%s: invalid option -- %c\n"),
  791                argv[0], c);
  792       }
  793     optopt = c;
  794     return '?';
  795       }
  796     /* Convenience. Treat POSIX -W foo same as long option --foo */
  797     if (temp[0] == 'W' && temp[1] == ';')
  798       {
  799     char *nameend;
  800     const struct option *p;
  801     const struct option *pfound = NULL;
  802     int exact = 0;
  803     int ambig = 0;
  804     int indfound = 0;
  805     int option_index;
  806 
  807     /* This is an option that requires an argument.  */
  808     if (*nextchar != '\0')
  809       {
  810         optarg = nextchar;
  811         /* If we end this ARGV-element by taking the rest as an arg,
  812            we must advance to the next element now.  */
  813         optind++;
  814       }
  815     else if (optind == argc)
  816       {
  817         if (opterr)
  818           {
  819         /* 1003.2 specifies the format of this message.  */
  820         fprintf (stderr, _("%s: option requires an argument -- %c\n"),
  821              argv[0], c);
  822           }
  823         optopt = c;
  824         if (optstring[0] == ':')
  825           c = ':';
  826         else
  827           c = '?';
  828         return c;
  829       }
  830     else
  831       /* We already incremented `optind' once;
  832          increment it again when taking next ARGV-elt as argument.  */
  833       optarg = argv[optind++];
  834 
  835     /* optarg is now the argument, see if it's in the
  836        table of longopts.  */
  837 
  838     for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
  839       /* Do nothing.  */ ;
  840 
  841     /* Test all long options for either exact match
  842        or abbreviated matches.  */
  843     for (p = longopts, option_index = 0; p->name; p++, option_index++)
  844       if (!strncmp (p->name, nextchar, nameend - nextchar))
  845         {
  846           if ((unsigned int) (nameend - nextchar) == strlen (p->name))
  847         {
  848           /* Exact match found.  */
  849           pfound = p;
  850           indfound = option_index;
  851           exact = 1;
  852           break;
  853         }
  854           else if (pfound == NULL)
  855         {
  856           /* First nonexact match found.  */
  857           pfound = p;
  858           indfound = option_index;
  859         }
  860           else
  861         /* Second or later nonexact match found.  */
  862         ambig = 1;
  863         }
  864     if (ambig && !exact)
  865       {
  866         if (opterr)
  867           fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
  868                argv[0], argv[optind]);
  869         nextchar += strlen (nextchar);
  870         optind++;
  871         return '?';
  872       }
  873     if (pfound != NULL)
  874       {
  875         option_index = indfound;
  876         if (*nameend)
  877           {
  878         /* Don't test has_arg with >, because some C compilers don't
  879            allow it to be used on enums.  */
  880         if (pfound->has_arg)
  881           optarg = nameend + 1;
  882         else
  883           {
  884             if (opterr)
  885               fprintf (stderr, _("\
  886 %s: option `-W %s' doesn't allow an argument\n"),
  887                    argv[0], pfound->name);
  888 
  889             nextchar += strlen (nextchar);
  890             return '?';
  891           }
  892           }
  893         else if (pfound->has_arg == 1)
  894           {
  895         if (optind < argc)
  896           optarg = argv[optind++];
  897         else
  898           {
  899             if (opterr)
  900               fprintf (stderr,
  901                    _("%s: option `%s' requires an argument\n"),
  902                    argv[0], argv[optind - 1]);
  903             nextchar += strlen (nextchar);
  904             return optstring[0] == ':' ? ':' : '?';
  905           }
  906           }
  907         nextchar += strlen (nextchar);
  908         if (longind != NULL)
  909           *longind = option_index;
  910         if (pfound->flag)
  911           {
  912         *(pfound->flag) = pfound->val;
  913         return 0;
  914           }
  915         return pfound->val;
  916       }
  917       nextchar = NULL;
  918       return 'W';   /* Let the application handle it.   */
  919       }
  920     if (temp[1] == ':')
  921       {
  922     if (temp[2] == ':')
  923       {
  924         /* This is an option that accepts an argument optionally.  */
  925         if (*nextchar != '\0')
  926           {
  927         optarg = nextchar;
  928         optind++;
  929           }
  930         else
  931           optarg = NULL;
  932         nextchar = NULL;
  933       }
  934     else
  935       {
  936         /* This is an option that requires an argument.  */
  937         if (*nextchar != '\0')
  938           {
  939         optarg = nextchar;
  940         /* If we end this ARGV-element by taking the rest as an arg,
  941            we must advance to the next element now.  */
  942         optind++;
  943           }
  944         else if (optind == argc)
  945           {
  946         if (opterr)
  947           {
  948             /* 1003.2 specifies the format of this message.  */
  949             fprintf (stderr,
  950                _("%s: option requires an argument -- %c\n"),
  951                argv[0], c);
  952           }
  953         optopt = c;
  954         if (optstring[0] == ':')
  955           c = ':';
  956         else
  957           c = '?';
  958           }
  959         else
  960           /* We already incremented `optind' once;
  961          increment it again when taking next ARGV-elt as argument.  */
  962           optarg = argv[optind++];
  963         nextchar = NULL;
  964       }
  965       }
  966     return c;
  967   }
  968 }
  969 
  970 int
  971 getopt (argc, argv, optstring)
  972      int argc;
  973      char *const *argv;
  974      const char *optstring;
  975 {
  976   return _getopt_internal (argc, argv, optstring,
  977                (const struct option *) 0,
  978                (int *) 0,
  979                0);
  980 }
  981 
  982 #endif  /* Not ELIDE_CODE.  */
  983 
  984 #ifdef TEST
  985 
  986 /* Compile with -DTEST to make an executable for use in testing
  987    the above definition of `getopt'.  */
  988 
  989 int
  990 main (argc, argv)
  991      int argc;
  992      char **argv;
  993 {
  994   int c;
  995   int digit_optind = 0;
  996 
  997   while (1)
  998     {
  999       int this_option_optind = optind ? optind : 1;
 1000 
 1001       c = getopt (argc, argv, "abc:d:0123456789");
 1002       if (c == -1)
 1003     break;
 1004 
 1005       switch (c)
 1006     {
 1007     case '0':
 1008     case '1':
 1009     case '2':
 1010     case '3':
 1011     case '4':
 1012     case '5':
 1013     case '6':
 1014     case '7':
 1015     case '8':
 1016     case '9':
 1017       if (digit_optind != 0 && digit_optind != this_option_optind)
 1018         printf ("digits occur in two different argv-elements.\n");
 1019       digit_optind = this_option_optind;
 1020       printf ("option %c\n", c);
 1021       break;
 1022 
 1023     case 'a':
 1024       printf ("option a\n");
 1025       break;
 1026 
 1027     case 'b':
 1028       printf ("option b\n");
 1029       break;
 1030 
 1031     case 'c':
 1032       printf ("option c with value `%s'\n", optarg);
 1033       break;
 1034 
 1035     case '?':
 1036       break;
 1037 
 1038     default:
 1039       printf ("?? getopt returned character code 0%o ??\n", c);
 1040     }
 1041     }
 1042 
 1043   if (optind < argc)
 1044     {
 1045       printf ("non-option ARGV-elements: ");
 1046       while (optind < argc)
 1047     printf ("%s ", argv[optind++]);
 1048       printf ("\n");
 1049     }
 1050 
 1051   exit (0);
 1052 }
 1053 
 1054 #endif /* TEST */