"Fossies" - the Fresh Open Source Software Archive

Member "npadmin-0.14/getopt.c" (19 Apr 2001, 30989 Bytes) of package /linux/misc/old/npadmin-0.14.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.

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