root/lib/getopt.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. exchange
  2. process_long_option
  3. _getopt_initialize
  4. _getopt_internal_r
  5. _getopt_internal
  6. GETOPT_ENTRY

     1 /* Getopt for GNU.
     2    Copyright (C) 1987-2023 Free Software Foundation, Inc.
     3    This file is part of the GNU C Library and is also part of gnulib.
     4    Patches to this file should be submitted to both projects.
     5 
     6    The GNU C Library is free software; you can redistribute it and/or
     7    modify it under the terms of the GNU Lesser General Public
     8    License as published by the Free Software Foundation; either
     9    version 2.1 of the License, or (at your option) any later version.
    10 
    11    The GNU C Library is distributed in the hope that it will be useful,
    12    but WITHOUT ANY WARRANTY; without even the implied warranty of
    13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    14    Lesser General Public License for more details.
    15 
    16    You should have received a copy of the GNU Lesser General Public
    17    License along with the GNU C Library; if not, see
    18    <https://www.gnu.org/licenses/>.  */
    19 
    20 #ifndef _LIBC
    21 # include <config.h>
    22 #endif
    23 
    24 #include "getopt.h"
    25 
    26 #include <stdio.h>
    27 #include <stdlib.h>
    28 #include <string.h>
    29 #include <unistd.h>
    30 
    31 #ifdef _LIBC
    32 /* When used as part of glibc, error printing must be done differently
    33    for standards compliance.  getopt is not a cancellation point, so
    34    it must not call functions that are, and it is specified by an
    35    older standard than stdio locking, so it must not refer to
    36    functions in the "user namespace" related to stdio locking.
    37    Finally, it must use glibc's internal message translation so that
    38    the messages are looked up in the proper text domain.  */
    39 # include <libintl.h>
    40 # define fprintf __fxprintf_nocancel
    41 # define flockfile(fp) _IO_flockfile (fp)
    42 # define funlockfile(fp) _IO_funlockfile (fp)
    43 #else
    44 # include "gettext.h"
    45 # define _(msgid) gettext (msgid)
    46 /* When used standalone, flockfile and funlockfile might not be
    47    available.  */
    48 # if (!defined _POSIX_THREAD_SAFE_FUNCTIONS \
    49       || (defined _WIN32 && ! defined __CYGWIN__))
    50 #  define flockfile(fp) /* nop */
    51 #  define funlockfile(fp) /* nop */
    52 # endif
    53 /* When used standalone, do not attempt to use alloca.  */
    54 # define __libc_use_alloca(size) 0
    55 # undef alloca
    56 # define alloca(size) (abort (), (void *)0)
    57 #endif
    58 
    59 /* This implementation of 'getopt' has three modes for handling
    60    options interspersed with non-option arguments.  It can stop
    61    scanning for options at the first non-option argument encountered,
    62    as POSIX specifies.  It can continue scanning for options after the
    63    first non-option argument, but permute 'argv' as it goes so that,
    64    after 'getopt' is done, all the options precede all the non-option
    65    arguments and 'optind' points to the first non-option argument.
    66    Or, it can report non-option arguments as if they were arguments to
    67    the option character '\x01'.
    68 
    69    The default behavior of 'getopt_long' is to permute the argument list.
    70    When this implementation is used standalone, the default behavior of
    71    'getopt' is to stop at the first non-option argument, but when it is
    72    used as part of GNU libc it also permutes the argument list.  In both
    73    cases, setting the environment variable POSIXLY_CORRECT to any value
    74    disables permutation.
    75 
    76    If the first character of the OPTSTRING argument to 'getopt' or
    77    'getopt_long' is '+', both functions will stop at the first
    78    non-option argument.  If it is '-', both functions will report
    79    non-option arguments as arguments to the option character '\x01'.  */
    80 
    81 #include "getopt_int.h"
    82 
    83 /* For communication from 'getopt' to the caller.
    84    When 'getopt' finds an option that takes an argument,
    85    the argument value is returned here.
    86    Also, when 'ordering' is RETURN_IN_ORDER,
    87    each non-option ARGV-element is returned here.  */
    88 
    89 char *optarg;
    90 
    91 /* Index in ARGV of the next element to be scanned.
    92    This is used for communication to and from the caller
    93    and for communication between successive calls to 'getopt'.
    94 
    95    On entry to 'getopt', zero means this is the first call; initialize.
    96 
    97    When 'getopt' returns -1, this is the index of the first of the
    98    non-option elements that the caller should itself scan.
    99 
   100    Otherwise, 'optind' communicates from one call to the next
   101    how much of ARGV has been scanned so far.  */
   102 
   103 /* 1003.2 says this must be 1 before any call.  */
   104 int optind = 1;
   105 
   106 /* Callers store zero here to inhibit the error message
   107    for unrecognized options.  */
   108 
   109 int opterr = 1;
   110 
   111 /* Set to an option character which was unrecognized.
   112    This must be initialized on some systems to avoid linking in the
   113    system's own getopt implementation.  */
   114 
   115 int optopt = '?';
   116 
   117 /* Keep a global copy of all internal members of getopt_data.  */
   118 
   119 static struct _getopt_data getopt_data;
   120 
   121 /* Exchange two adjacent subsequences of ARGV.
   122    One subsequence is elements [first_nonopt,last_nonopt)
   123    which contains all the non-options that have been skipped so far.
   124    The other is elements [last_nonopt,optind), which contains all
   125    the options processed since those non-options were skipped.
   126 
   127    'first_nonopt' and 'last_nonopt' are relocated so that they describe
   128    the new indices of the non-options in ARGV after they are moved.  */
   129 
   130 static void
   131 exchange (char **argv, struct _getopt_data *d)
   132 {
   133   int bottom = d->__first_nonopt;
   134   int middle = d->__last_nonopt;
   135   int top = d->optind;
   136   char *tem;
   137 
   138   /* Exchange the shorter segment with the far end of the longer segment.
   139      That puts the shorter segment into the right place.
   140      It leaves the longer segment in the right place overall,
   141      but it consists of two parts that need to be swapped next.  */
   142 
   143   while (top > middle && middle > bottom)
   144     {
   145       if (top - middle > middle - bottom)
   146         {
   147           /* Bottom segment is the short one.  */
   148           int len = middle - bottom;
   149           int i;
   150 
   151           /* Swap it with the top part of the top segment.  */
   152           for (i = 0; i < len; i++)
   153             {
   154               tem = argv[bottom + i];
   155               argv[bottom + i] = argv[top - (middle - bottom) + i];
   156               argv[top - (middle - bottom) + i] = tem;
   157             }
   158           /* Exclude the moved bottom segment from further swapping.  */
   159           top -= len;
   160         }
   161       else
   162         {
   163           /* Top segment is the short one.  */
   164           int len = top - middle;
   165           int i;
   166 
   167           /* Swap it with the bottom part of the bottom segment.  */
   168           for (i = 0; i < len; i++)
   169             {
   170               tem = argv[bottom + i];
   171               argv[bottom + i] = argv[middle + i];
   172               argv[middle + i] = tem;
   173             }
   174           /* Exclude the moved top segment from further swapping.  */
   175           bottom += len;
   176         }
   177     }
   178 
   179   /* Update records for the slots the non-options now occupy.  */
   180 
   181   d->__first_nonopt += (d->optind - d->__last_nonopt);
   182   d->__last_nonopt = d->optind;
   183 }
   184 
   185 /* Process the argument starting with d->__nextchar as a long option.
   186    d->optind should *not* have been advanced over this argument.
   187 
   188    If the value returned is -1, it was not actually a long option, the
   189    state is unchanged, and the argument should be processed as a set
   190    of short options (this can only happen when long_only is true).
   191    Otherwise, the option (and its argument, if any) have been consumed
   192    and the return value is the value to return from _getopt_internal_r.  */
   193 static int
   194 process_long_option (int argc, char **argv, const char *optstring,
   195                      const struct option *longopts, int *longind,
   196                      int long_only, struct _getopt_data *d,
   197                      int print_errors, const char *prefix)
   198 {
   199   char *nameend;
   200   size_t namelen;
   201   const struct option *p;
   202   const struct option *pfound = NULL;
   203   int n_options;
   204   int option_index;
   205 
   206   for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++)
   207     /* Do nothing.  */ ;
   208   namelen = nameend - d->__nextchar;
   209 
   210   /* First look for an exact match, counting the options as a side
   211      effect.  */
   212   for (p = longopts, n_options = 0; p->name; p++, n_options++)
   213     if (!strncmp (p->name, d->__nextchar, namelen)
   214         && namelen == strlen (p->name))
   215       {
   216         /* Exact match found.  */
   217         pfound = p;
   218         option_index = n_options;
   219         break;
   220       }
   221 
   222   if (pfound == NULL)
   223     {
   224       /* Didn't find an exact match, so look for abbreviations.  */
   225       unsigned char *ambig_set = NULL;
   226       int ambig_malloced = 0;
   227       int ambig_fallback = 0;
   228       int indfound = -1;
   229 
   230       for (p = longopts, option_index = 0; p->name; p++, option_index++)
   231         if (!strncmp (p->name, d->__nextchar, namelen))
   232           {
   233             if (pfound == NULL)
   234               {
   235                 /* First nonexact match found.  */
   236                 pfound = p;
   237                 indfound = option_index;
   238               }
   239             else if (long_only
   240                      || pfound->has_arg != p->has_arg
   241                      || pfound->flag != p->flag
   242                      || pfound->val != p->val)
   243               {
   244                 /* Second or later nonexact match found.  */
   245                 if (!ambig_fallback)
   246                   {
   247                     if (!print_errors)
   248                       /* Don't waste effort tracking the ambig set if
   249                          we're not going to print it anyway.  */
   250                       ambig_fallback = 1;
   251                     else if (!ambig_set)
   252                       {
   253                         if (__libc_use_alloca (n_options))
   254                           ambig_set = alloca (n_options);
   255                         else if ((ambig_set = malloc (n_options)) == NULL)
   256                           /* Fall back to simpler error message.  */
   257                           ambig_fallback = 1;
   258                         else
   259                           ambig_malloced = 1;
   260 
   261                         if (ambig_set)
   262                           {
   263                             memset (ambig_set, 0, n_options);
   264                             ambig_set[indfound] = 1;
   265                           }
   266                       }
   267                     if (ambig_set)
   268                       ambig_set[option_index] = 1;
   269                   }
   270               }
   271           }
   272 
   273       if (ambig_set || ambig_fallback)
   274         {
   275           if (print_errors)
   276             {
   277               if (ambig_fallback)
   278                 fprintf (stderr, _("%s: option '%s%s' is ambiguous\n"),
   279                          argv[0], prefix, d->__nextchar);
   280               else
   281                 {
   282                   flockfile (stderr);
   283                   fprintf (stderr,
   284                            _("%s: option '%s%s' is ambiguous; possibilities:"),
   285                            argv[0], prefix, d->__nextchar);
   286 
   287                   for (option_index = 0; option_index < n_options; option_index++)
   288                     if (ambig_set[option_index])
   289                       fprintf (stderr, " '%s%s'",
   290                                prefix, longopts[option_index].name);
   291 
   292                   /* This must use 'fprintf' even though it's only
   293                      printing a single character, so that it goes through
   294                      __fxprintf_nocancel when compiled as part of glibc.  */
   295                   fprintf (stderr, "\n");
   296                   funlockfile (stderr);
   297                 }
   298             }
   299           if (ambig_malloced)
   300             free (ambig_set);
   301           d->__nextchar += strlen (d->__nextchar);
   302           d->optind++;
   303           d->optopt = 0;
   304           return '?';
   305         }
   306 
   307       option_index = indfound;
   308     }
   309 
   310   if (pfound == NULL)
   311     {
   312       /* Can't find it as a long option.  If this is not getopt_long_only,
   313          or the option starts with '--' or is not a valid short option,
   314          then it's an error.  */
   315       if (!long_only || argv[d->optind][1] == '-'
   316           || strchr (optstring, *d->__nextchar) == NULL)
   317         {
   318           if (print_errors)
   319             fprintf (stderr, _("%s: unrecognized option '%s%s'\n"),
   320                      argv[0], prefix, d->__nextchar);
   321 
   322           d->__nextchar = NULL;
   323           d->optind++;
   324           d->optopt = 0;
   325           return '?';
   326         }
   327 
   328       /* Otherwise interpret it as a short option.  */
   329       return -1;
   330     }
   331 
   332   /* We have found a matching long option.  Consume it.  */
   333   d->optind++;
   334   d->__nextchar = NULL;
   335   if (*nameend)
   336     {
   337       /* Don't test has_arg with >, because some C compilers don't
   338          allow it to be used on enums.  */
   339       if (pfound->has_arg)
   340         d->optarg = nameend + 1;
   341       else
   342         {
   343           if (print_errors)
   344             fprintf (stderr,
   345                      _("%s: option '%s%s' doesn't allow an argument\n"),
   346                      argv[0], prefix, pfound->name);
   347 
   348           d->optopt = pfound->val;
   349           return '?';
   350         }
   351     }
   352   else if (pfound->has_arg == 1)
   353     {
   354       if (d->optind < argc)
   355         d->optarg = argv[d->optind++];
   356       else
   357         {
   358           if (print_errors)
   359             fprintf (stderr,
   360                      _("%s: option '%s%s' requires an argument\n"),
   361                      argv[0], prefix, pfound->name);
   362 
   363           d->optopt = pfound->val;
   364           return optstring[0] == ':' ? ':' : '?';
   365         }
   366     }
   367 
   368   if (longind != NULL)
   369     *longind = option_index;
   370   if (pfound->flag)
   371     {
   372       *(pfound->flag) = pfound->val;
   373       return 0;
   374     }
   375   return pfound->val;
   376 }
   377 
   378 /* Initialize internal data upon the first call to getopt.  */
   379 
   380 static const char *
   381 _getopt_initialize (_GL_UNUSED int argc,
   382                     _GL_UNUSED char **argv, const char *optstring,
   383                     struct _getopt_data *d, int posixly_correct)
   384 {
   385   /* Start processing options with ARGV-element 1 (since ARGV-element 0
   386      is the program name); the sequence of previously skipped
   387      non-option ARGV-elements is empty.  */
   388   if (d->optind == 0)
   389     d->optind = 1;
   390 
   391   d->__first_nonopt = d->__last_nonopt = d->optind;
   392   d->__nextchar = NULL;
   393 
   394   /* Determine how to handle the ordering of options and nonoptions.  */
   395   if (optstring[0] == '-')
   396     {
   397       d->__ordering = RETURN_IN_ORDER;
   398       ++optstring;
   399     }
   400   else if (optstring[0] == '+')
   401     {
   402       d->__ordering = REQUIRE_ORDER;
   403       ++optstring;
   404     }
   405   else if (posixly_correct || !!getenv ("POSIXLY_CORRECT"))
   406     d->__ordering = REQUIRE_ORDER;
   407   else
   408     d->__ordering = PERMUTE;
   409 
   410   d->__initialized = 1;
   411   return optstring;
   412 }
   413 
   414 /* Scan elements of ARGV (whose length is ARGC) for option characters
   415    given in OPTSTRING.
   416 
   417    If an element of ARGV starts with '-', and is not exactly "-" or "--",
   418    then it is an option element.  The characters of this element
   419    (aside from the initial '-') are option characters.  If 'getopt'
   420    is called repeatedly, it returns successively each of the option characters
   421    from each of the option elements.
   422 
   423    If 'getopt' finds another option character, it returns that character,
   424    updating 'optind' and 'nextchar' so that the next call to 'getopt' can
   425    resume the scan with the following option character or ARGV-element.
   426 
   427    If there are no more option characters, 'getopt' returns -1.
   428    Then 'optind' is the index in ARGV of the first ARGV-element
   429    that is not an option.  (The ARGV-elements have been permuted
   430    so that those that are not options now come last.)
   431 
   432    OPTSTRING is a string containing the legitimate option characters.
   433    If an option character is seen that is not listed in OPTSTRING,
   434    return '?' after printing an error message.  If you set 'opterr' to
   435    zero, the error message is suppressed but we still return '?'.
   436 
   437    If a char in OPTSTRING is followed by a colon, that means it wants an arg,
   438    so the following text in the same ARGV-element, or the text of the following
   439    ARGV-element, is returned in 'optarg'.  Two colons mean an option that
   440    wants an optional arg; if there is text in the current ARGV-element,
   441    it is returned in 'optarg', otherwise 'optarg' is set to zero.
   442 
   443    If OPTSTRING starts with '-' or '+', it requests different methods of
   444    handling the non-option ARGV-elements.
   445    See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
   446 
   447    Long-named options begin with '--' instead of '-'.
   448    Their names may be abbreviated as long as the abbreviation is unique
   449    or is an exact match for some defined option.  If they have an
   450    argument, it follows the option name in the same ARGV-element, separated
   451    from the option name by a '=', or else the in next ARGV-element.
   452    When 'getopt' finds a long-named option, it returns 0 if that option's
   453    'flag' field is nonzero, the value of the option's 'val' field
   454    if the 'flag' field is zero.
   455 
   456    The elements of ARGV aren't really const, because we permute them.
   457    But we pretend they're const in the prototype to be compatible
   458    with other systems.
   459 
   460    LONGOPTS is a vector of 'struct option' terminated by an
   461    element containing a name which is zero.
   462 
   463    LONGIND returns the index in LONGOPT of the long-named option found.
   464    It is only valid when a long-named option has been found by the most
   465    recent call.
   466 
   467    If LONG_ONLY is nonzero, '-' as well as '--' can introduce
   468    long-named options.  */
   469 
   470 int
   471 _getopt_internal_r (int argc, char **argv, const char *optstring,
   472                     const struct option *longopts, int *longind,
   473                     int long_only, struct _getopt_data *d, int posixly_correct)
   474 {
   475   int print_errors = d->opterr;
   476 
   477   if (argc < 1)
   478     return -1;
   479 
   480   d->optarg = NULL;
   481 
   482   if (d->optind == 0 || !d->__initialized)
   483     optstring = _getopt_initialize (argc, argv, optstring, d, posixly_correct);
   484   else if (optstring[0] == '-' || optstring[0] == '+')
   485     optstring++;
   486 
   487   if (optstring[0] == ':')
   488     print_errors = 0;
   489 
   490   /* Test whether ARGV[optind] points to a non-option argument.  */
   491 #define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0')
   492 
   493   if (d->__nextchar == NULL || *d->__nextchar == '\0')
   494     {
   495       /* Advance to the next ARGV-element.  */
   496 
   497       /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
   498          moved back by the user (who may also have changed the arguments).  */
   499       if (d->__last_nonopt > d->optind)
   500         d->__last_nonopt = d->optind;
   501       if (d->__first_nonopt > d->optind)
   502         d->__first_nonopt = d->optind;
   503 
   504       if (d->__ordering == PERMUTE)
   505         {
   506           /* If we have just processed some options following some non-options,
   507              exchange them so that the options come first.  */
   508 
   509           if (d->__first_nonopt != d->__last_nonopt
   510               && d->__last_nonopt != d->optind)
   511             exchange (argv, d);
   512           else if (d->__last_nonopt != d->optind)
   513             d->__first_nonopt = d->optind;
   514 
   515           /* Skip any additional non-options
   516              and extend the range of non-options previously skipped.  */
   517 
   518           while (d->optind < argc && NONOPTION_P)
   519             d->optind++;
   520           d->__last_nonopt = d->optind;
   521         }
   522 
   523       /* The special ARGV-element '--' means premature end of options.
   524          Skip it like a null option,
   525          then exchange with previous non-options as if it were an option,
   526          then skip everything else like a non-option.  */
   527 
   528       if (d->optind != argc && !strcmp (argv[d->optind], "--"))
   529         {
   530           d->optind++;
   531 
   532           if (d->__first_nonopt != d->__last_nonopt
   533               && d->__last_nonopt != d->optind)
   534             exchange (argv, d);
   535           else if (d->__first_nonopt == d->__last_nonopt)
   536             d->__first_nonopt = d->optind;
   537           d->__last_nonopt = argc;
   538 
   539           d->optind = argc;
   540         }
   541 
   542       /* If we have done all the ARGV-elements, stop the scan
   543          and back over any non-options that we skipped and permuted.  */
   544 
   545       if (d->optind == argc)
   546         {
   547           /* Set the next-arg-index to point at the non-options
   548              that we previously skipped, so the caller will digest them.  */
   549           if (d->__first_nonopt != d->__last_nonopt)
   550             d->optind = d->__first_nonopt;
   551           return -1;
   552         }
   553 
   554       /* If we have come to a non-option and did not permute it,
   555          either stop the scan or describe it to the caller and pass it by.  */
   556 
   557       if (NONOPTION_P)
   558         {
   559           if (d->__ordering == REQUIRE_ORDER)
   560             return -1;
   561           d->optarg = argv[d->optind++];
   562           return 1;
   563         }
   564 
   565       /* We have found another option-ARGV-element.
   566          Check whether it might be a long option.  */
   567       if (longopts)
   568         {
   569           if (argv[d->optind][1] == '-')
   570             {
   571               /* "--foo" is always a long option.  The special option
   572                  "--" was handled above.  */
   573               d->__nextchar = argv[d->optind] + 2;
   574               return process_long_option (argc, argv, optstring, longopts,
   575                                           longind, long_only, d,
   576                                           print_errors, "--");
   577             }
   578 
   579           /* If long_only and the ARGV-element has the form "-f",
   580              where f is a valid short option, don't consider it an
   581              abbreviated form of a long option that starts with f.
   582              Otherwise there would be no way to give the -f short
   583              option.
   584 
   585              On the other hand, if there's a long option "fubar" and
   586              the ARGV-element is "-fu", do consider that an
   587              abbreviation of the long option, just like "--fu", and
   588              not "-f" with arg "u".
   589 
   590              This distinction seems to be the most useful approach.  */
   591           if (long_only && (argv[d->optind][2]
   592                             || !strchr (optstring, argv[d->optind][1])))
   593             {
   594               int code;
   595               d->__nextchar = argv[d->optind] + 1;
   596               code = process_long_option (argc, argv, optstring, longopts,
   597                                           longind, long_only, d,
   598                                           print_errors, "-");
   599               if (code != -1)
   600                 return code;
   601             }
   602         }
   603 
   604       /* It is not a long option.  Skip the initial punctuation.  */
   605       d->__nextchar = argv[d->optind] + 1;
   606     }
   607 
   608   /* Look at and handle the next short option-character.  */
   609 
   610   {
   611     char c = *d->__nextchar++;
   612     const char *temp = strchr (optstring, c);
   613 
   614     /* Increment 'optind' when we start to process its last character.  */
   615     if (*d->__nextchar == '\0')
   616       ++d->optind;
   617 
   618     if (temp == NULL || c == ':' || c == ';')
   619       {
   620         if (print_errors)
   621           fprintf (stderr, _("%s: invalid option -- '%c'\n"), argv[0], c);
   622         d->optopt = c;
   623         return '?';
   624       }
   625 
   626     /* Convenience. Treat POSIX -W foo same as long option --foo */
   627     if (temp[0] == 'W' && temp[1] == ';' && longopts != NULL)
   628       {
   629         /* This is an option that requires an argument.  */
   630         if (*d->__nextchar != '\0')
   631           d->optarg = d->__nextchar;
   632         else if (d->optind == argc)
   633           {
   634             if (print_errors)
   635               fprintf (stderr,
   636                        _("%s: option requires an argument -- '%c'\n"),
   637                        argv[0], c);
   638 
   639             d->optopt = c;
   640             if (optstring[0] == ':')
   641               c = ':';
   642             else
   643               c = '?';
   644             return c;
   645           }
   646         else
   647           d->optarg = argv[d->optind];
   648 
   649         d->__nextchar = d->optarg;
   650         d->optarg = NULL;
   651         return process_long_option (argc, argv, optstring, longopts, longind,
   652                                     0 /* long_only */, d, print_errors, "-W ");
   653       }
   654     if (temp[1] == ':')
   655       {
   656         if (temp[2] == ':')
   657           {
   658             /* This is an option that accepts an argument optionally.  */
   659             if (*d->__nextchar != '\0')
   660               {
   661                 d->optarg = d->__nextchar;
   662                 d->optind++;
   663               }
   664             else
   665               d->optarg = NULL;
   666             d->__nextchar = NULL;
   667           }
   668         else
   669           {
   670             /* This is an option that requires an argument.  */
   671             if (*d->__nextchar != '\0')
   672               {
   673                 d->optarg = d->__nextchar;
   674                 /* If we end this ARGV-element by taking the rest as an arg,
   675                    we must advance to the next element now.  */
   676                 d->optind++;
   677               }
   678             else if (d->optind == argc)
   679               {
   680                 if (print_errors)
   681                   fprintf (stderr,
   682                            _("%s: option requires an argument -- '%c'\n"),
   683                            argv[0], c);
   684 
   685                 d->optopt = c;
   686                 if (optstring[0] == ':')
   687                   c = ':';
   688                 else
   689                   c = '?';
   690               }
   691             else
   692               /* We already incremented 'optind' once;
   693                  increment it again when taking next ARGV-elt as argument.  */
   694               d->optarg = argv[d->optind++];
   695             d->__nextchar = NULL;
   696           }
   697       }
   698     return c;
   699   }
   700 }
   701 
   702 int
   703 _getopt_internal (int argc, char **argv, const char *optstring,
   704                   const struct option *longopts, int *longind, int long_only,
   705                   int posixly_correct)
   706 {
   707   int result;
   708 
   709   getopt_data.optind = optind;
   710   getopt_data.opterr = opterr;
   711 
   712   result = _getopt_internal_r (argc, argv, optstring, longopts,
   713                                longind, long_only, &getopt_data,
   714                                posixly_correct);
   715 
   716   optind = getopt_data.optind;
   717   optarg = getopt_data.optarg;
   718   optopt = getopt_data.optopt;
   719 
   720   return result;
   721 }
   722 
   723 /* glibc gets a LSB-compliant getopt and a POSIX-complaint __posix_getopt.
   724    Standalone applications just get a POSIX-compliant getopt.
   725    POSIX and LSB both require these functions to take 'char *const *argv'
   726    even though this is incorrect (because of the permutation).  */
   727 #define GETOPT_ENTRY(NAME, POSIXLY_CORRECT)                     \
   728   int                                                           \
   729   NAME (int argc, char *const *argv, const char *optstring)     \
   730   {                                                             \
   731     return _getopt_internal (argc, (char **)argv, optstring,    \
   732                              0, 0, 0, POSIXLY_CORRECT);         \
   733   }
   734 
   735 #ifdef _LIBC
   736 GETOPT_ENTRY(getopt, 0)
   737 GETOPT_ENTRY(__posix_getopt, 1)
   738 #else
   739 GETOPT_ENTRY(getopt, 1)
   740 #endif
   741 
   742 
   743 #ifdef TEST
   744 
   745 /* Compile with -DTEST to make an executable for use in testing
   746    the above definition of 'getopt'.  */
   747 
   748 int
   749 main (int argc, char **argv)
   750 {
   751   int c;
   752   int digit_optind = 0;
   753 
   754   while (1)
   755     {
   756       int this_option_optind = optind ? optind : 1;
   757 
   758       c = getopt (argc, argv, "abc:d:0123456789");
   759       if (c == -1)
   760         break;
   761 
   762       switch (c)
   763         {
   764         case '0':
   765         case '1':
   766         case '2':
   767         case '3':
   768         case '4':
   769         case '5':
   770         case '6':
   771         case '7':
   772         case '8':
   773         case '9':
   774           if (digit_optind != 0 && digit_optind != this_option_optind)
   775             printf ("digits occur in two different argv-elements.\n");
   776           digit_optind = this_option_optind;
   777           printf ("option %c\n", c);
   778           break;
   779 
   780         case 'a':
   781           printf ("option a\n");
   782           break;
   783 
   784         case 'b':
   785           printf ("option b\n");
   786           break;
   787 
   788         case 'c':
   789           printf ("option c with value '%s'\n", optarg);
   790           break;
   791 
   792         case '?':
   793           break;
   794 
   795         default:
   796           printf ("?? getopt returned character code 0%o ??\n", c);
   797         }
   798     }
   799 
   800   if (optind < argc)
   801     {
   802       printf ("non-option ARGV-elements: ");
   803       while (optind < argc)
   804         printf ("%s ", argv[optind++]);
   805       printf ("\n");
   806     }
   807 
   808   exit (0);
   809 }
   810 
   811 #endif /* TEST */

/* [<][>][^][v][top][bottom][index][help] */