root/maint/gnulib/lib/getopt.c

/* [previous][next][first][last][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-2021 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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,
     /* [previous][next][first][last][top][bottom][index][help] */
 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,
     /* [previous][next][first][last][top][bottom][index][help] */
 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,
     /* [previous][next][first][last][top][bottom][index][help] */
 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,
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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 */

/* [previous][next][first][last][top][bottom][index][help] */