"Fossies" - the Fresh Open Source Software Archive

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