Ignore:
Timestamp:
Mar 30, 2018, 11:03:28 PM (7 years ago)
Author:
bird
Message:

kmk: Forked getopt and created a reentrant variant getopt_r.

File:
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/kmkbuiltin/getopt_r.c

    r3212 r3213  
    1 /* Getopt for GNU.
     1/* Reentrant version of getopt.
     2
     3Based on ../getopt*.*:
     4
     5   Getopt for GNU.
    26NOTE: getopt is now part of the C library, so if you don't know what
    37"Keep this file name-space clean" means, talk to drepper@gnu.org
     
    1923
    2024You should have received a copy of the GNU General Public License along with
    21 this program.  If not, see <http://www.gnu.org/licenses/>.  */
     25this program.  If not, see <http://www.gnu.org/licenses/>.
     26
     27Modifications:
     28  Copyright (c) 2018 knut st. osmundsen <bird-kBuild-spamx@anduin.net>
     29*/
    2230
    2331/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
     
    2735#endif
    2836
     37#define FAKES_NO_GETOPT_H /* bird */
    2938#ifdef HAVE_CONFIG_H
    3039# include <config.h>
     
    4150#include <stdio.h>
    4251
     52#if 0
    4353/* Comment out all this code if we are using the GNU C Library, and are not
    4454   actually compiling the library itself.  This code is part of the GNU C
     
    5666# endif
    5767#endif
    58 
    59 #ifndef ELIDE_CODE
     68#endif
     69
     70#if 1 //ndef ELIDE_CODE
    6071
    6172
     
    96107   they can distinguish the relative order of options and other arguments.  */
    97108
    98 #include "getopt.h"
    99 
     109#include "getopt_r.h"
     110#include "err.h"
     111#include <assert.h>
     112
     113#if 0 /* Moved to state_getopt_r in getopt_r.h. */
    100114/* For communication from `getopt' to the caller.
    101115   When `getopt' finds an option that takes an argument,
     
    146160
    147161int optopt = '?';
     162#endif /* Moved to state_getopt_r in getopt_r.h. */
    148163
    149164/* Describe how to deal with options that follow non-option ARGV-elements.
     
    176191   `--' can cause `getopt' to return -1 with `optind' != ARGC.  */
    177192
    178 static enum
     193/*static*/ enum
    179194{
    180195  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
    181 } ordering;
    182 
     196} /*ordering*/;
     197
     198#if 0 /* Moved to state_getopt_r in getopt_r.h. */
    183199/* Value of POSIXLY_CORRECT environment variable.  */
    184200static char *posixly_correct;
    185 
    186 
    187 #ifdef  __GNU_LIBRARY__
     201#endif
     202
     203
     204
     205#if 1 //def     __GNU_LIBRARY__
    188206/* We want to avoid inclusion of string.h with non-GNU libraries
    189207   because there are many ways it can cause trouble.
     
    191209   in GCC.  */
    192210# include <string.h>
    193 # define my_index       strchr
     211//# define my_index     strchr
    194212#else
    195213
     
    200218# endif
    201219
    202 #ifndef KMK
     220#if 0 //def
    203221/* Avoid depending on library functions or files
    204222   whose names are inconsistent.  */
     
    206224extern char *getenv ();
    207225#endif
    208 #endif /* !KMK */
     226#endif
    209227
    210228static char *
     
    237255/* Handle permutation of arguments.  */
    238256
     257#if 0 /* Moved to state_getopt_r in getopt_r.h. */
    239258/* Describe the part of ARGV that contains non-options that have
    240259   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
     
    243262static int first_nonopt;
    244263static int last_nonopt;
    245 
    246 #ifdef _LIBC
     264#endif
     265
     266#if 0 //def _LIBC
    247267/* Bash 2.0 gives us an environment variable containing flags
    248268   indicating ARGV elements that should not be considered arguments.  */
     
    280300    }
    281301#else   /* !_LIBC */
    282 # define SWAP_FLAGS(ch1, ch2)
     302# define SWAP_FLAGS(ch1, ch2) do { } while (0)
    283303#endif  /* _LIBC */
    284304
     
    292312   the new indices of the non-options in ARGV after they are moved.  */
    293313
    294 #if defined __STDC__ && __STDC__
    295 static void exchange (char **);
    296 #endif
    297 
    298314static void
    299 exchange (char **argv)
     315exchange (struct getopt_state_r *gos, char **argv)
    300316{
    301   int bottom = first_nonopt;
    302   int middle = last_nonopt;
    303   int top = optind;
     317  int bottom = gos->first_nonopt;
     318  int middle = gos->last_nonopt;
     319  int top = gos->optind;
    304320  char *tem;
    305321
     
    309325     but it consists of two parts that need to be swapped next.  */
    310326
    311 #ifdef _LIBC
     327#if 0 //def _LIBC
    312328  /* First make sure the handling of the `__getopt_nonoption_flags'
    313329     string can work normally.  Our top argument must be in the range
     
    371387  /* Update records for the slots the non-options now occupy.  */
    372388
    373   first_nonopt += (optind - last_nonopt);
    374   last_nonopt = optind;
     389  gos->first_nonopt += (gos->optind - gos->last_nonopt);
     390  gos->last_nonopt = gos->optind;
    375391}
    376392
    377 /* Initialize the internal data when the first call is made.  */
    378 
    379 #if defined __STDC__ && __STDC__
    380 static const char *_getopt_initialize (int, char *const *, const char *);
    381 #endif
    382 static const char *
    383 _getopt_initialize (int argc, char *const *argv, const char *optstring)
     393/* Initialize the internal data   */
     394
     395void
     396getopt_initialize_r (struct getopt_state_r *gos, int argc,
     397                     char * const *argv, const char *shortopts,
     398                     const struct option *long_options,
     399                     char **envp, struct KMKBUILTINCTX *pCtx)
    384400{
     401  assert (shortopts != NULL);
     402
     403  /* General initialization. */
     404  gos->optarg = NULL;
     405  gos->optind = 1;
     406  gos->__getopt_initialized = (void *)(uintptr_t)&exchange;
     407  gos->opterr = 1;
     408  gos->optopt = '?';
     409  gos->argc = argc;
     410  gos->argv = argv;
     411  gos->optstring = shortopts;
     412  gos->len_optstring = strlen (shortopts);
     413  gos->long_options = long_options;
     414  gos->pCtx = pCtx;
     415
    385416  /* Start processing options with ARGV-element 1 (since ARGV-element 0
    386417     is the program name); the sequence of previously skipped
    387418     non-option ARGV-elements is empty.  */
    388419
    389   first_nonopt = last_nonopt = optind;
    390 
    391   nextchar = NULL;
    392 
    393   posixly_correct = getenv ("POSIXLY_CORRECT");
     420  gos->first_nonopt = gos->last_nonopt = gos->optind;
     421
     422  gos->nextchar = NULL;
     423
     424  if (!envp)
     425    gos->posixly_correct = getenv("POSIXLY_CORRECT");
     426  else
     427    {
     428      const char *psz;
     429      size_t i = 0;
     430      gos->posixly_correct = NULL;
     431      while ((psz = envp[i]) != NULL)
     432        {
     433          if (   psz[0] == 'P'
     434              && strncmp (psz, "POSIXLY_CORRECT=", sizeof("POSIXLY_CORRECT=") - 1) == 0)
     435            {
     436              gos->posixly_correct = psz + sizeof("POSIXLY_CORRECT=") - 1;
     437              break;
     438            }
     439          i++;
     440        }
     441    }
    394442
    395443  /* Determine how to handle the ordering of options and nonoptions.  */
    396444
    397   if (optstring[0] == '-')
    398     {
    399       ordering = RETURN_IN_ORDER;
    400       ++optstring;
    401     }
    402   else if (optstring[0] == '+')
    403     {
    404       ordering = REQUIRE_ORDER;
    405       ++optstring;
    406     }
    407   else if (posixly_correct != NULL)
    408     ordering = REQUIRE_ORDER;
     445  if (shortopts[0] == '-')
     446    {
     447      gos->ordering = RETURN_IN_ORDER;
     448      gos->optstring++;
     449      gos->len_optstring--;
     450    }
     451  else if (shortopts[0] == '+')
     452    {
     453      gos->ordering = REQUIRE_ORDER;
     454      gos->optstring++;
     455      gos->len_optstring--;
     456    }
     457  else if (gos->posixly_correct != NULL)
     458    gos->ordering = REQUIRE_ORDER;
    409459  else
    410     ordering = PERMUTE;
    411 
    412 #ifdef _LIBC
     460    gos->ordering = PERMUTE;
     461
     462#if 0 //def _LIBC
    413463  if (posixly_correct == NULL
    414464      && argc == original_argc && argv == original_argv)
     
    440490#endif
    441491
    442   return optstring;
     492  //return optstring;
    443493}
    444494
     
    501551
    502552int
    503 _getopt_internal (int argc, char *const *argv, const char *optstring,
    504                   const struct option *longopts, int *longind, int long_only)
     553_getopt_internal_r (struct getopt_state_r *gos, const struct option *longopts,
     554                    int *longind, int long_only)
    505555{
    506   optarg = NULL;
    507 
    508   if (optind == 0 || !__getopt_initialized)
    509     {
    510       if (optind == 0)
    511         optind = 1;     /* Don't scan ARGV[0], the program name.  */
    512       optstring = _getopt_initialize (argc, argv, optstring);
    513       __getopt_initialized = 1;
    514     }
     556  assert (gos->__getopt_initialized == (void *)(uintptr_t)&exchange);
     557  gos->optarg = NULL;
     558
     559#if 0 /* requires explicit call now */
     560  if (gos->optind == 0 || !gos->__getopt_initialized)
     561    {
     562      if (gos->optind == 0)
     563        gos->optind = 1;        /* Don't scan ARGV[0], the program name.  */
     564      optstring = _getopt_initialize_r (gos, gos->argc, gos->argv, optstring);
     565      gos->__getopt_initialized = 1;
     566    }
     567#else
     568  assert (gos->__getopt_initialized == (void *)(uintptr_t)&exchange);
     569#endif
    515570
    516571  /* Test whether ARGV[optind] points to a non-option argument.
     
    518573     from the shell indicating it is not an option.  The later information
    519574     is only used when the used in the GNU libc.  */
    520 #ifdef _LIBC
    521 # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'       \
    522                       || (optind < nonoption_flags_len                        \
    523                           && __getopt_nonoption_flags[optind] == '1'))
     575#if 0 //def _LIBC
     576# define NONOPTION_P (gos->argv[gos->optind][0] != '-' || gos->argv[gos->optind][1] == '\0'           \
     577                      || (gos->optind < gos->nonoption_flags_len                              \
     578                          && gos->__getopt_nonoption_flags[gos->optind] == '1'))
    524579#else
    525 # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
    526 #endif
    527 
    528   if (nextchar == NULL || *nextchar == '\0')
     580# define NONOPTION_P (gos->argv[gos->optind][0] != '-' || gos->argv[gos->optind][1] == '\0')
     581#endif
     582
     583  if (gos->nextchar == NULL || *gos->nextchar == '\0')
    529584    {
    530585      /* Advance to the next ARGV-element.  */
     
    532587      /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
    533588         moved back by the user (who may also have changed the arguments).  */
    534       if (last_nonopt > optind)
    535         last_nonopt = optind;
    536       if (first_nonopt > optind)
    537         first_nonopt = optind;
    538 
    539       if (ordering == PERMUTE)
     589      if (gos->last_nonopt > gos->optind)
     590        gos->last_nonopt = gos->optind;
     591      if (gos->first_nonopt > gos->optind)
     592        gos->first_nonopt = gos->optind;
     593
     594      if (gos->ordering == PERMUTE)
    540595        {
    541596          /* If we have just processed some options following some non-options,
    542597             exchange them so that the options come first.  */
    543598
    544           if (first_nonopt != last_nonopt && last_nonopt != optind)
    545             exchange ((char **) argv);
    546           else if (last_nonopt != optind)
    547             first_nonopt = optind;
     599          if (gos->first_nonopt != gos->last_nonopt && gos->last_nonopt != gos->optind)
     600            exchange (gos, (char **) gos->argv);
     601          else if (gos->last_nonopt != gos->optind)
     602            gos->first_nonopt = gos->optind;
    548603
    549604          /* Skip any additional non-options
    550605             and extend the range of non-options previously skipped.  */
    551606
    552           while (optind < argc && NONOPTION_P)
    553             optind++;
    554           last_nonopt = optind;
     607          while (gos->optind < gos->argc && NONOPTION_P)
     608            gos->optind++;
     609          gos->last_nonopt = gos->optind;
    555610        }
    556611
     
    560615         then skip everything else like a non-option.  */
    561616
    562       if (optind != argc && !strcmp (argv[optind], "--"))
    563         {
    564           optind++;
    565 
    566           if (first_nonopt != last_nonopt && last_nonopt != optind)
    567             exchange ((char **) argv);
    568           else if (first_nonopt == last_nonopt)
    569             first_nonopt = optind;
    570           last_nonopt = argc;
    571 
    572           optind = argc;
     617      if (gos->optind != gos->argc && !strcmp (gos->argv[gos->optind], "--"))
     618        {
     619          gos->optind++;
     620
     621          if (gos->first_nonopt != gos->last_nonopt && gos->last_nonopt != gos->optind)
     622            exchange (gos, (char **) gos->argv);
     623          else if (gos->first_nonopt == gos->last_nonopt)
     624            gos->first_nonopt = gos->optind;
     625          gos->last_nonopt = gos->argc;
     626
     627          gos->optind = gos->argc;
    573628        }
    574629
     
    576631         and back over any non-options that we skipped and permuted.  */
    577632
    578       if (optind == argc)
     633      if (gos->optind == gos->argc)
    579634        {
    580635          /* Set the next-arg-index to point at the non-options
    581636             that we previously skipped, so the caller will digest them.  */
    582           if (first_nonopt != last_nonopt)
    583             optind = first_nonopt;
     637          if (gos->first_nonopt != gos->last_nonopt)
     638            gos->optind = gos->first_nonopt;
    584639          return -1;
    585640        }
     
    590645      if (NONOPTION_P)
    591646        {
    592           if (ordering == REQUIRE_ORDER)
     647          if (gos->ordering == REQUIRE_ORDER)
    593648            return -1;
    594           optarg = argv[optind++];
     649          gos->optarg = gos->argv[gos->optind++];
    595650          return 1;
    596651        }
     
    599654         Skip the initial punctuation.  */
    600655
    601       nextchar = (argv[optind] + 1
    602                   + (longopts != NULL && argv[optind][1] == '-'));
     656      gos->nextchar = (gos->argv[gos->optind] + 1
     657                    + (longopts != NULL && gos->argv[gos->optind][1] == '-'));
    603658    }
    604659
     
    619674
    620675  if (longopts != NULL
    621       && (argv[optind][1] == '-'
    622           || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
     676      && (gos->argv[gos->optind][1] == '-'
     677          || (long_only
     678              && (  gos->argv[gos->optind][2]
     679                  || !memchr (gos->optstring, gos->argv[gos->optind][1], gos->len_optstring) )
     680              )
     681          )
     682      )
    623683    {
    624684      char *nameend;
     
    630690      int option_index;
    631691
    632       for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
     692      for (nameend = gos->nextchar; *nameend && *nameend != '='; nameend++)
    633693        /* Do nothing.  */ ;
    634694
     
    636696         or abbreviated matches.  */
    637697      for (p = longopts, option_index = 0; p->name; p++, option_index++)
    638         if (!strncmp (p->name, nextchar, nameend - nextchar))
     698        if (!strncmp (p->name, gos->nextchar, nameend - gos->nextchar))
    639699          {
    640             if ((unsigned int) (nameend - nextchar)
     700            if ((unsigned int) (nameend - gos->nextchar)
    641701                == (unsigned int) strlen (p->name))
    642702              {
     
    660720      if (ambig && !exact)
    661721        {
    662           if (opterr)
    663             fprintf (stderr, _("%s: option '%s' is ambiguous\n"),
    664                      argv[0], argv[optind]);
    665           nextchar += strlen (nextchar);
    666           optind++;
    667           optopt = 0;
     722          if (gos->opterr)
     723            errx (gos->pCtx, 2, _("%s: option '%s' is ambiguous"),
     724                  gos->argv[0], gos->argv[gos->optind]);
     725          gos->nextchar += strlen (gos->nextchar);
     726          gos->optind++;
     727          gos->optopt = 0;
    668728          return '?';
    669729        }
     
    672732        {
    673733          option_index = indfound;
    674           optind++;
     734          gos->optind++;
    675735          if (*nameend)
    676736            {
     
    678738                 allow it to be used on enums.  */
    679739              if (pfound->has_arg)
    680                 optarg = nameend + 1;
     740                gos->optarg = nameend + 1;
    681741              else
    682742                {
    683                   if (opterr)
     743                  if (gos->opterr)
    684744                  { /* bird: disambiguate */
    685                    if (argv[optind - 1][1] == '-')
     745                   if (gos->argv[gos->optind - 1][1] == '-')
    686746                    /* --option */
    687                     fprintf (stderr,
    688                      _("%s: option '--%s' doesn't allow an argument\n"),
    689                      argv[0], pfound->name);
     747                    errx (gos->pCtx, 2,
     748                          _("%s: option '--%s' doesn't allow an argument\n"),
     749                          gos->argv[0], pfound->name);
    690750                   else
    691751                    /* +option or -option */
    692                     fprintf (stderr,
    693                      _("%s: option '%c%s' doesn't allow an argument\n"),
    694                      argv[0], argv[optind - 1][0], pfound->name);
     752                    errx (gos->pCtx, 2,
     753                          _("%s: option '%c%s' doesn't allow an argument\n"),
     754                          gos->argv[0], gos->argv[gos->optind - 1][0], pfound->name);
    695755                  }
    696756
    697                   nextchar += strlen (nextchar);
    698 
    699                   optopt = pfound->val;
     757                  gos->nextchar += strlen (gos->nextchar);
     758
     759                  gos->optopt = pfound->val;
    700760                  return '?';
    701761                }
     
    703763          else if (pfound->has_arg == 1)
    704764            {
    705               if (optind < argc)
    706                 optarg = argv[optind++];
     765              if (gos->optind < gos->argc)
     766                gos->optarg = gos->argv[gos->optind++];
    707767              else
    708768                {
    709                   if (opterr)
    710                     fprintf (stderr,
    711                            _("%s: option '%s' requires an argument\n"),
    712                            argv[0], argv[optind - 1]);
    713                   nextchar += strlen (nextchar);
    714                   optopt = pfound->val;
    715                   return optstring[0] == ':' ? ':' : '?';
     769                  if (gos->opterr)
     770                    errx (gos->pCtx, 2,
     771                          _("%s: option '%s' requires an argument\n"),
     772                          gos->argv[0], gos->argv[gos->optind - 1]);
     773                  gos->nextchar += strlen (gos->nextchar);
     774                  gos->optopt = pfound->val;
     775                  return gos->optstring[0] == ':' ? ':' : '?';
    716776                }
    717777            }
    718           nextchar += strlen (nextchar);
     778          gos->nextchar += strlen (gos->nextchar);
    719779          if (longind != NULL)
    720780            *longind = option_index;
     
    731791         option, then it's an error.
    732792         Otherwise interpret it as a short option.  */
    733       if (!long_only || argv[optind][1] == '-'
    734           || my_index (optstring, *nextchar) == NULL)
    735         {
    736           if (opterr)
     793      if (!long_only || gos->argv[gos->optind][1] == '-'
     794          || memchr(gos->optstring, *gos->nextchar, gos->len_optstring) == NULL)
     795        {
     796          if (gos->opterr)
    737797            {
    738               if (argv[optind][1] == '-')
     798              if (gos->argv[gos->optind][1] == '-')
    739799                /* --option */
    740                 fprintf (stderr, _("%s: unrecognized option '--%s'\n"),
    741                          argv[0], nextchar);
     800                errx (gos->pCtx, 2, _("%s: unrecognized option '--%s'\n"),
     801                      gos->argv[0], gos->nextchar);
    742802              else
    743803                /* +option or -option */
    744                 fprintf (stderr, _("%s: unrecognized option '%c%s'\n"),
    745                          argv[0], argv[optind][0], nextchar);
     804                errx (gos->pCtx, 2, _("%s: unrecognized option '%c%s'\n"),
     805                      gos->argv[0], gos->argv[gos->optind][0], gos->nextchar);
    746806            }
    747           nextchar = (char *) "";
    748           optind++;
    749           optopt = 0;
     807          gos->nextchar = (char *) "";
     808          gos->optind++;
     809          gos->optopt = 0;
    750810          return '?';
    751811        }
     
    755815
    756816  {
    757     char c = *nextchar++;
    758     char *temp = my_index (optstring, c);
     817    char c = *gos->nextchar++;
     818    char *temp = (char *)memchr (gos->optstring, c, gos->len_optstring);
    759819
    760820    /* Increment `optind' when we start to process its last character.  */
    761     if (*nextchar == '\0')
    762       ++optind;
     821    if (*gos->nextchar == '\0')
     822      ++gos->optind;
    763823
    764824    if (temp == NULL || c == ':')
    765825      {
    766         if (opterr)
     826        if (gos->opterr)
    767827          {
    768             if (posixly_correct)
     828            if (gos->posixly_correct)
    769829              /* 1003.2 specifies the format of this message.  */
    770               fprintf (stderr, _("%s: illegal option -- %c\n"),
    771                        argv[0], c);
     830              errx (gos->pCtx, 2, _("%s: illegal option -- %c\n"),
     831                    gos->argv[0], c);
    772832            else
    773               fprintf (stderr, _("%s: invalid option -- %c\n"),
    774                        argv[0], c);
     833              errx (gos->pCtx, 2, _("%s: invalid option -- %c\n"),
     834                    gos->argv[0], c);
    775835          }
    776         optopt = c;
     836        gos->optopt = c;
    777837        return '?';
    778838      }
     
    789849
    790850        /* This is an option that requires an argument.  */
    791         if (*nextchar != '\0')
     851        if (*gos->nextchar != '\0')
    792852          {
    793             optarg = nextchar;
     853            gos->optarg = gos->nextchar;
    794854            /* If we end this ARGV-element by taking the rest as an arg,
    795855               we must advance to the next element now.  */
    796             optind++;
     856            gos->optind++;
    797857          }
    798         else if (optind == argc)
     858        else if (gos->optind == gos->argc)
    799859          {
    800             if (opterr)
     860            if (gos->opterr)
    801861              {
    802862                /* 1003.2 specifies the format of this message.  */
    803                 fprintf (stderr, _("%s: option requires an argument -- %c\n"),
    804                          argv[0], c);
     863                errx (gos->pCtx, 2, _("%s: option requires an argument -- %c\n"),
     864                      gos->argv[0], c);
    805865              }
    806             optopt = c;
    807             if (optstring[0] == ':')
     866            gos->optopt = c;
     867            if (gos->optstring[0] == ':')
    808868              c = ':';
    809869            else
     
    814874          /* We already incremented `optind' once;
    815875             increment it again when taking next ARGV-elt as argument.  */
    816           optarg = argv[optind++];
     876          gos->optarg = gos->argv[gos->optind++];
    817877
    818878        /* optarg is now the argument, see if it's in the
    819879           table of longopts.  */
    820880
    821         for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
     881        for (gos->nextchar = nameend = gos->optarg; *nameend && *nameend != '='; nameend++)
    822882          /* Do nothing.  */ ;
    823883
     
    825885           or abbreviated matches.  */
    826886        for (p = longopts, option_index = 0; p->name; p++, option_index++)
    827           if (!strncmp (p->name, nextchar, nameend - nextchar))
     887          if (!strncmp (p->name, gos->nextchar, nameend - gos->nextchar))
    828888            {
    829               if ((unsigned int) (nameend - nextchar) == strlen (p->name))
     889              if ((unsigned int) (nameend - gos->nextchar) == strlen (p->name))
    830890                {
    831891                  /* Exact match found.  */
     
    847907        if (ambig && !exact)
    848908          {
    849             if (opterr)
    850               fprintf (stderr, _("%s: option '-W %s' is ambiguous\n"),
    851                        argv[0], argv[optind]);
    852             nextchar += strlen (nextchar);
    853             optind++;
     909            if (gos->opterr)
     910              errx (gos->pCtx, 2, _("%s: option '-W %s' is ambiguous\n"),
     911                    gos->argv[0], gos->argv[gos->optind]);
     912            gos->nextchar += strlen (gos->nextchar);
     913            gos->optind++;
    854914            return '?';
    855915          }
     
    862922                   allow it to be used on enums.  */
    863923                if (pfound->has_arg)
    864                   optarg = nameend + 1;
     924                  gos->optarg = nameend + 1;
    865925                else
    866926                  {
    867                     if (opterr)
    868                       fprintf (stderr, _("\
    869 %s: option '-W %s' doesn't allow an argument\n"),
    870                                argv[0], pfound->name);
    871 
    872                     nextchar += strlen (nextchar);
     927                    if (gos->opterr)
     928                      errx (gos->pCtx, 2,
     929                            _("%s: option '-W %s' doesn't allow an argument\n"),
     930                            gos->argv[0], pfound->name);
     931
     932                    gos->nextchar += strlen (gos->nextchar);
    873933                    return '?';
    874934                  }
     
    876936            else if (pfound->has_arg == 1)
    877937              {
    878                 if (optind < argc)
    879                   optarg = argv[optind++];
     938                if (gos->optind < gos->argc)
     939                  gos->optarg = gos->argv[gos->optind++];
    880940                else
    881941                  {
    882                     if (opterr)
    883                       fprintf (stderr,
    884                                _("%s: option '%s' requires an argument\n"),
    885                                argv[0], argv[optind - 1]);
    886                     nextchar += strlen (nextchar);
    887                     return optstring[0] == ':' ? ':' : '?';
     942                    if (gos->opterr)
     943                      errx (gos->pCtx, 2,
     944                            _("%s: option '%s' requires an argument\n"),
     945                            gos->argv[0], gos->argv[gos->optind - 1]);
     946                    gos->nextchar += strlen (gos->nextchar);
     947                    return gos->optstring[0] == ':' ? ':' : '?';
    888948                  }
    889949              }
    890             nextchar += strlen (nextchar);
     950            gos->nextchar += strlen (gos->nextchar);
    891951            if (longind != NULL)
    892952              *longind = option_index;
     
    898958            return pfound->val;
    899959          }
    900           nextchar = NULL;
     960          gos->nextchar = NULL;
    901961          return 'W';   /* Let the application handle it.   */
    902962      }
     
    906966          {
    907967            /* This is an option that accepts an argument optionally.  */
    908             if (*nextchar != '\0')
     968            if (*gos->nextchar != '\0')
    909969              {
    910                 optarg = nextchar;
    911                 optind++;
     970                gos->optarg = gos->nextchar;
     971                gos->optind++;
    912972              }
    913973            else
    914               optarg = NULL;
    915             nextchar = NULL;
     974              gos->optarg = NULL;
     975            gos->nextchar = NULL;
    916976          }
    917977        else
    918978          {
    919979            /* This is an option that requires an argument.  */
    920             if (*nextchar != '\0')
     980            if (*gos->nextchar != '\0')
    921981              {
    922                 optarg = nextchar;
     982                gos->optarg = gos->nextchar;
    923983                /* If we end this ARGV-element by taking the rest as an arg,
    924984                   we must advance to the next element now.  */
    925                 optind++;
     985                gos->optind++;
    926986              }
    927             else if (optind == argc)
     987            else if (gos->optind == gos->argc)
    928988              {
    929                 if (opterr)
     989                if (gos->opterr)
    930990                  {
    931991                    /* 1003.2 specifies the format of this message.  */
    932                     fprintf (stderr,
    933                            _("%s: option requires an argument -- %c\n"),
    934                            argv[0], c);
     992                    errx (gos->pCtx, 2,
     993                          _("%s: option requires an argument -- %c\n"),
     994                          gos->argv[0], c);
    935995                  }
    936                 optopt = c;
    937                 if (optstring[0] == ':')
     996                gos->optopt = c;
     997                if (gos->optstring[0] == ':')
    938998                  c = ':';
    939999                else
     
    9431003              /* We already incremented `optind' once;
    9441004                 increment it again when taking next ARGV-elt as argument.  */
    945               optarg = argv[optind++];
    946             nextchar = NULL;
     1005              gos->optarg = gos->argv[gos->optind++];
     1006            gos->nextchar = NULL;
    9471007          }
    9481008      }
     
    9521012
    9531013int
    954 getopt (int argc, char *const *argv, const char *optstring)
     1014getopt_r (struct getopt_state_r *gos)
    9551015{
    956   return _getopt_internal (argc, argv, optstring,
    957                            (const struct option *) 0,
    958                            (int *) 0,
    959                            0);
     1016  return _getopt_internal_r (gos, NULL, NULL, 0);
    9601017}
    9611018
    962 #endif  /* Not ELIDE_CODE.  */
     1019#endif /* #if 1 */ /* Not ELIDE_CODE.  */
    9631020
    9641021
     
    9731030  int c;
    9741031  int digit_optind = 0;
     1032  struct getopt_state_r = gos;
     1033
     1034  getopt_initialize_r (&gos, argc, argv, "abc:d:0123456789", NULL, NULL, NULL);
    9751035
    9761036  while (1)
    9771037    {
    978       int this_option_optind = optind ? optind : 1;
    979 
    980       c = getopt (argc, argv, "abc:d:0123456789");
     1038      int this_option_optind = gos.optind ? gos.optind : 1;
     1039
     1040      c = getopt_r (&gos);
    9811041      if (c == -1)
    9821042        break;
     
    10201080    }
    10211081
    1022   if (optind < argc)
     1082  if (gos.optind < argc)
    10231083    {
    10241084      printf ("non-option ARGV-elements: ");
    1025       while (optind < argc)
    1026         printf ("%s ", argv[optind++]);
     1085      while (gos.optind < argc)
     1086        printf ("%s ", argv[gos.optind++]);
    10271087      printf ("\n");
    10281088    }
Note: See TracChangeset for help on using the changeset viewer.