VirtualBox

Changeset 3213 in kBuild


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

kmk: Forked getopt and created a reentrant variant getopt_r.

Location:
trunk/src/kmk/kmkbuiltin
Files:
2 edited
3 copied

Legend:

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

    r3212 r3213  
    1 /* getopt_long and getopt_long_only entry points for GNU getopt.
     1/*  Reentrant version of getopt_long and getopt_long_only.
     2
     3Based on ../getopt*.*:
     4
     5   getopt_long and getopt_long_only entry points for GNU getopt.
    26Copyright (C) 1987-1994, 1996-2016 Free Software Foundation, Inc.
    37
     
    1519
    1620You should have received a copy of the GNU General Public License along with
    17 this program.  If not, see <http://www.gnu.org/licenses/>.  */
     21this program.  If not, see <http://www.gnu.org/licenses/>.
     22
     23Modifications:
     24  Copyright (c) 2018 knut st. osmundsen <[email protected]>
     25*/
    1826
    1927
     28#define FAKES_NO_GETOPT_H /* bird */
    2029#ifdef HAVE_CONFIG_H
    2130#include <config.h>
    2231#endif
    2332
    24 #include "getopt.h"
     33#include "getopt_r.h"
    2534
    2635#if !defined __STDC__ || !__STDC__
     
    3443#include <stdio.h>
    3544
     45#if 0
    3646/* Comment out all this code if we are using the GNU C Library, and are not
    3747   actually compiling the library itself.  This code is part of the GNU C
     
    4959#endif
    5060#endif
     61#endif
    5162
    52 #ifndef ELIDE_CODE
     63#if 1 //ndef ELIDE_CODE
    5364
    5465
     
    6475
    6576int
    66 getopt_long (int argc, char *const *argv, const char *options,
    67              const struct option *long_options, int *opt_index)
     77getopt_long_r (struct getopt_state_r *gos, int *opt_index)
    6878{
    69   return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
     79  return _getopt_internal_r (gos, gos->long_options, opt_index, 0);
    7080}
    7181
     
    7686
    7787int
    78 getopt_long_only (int argc, char *const *argv, const char *options,
    79                   const struct option *long_options, int *opt_index)
     88getopt_long_only_r (struct getopt_state_r *gos, int *opt_index)
    8089{
    81   return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
     90  return _getopt_internal_r (gos, gos->long_options, opt_index, 0);
    8291}
    8392
    8493
    85 #endif  /* Not ELIDE_CODE.  */
     94#endif /* #if 1 */ /* Not ELIDE_CODE.  */
    8695
    8796
     
    100109      int this_option_optind = optind ? optind : 1;
    101110      int option_index = 0;
     111      struct getopt_state_r gos;
    102112      static struct option long_options[] =
    103113      {
     
    111121      };
    112122
    113       c = getopt_long (argc, argv, "abc:d:0123456789",
    114                        long_options, &option_index);
     123      getopt_initialize_r (&gos, argc, argv, "abc:d:0123456789", long_options, NULL, NULL);
     124      c = getopt_long_r (&geo, &option_index);
    115125      if (c == -1)
    116126        break;
     
    120130        case 0:
    121131          printf ("option %s", long_options[option_index].name);
    122           if (optarg)
    123             printf (" with arg %s", optarg);
     132          if (geo.optarg)
     133            printf (" with arg %s", geo.optarg);
    124134          printf ("\n");
    125135          break;
     
    150160
    151161        case 'c':
    152           printf ("option c with value '%s'\n", optarg);
     162          printf ("option c with value '%s'\n", geo.optarg);
    153163          break;
    154164
    155165        case 'd':
    156           printf ("option d with value '%s'\n", optarg);
     166          printf ("option d with value '%s'\n", geo.optarg);
    157167          break;
    158168
     
    165175    }
    166176
    167   if (optind < argc)
     177  if (geo.optind < argc)
    168178    {
    169179      printf ("non-option ARGV-elements: ");
    170180      while (optind < argc)
    171         printf ("%s ", argv[optind++]);
     181        printf ("%s ", argv[geo.optind++]);
    172182      printf ("\n");
    173183    }
  • 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 [email protected]
     
    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 <[email protected]>
     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    }
  • trunk/src/kmk/kmkbuiltin/getopt_r.h

    r3212 r3213  
    1 /* Declarations for getopt.
     1/* Reentrant version of getopt.
     2
     3Based on ../getopt*.*:
     4
     5   Declarations for getopt.
    26Copyright (C) 1989-2016 Free Software Foundation, Inc.
    37
     
    1519
    1620You should have received a copy of the GNU General Public License along with
    17 this program.  If not, see <http://www.gnu.org/licenses/>.  */
     21this program.  If not, see <http://www.gnu.org/licenses/>.
    1822
    19 #ifndef _GETOPT_H
    20 #define _GETOPT_H 1
     23Modifications:
     24  Copyright (c) 2018 knut st. osmundsen <[email protected]>
     25*/
     26
     27/* Not quite safe to mix when converting code. */
     28#ifdef _GETOPT_H
     29# define _GETOPT_H "getopt.h was included already"
     30# error "getopt.h was included already"
     31#endif
     32
     33#ifndef INCLUDED_GETOPT_R_H
     34#define INCLUDED_GETOPT_R_H 1
    2135
    2236#ifdef  __cplusplus
    2337extern "C" {
    2438#endif
     39
     40typedef struct getopt_state_r
     41{
    2542
    2643/* For communication from `getopt' to the caller.
     
    3047   each non-option ARGV-element is returned here.  */
    3148
    32 extern char *optarg;
     49/*extern*/ char *optarg;
    3350
    3451/* Index in ARGV of the next element to be scanned.
     
    4461   how much of ARGV has been scanned so far.  */
    4562
    46 extern int optind;
     63/*extern*/ int optind;
    4764
    4865/* Callers store zero here to inhibit the error message `getopt' prints
    4966   for unrecognized options.  */
    5067
    51 extern int opterr;
     68/*extern*/ int opterr;
    5269
    5370/* Set to an option character which was unrecognized.  */
    5471
    55 extern int optopt;
     72/*extern*/ int optopt;
     73
     74
     75/* Internal state: */
     76
     77/* The next char to be scanned in the option-element
     78   in which the last option character we returned was found.
     79   This allows us to pick up the scan where we left off.
     80
     81   If this is zero, or a null string, it means resume the scan
     82   by advancing to the next ARGV-element.  */
     83
     84/*static*/ char *nextchar;
     85
     86/* REQUIRE_ORDER, PERMUTE or RETURN_IN_ORDER, see getopt_r.c. */
     87/*static*/ int ordering;
     88
     89/* Value of POSIXLY_CORRECT environment variable.  */
     90/*static*/ char *posixly_correct;
     91
     92/* Describe the part of ARGV that contains non-options that have
     93   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
     94   `last_nonopt' is the index after the last of them.  */
     95
     96/*static*/ int first_nonopt;
     97/*static*/ int last_nonopt;
     98
     99/* Mainly for asserting usage sanity. */
     100/*static*/ void *__getopt_initialized;
     101
     102/* New internal state (to resubmitting same parameters in each call): */
     103  /* new: the argument vector length. */
     104  int argc;
     105  /* new: the argument vector. */
     106  char * const *argv;
     107  /* new: the short option string (can be NULL/empty). */
     108  const char *optstring;
     109  /* new: the short option string length. */
     110  size_t len_optstring;
     111  /* new: the long options (can be NULL) */
     112  const struct option *long_options;
     113  /* Output context for err.h. */
     114  struct KMKBUILTINCTX *pCtx;
     115} getopt_state_r;
     116
     117
     118#ifndef no_argument
    56119
    57120/* Describe the long-named options requested by the application.
     
    96159#define optional_argument       2
    97160
    98 #if defined (__STDC__) && __STDC__
    99 #ifdef __GNU_LIBRARY__
    100 /* Many other libraries have conflicting prototypes for getopt, with
    101    differences in the consts, in stdlib.h.  To avoid compilation
    102    errors, only prototype getopt for the GNU C library.  */
    103 extern int getopt (int argc, char *const *argv, const char *shortopts);
    104 #else /* not __GNU_LIBRARY__ */
    105 extern int getopt ();
    106 #endif /* __GNU_LIBRARY__ */
    107 extern int getopt_long (int argc, char *const *argv, const char *shortopts,
    108                         const struct option *longopts, int *longind);
    109 extern int getopt_long_only (int argc, char *const *argv,
    110                              const char *shortopts,
    111                              const struct option *longopts, int *longind);
     161#endif /* Same as ../getopt.h.  Fix later? */
     162
     163extern void getopt_initialize_r (struct getopt_state_r *gos, int argc,
     164                                 char *const *argv, const char *shortopts,
     165                                 const struct option *longopts,
     166                                 char **envp, struct KMKBUILTINCTX *pCtx);
     167extern int getopt_r (struct getopt_state_r *gos);
     168extern int getopt_long_r (struct getopt_state_r *gos, int *longind);
     169extern int getopt_long_only_r (struct getopt_state_r *gos, int *longind);
    112170
    113171/* Internal only.  Users should not call this directly.  */
    114 extern int _getopt_internal (int argc, char *const *argv,
    115                              const char *shortopts,
    116                              const struct option *longopts, int *longind,
    117                              int long_only);
    118 #else /* not __STDC__ */
    119 extern int getopt ();
    120 extern int getopt_long ();
    121 extern int getopt_long_only ();
    122 
    123 extern int _getopt_internal ();
    124 #endif /* __STDC__ */
     172extern int _getopt_internal_r (struct getopt_state_r *gos,
     173                               const struct option *longopts,
     174                               int *longind, int long_only);
    125175
    126176#ifdef  __cplusplus
     
    128178#endif
    129179
    130 #endif /* getopt.h */
     180#endif /* getopt_r.h */
  • trunk/src/kmk/kmkbuiltin/mscfakes.h

    r3188 r3213  
    3838#include <stdarg.h>
    3939#include <malloc.h>
    40 #include "getopt.h"
     40#ifndef FAKES_NO_GETOPT_H
     41# include "getopt.h"
     42#endif
    4143#ifndef MSCFAKES_NO_WINDOWS_H
    4244# include <Windows.h>
  • trunk/src/kmk/kmkbuiltin/solfakes.h

    r2413 r3213  
    3030#include <stdarg.h>
    3131#include <sys/types.h>
    32 #include "getopt.h"
     32#ifndef FAKES_NO_GETOPT_H
     33# include "getopt.h"
     34#endif
     35
    3336#define _PATH_DEVNULL "/dev/null"
    3437#define ALLPERMS 0000777
     
    4548
    4649#endif /* __sun__ */
    47 #endif /* ___solfakes_h */
     50#endif /* !___solfakes_h */
    4851
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette