From:	MERC::"uunet!WKUVX1.BITNET!FILESERV-Mgr" 12-JUN-1992 15:01:50.93
To:	galaxy::gleeve
CC:	
Subj:	GREP.05_OF_12

-+-+-+-+-+-+-+-+ START OF PART 5 -+-+-+-+-+-+-+-+
X`09`09`09`09   it is only a lexeme. */
X
X  _RPAREN,`09`09`09/* _RPAREN never appears in the parse tree. */
X
X  _SET`09`09`09`09/* _SET and (and any value greater) is a
X`09`09`09`09   terminal symbol that matches any of a
X`09`09`09`09   class of characters. */
X`7D _token;
X
X#else /* ! __STDC__ */
X
Xtypedef short _token;
X
X#define _END -1
X#define _EMPTY _NOTCHAR
X#define _BACKREF (_EMPTY + 1)
X#define _BEGLINE (_EMPTY + 2)
X#define _ALLBEGLINE (_EMPTY + 3)
X#define _ENDLINE (_EMPTY + 4)
X#define _ALLENDLINE (_EMPTY + 5)
X#define _BEGWORD (_EMPTY + 6)
X#define _ENDWORD (_EMPTY + 7)
X#define _LIMWORD (_EMPTY + 8)
X#define _NOTLIMWORD (_EMPTY + 9)
X#define _QMARK (_EMPTY + 10)
X#define _STAR (_EMPTY + 11)
X#define _PLUS (_EMPTY + 12)
X#define _CAT (_EMPTY + 13)
X#define _OR (_EMPTY + 14)
X#define _LPAREN (_EMPTY + 15)
X#define _RPAREN (_EMPTY + 16)
X#define _SET (_EMPTY + 17)
X
X#endif /* ! __STDC__ */
X
X/* Sets are stored in an array in the compiled regexp; the index of the
X   array corresponding to a given set token is given by _SET_INDEX(t). */
X#define _SET_INDEX(t) ((t) - _SET)
X
X/* Sometimes characters can only be matched depending on the surrounding
X   context.  Such context decisions depend on what the previous character
X   was, and the value of the current (lookahead) character.  Context
X   dependent constraints are encoded as 8 bit integers.  Each bit that
X   is set indicates that the constraint succeeds in the corresponding
X   context.
X
X   bit 7 - previous and current are newlines
X   bit 6 - previous was newline, current isn't
X   bit 5 - previous wasn't newline, current is
X   bit 4 - neither previous nor current is a newline
X   bit 3 - previous and current are word-constituents
X   bit 2 - previous was word-constituent, current isn't
X   bit 1 - previous wasn't word-constituent, current is
X   bit 0 - neither previous nor current is word-constituent
X
X   Word-constituent characters are those that satisfy isalnum().
X
X   The macro _SUCCEEDS_IN_CONTEXT determines whether a a given constraint
X   succeeds in a particular context.  Prevn is true if the previous characte
Vr
X   was a newline, currn is true if the lookahead character is a newline.
X   Prevl and currl similarly depend upon whether the previous and current
X   characters are word-constituent letters. */
X#define _MATCHES_NEWLINE_CONTEXT(constraint, prevn, currn) \
X  ((constraint) & 1 << ((prevn) ? 2 : 0) + ((currn) ? 1 : 0) + 4)
X#define _MATCHES_LETTER_CONTEXT(constraint, prevl, currl) \
X  ((constraint) & 1 << ((prevl) ? 2 : 0) + ((currl) ? 1 : 0))
X#define _SUCCEEDS_IN_CONTEXT(constraint, prevn, currn, prevl, currl) \
X  (_MATCHES_NEWLINE_CONTEXT(constraint, prevn, currn)`09`09     \
X   && _MATCHES_LETTER_CONTEXT(constraint, prevl, currl))
X
X/* The following macros give information about what a constraint depends on.
V */
X#define _PREV_NEWLINE_DEPENDENT(constraint) \
X  (((constraint) & 0xc0) >> 2 != ((constraint) & 0x30))
X#define _PREV_LETTER_DEPENDENT(constraint) \
X  (((constraint) & 0x0c) >> 2 != ((constraint) & 0x03))
X
X/* Tokens that match the empty string subject to some constraint actually
X   work by applying that constraint to determine what may follow them,
X   taking into account what has gone before.  The following values are
X   the constraints corresponding to the special tokens previously defined. *
V/
X#define _NO_CONSTRAINT 0xff
X#define _BEGLINE_CONSTRAINT 0xcf
X#define _ENDLINE_CONSTRAINT 0xaf
X#define _BEGWORD_CONSTRAINT 0xf2
X#define _ENDWORD_CONSTRAINT 0xf4
X#define _LIMWORD_CONSTRAINT 0xf6
X#define _NOTLIMWORD_CONSTRAINT 0xf9
X
X/* States of the recognizer correspond to sets of positions in the parse
X   tree, together with the constraints under which they may be matched.
X   So a position is encoded as an index into the parse tree together with
X   a constraint. */
Xtypedef struct
X`7B
X  unsigned index;`09`09/* Index into the parse array. */
X  unsigned constraint;`09`09/* Constraint for matching this position. */
X`7D _position;
X
X/* Sets of positions are stored as arrays. */
Xtypedef struct
X`7B
X  _position *elems;`09`09/* Elements of this position set. */
X  int nelem;`09`09`09/* Number of elements in this set. */
X`7D _position_set;
X
X/* A state of the regexp consists of a set of positions, some flags,
X   and the token value of the lowest-numbered position of the state that
X   contains an _END token. */
Xtypedef struct
X`7B
X  int hash;`09`09`09/* Hash of the positions of this state. */
X  _position_set elems;`09`09/* Positions this state could match. */
X  char newline;`09`09`09/* True if previous state matched newline. */
X  char letter;`09`09`09/* True if previous state matched a letter. */
X  char backref;`09`09`09/* True if this state matches a \<digit>. */
X  unsigned char constraint;`09/* Constraint for this state to accept. */
X  int first_end;`09`09/* Token value of the first _END in elems. */
X`7D _dfa_state;
X
X/* If an r.e. is at most MUST_MAX characters long, we look for a string whic
Vh
X   must appear in it; whatever's found is dropped into the struct reg. */
X
X#define MUST_MAX`0950
X
X/* A compiled regular expression. */
Xstruct regexp
X`7B
X  /* Stuff built by the scanner. */
X  _charset *charsets;`09`09/* Array of character sets for _SET tokens. */
X  int cindex;`09`09`09/* Index for adding new charsets. */
X  int calloc;`09`09`09/* Number of charsets currently allocated. */
X
X  /* Stuff built by the parser. */
X  _token *tokens;`09`09/* Postfix parse array. */
X  int tindex;`09`09`09/* Index for adding new tokens. */
X  int talloc;`09`09`09/* Number of tokens currently allocated. */
X  int depth;`09`09`09/* Depth required of an evaluation stack
X`09`09`09`09   used for depth-first traversal of the
X`09`09`09`09   parse tree. */
X  int nleaves;`09`09`09/* Number of leaves on the parse tree. */
X  int nregexps;`09`09`09/* Count of parallel regexps being built
X`09`09`09`09   with regparse(). */
X
X  /* Stuff owned by the state builder. */
X  _dfa_state *states;`09`09/* States of the regexp. */
X  int sindex;`09`09`09/* Index for adding new states. */
X  int salloc;`09`09`09/* Number of states currently allocated. */
X
X  /* Stuff built by the structure analyzer. */
X  _position_set *follows;`09/* Array of follow sets, indexed by position
X`09`09`09`09   index.  The follow of a position is the set
X`09`09`09`09   of positions containing characters that
X`09`09`09`09   could conceivably follow a character
X`09`09`09`09   matching the given position in a string
X`09`09`09`09   matching the regexp.  Allocated to the
X`09`09`09`09   maximum possible position index. */
X  int searchflag;`09`09/* True if we are supposed to build a searching
X`09`09`09`09   as opposed to an exact matcher.  A searching
X`09`09`09`09   matcher finds the first and shortest string
X`09`09`09`09   matching a regexp anywhere in the buffer,
X`09`09`09`09   whereas an exact matcher finds the longest
X`09`09`09`09   string matching, but anchored to the
X`09`09`09`09   beginning of the buffer. */
X
X  /* Stuff owned by the executor. */
X  int tralloc;`09`09`09/* Number of transition tables that have
X`09`09`09`09   slots so far. */
X  int trcount;`09`09`09/* Number of transition tables that have
X`09`09`09`09   actually been built. */
X  int **trans;`09`09`09/* Transition tables for states that can
X`09`09`09`09   never accept.  If the transitions for a
X`09`09`09`09   state have not yet been computed, or the
X`09`09`09`09   state could possibly accept, its entry in
X`09`09`09`09   this table is NULL. */
X  int **realtrans;`09`09/* Trans always points to realtrans + 1; this
X`09`09`09`09   is so trans`5B-1`5D can contain NULL. */
X  int **fails;`09`09`09/* Transition tables after failing to accept
X`09`09`09`09   on a state that potentially could do so. */
X  int *success;`09`09`09/* Table of acceptance conditions used in
X`09`09`09`09   regexecute and computed in build_state. */
X  int *newlines;`09`09/* Transitions on newlines.  The entry for a
X`09`09`09`09   newline in any transition table is always
X`09`09`09`09   -1 so we can count lines without wasting
X`09`09`09`09   too many cycles.  The transition for a
X`09`09`09`09   newline is stored separately and handled
X`09`09`09`09   as a special case.  Newline is also used
X`09`09`09`09   as a sentinel at the end of the buffer. */
X  char must`5BMUST_MAX`5D;
X  int mustn;
X`7D;
X
X/* Some macros for user access to regexp internals. */
X
X/* ACCEPTING returns true if s could possibly be an accepting state of r. */
X#define ACCEPTING(s, r) ((r).states`5Bs`5D.constraint)
X
X/* ACCEPTS_IN_CONTEXT returns true if the given state accepts in the
X   specified context. */
X#define ACCEPTS_IN_CONTEXT(prevn, currn, prevl, currl, state, reg) \
X  _SUCCEEDS_IN_CONTEXT((reg).states`5Bstate`5D.constraint,`09`09   \
X`09`09       prevn, currn, prevl, currl)
X
X/* FIRST_MATCHING_REGEXP returns the index number of the first of parallel
X   regexps that a given state could accept.  Parallel regexps are numbered
X   starting at 1. */
X#define FIRST_MATCHING_REGEXP(state, reg) (-(reg).states`5Bstate`5D.first_en
Vd)
X
X/* Entry points. */
X
X#if __STDC__
X
X/* Regsyntax() takes two arguments; the first sets the syntax bits described
X   earlier in this file, and the second sets the case-folding flag. */
Xextern void regsyntax(int, int);
X
X/* Compile the given string of the given length into the given struct regexp
V.
X   Final argument is a flag specifying whether to build a searching or an
X   exact matcher. */
Xextern void regcompile(const char *, size_t, struct regexp *, int);
X
X/* Execute the given struct regexp on the buffer of characters.  The
X   first char * points to the beginning, and the second points to the
X   first character after the end of the buffer, which must be a writable
X   place so a sentinel end-of-buffer marker can be stored there.  The
X   second-to-last argument is a flag telling whether to allow newlines to
X   be part of a string matching the regexp.  The next-to-last argument,
X   if non-NULL, points to a place to increment every time we see a
X   newline.  The final argument, if non-NULL, points to a flag that will
X   be set if further examination by a backtracking matcher is needed in
X   order to verify backreferencing; otherwise the flag will be cleared.
X   Returns NULL if no match is found, or a pointer to the first
X   character after the first & shortest matching string in the buffer. */
Xextern char *regexecute(struct regexp *, char *, char *, int, int *, int *);
X
X/* Free the storage held by the components of a struct regexp. */
Xextern void regfree(struct regexp *);
X
X/* Entry points for people who know what they're doing. */
X
X/* Initialize the components of a struct regexp. */
Xextern void reginit(struct regexp *);
X
X/* Incrementally parse a string of given length into a struct regexp. */
Xextern void regparse(const char *, size_t, struct regexp *);
X
X/* Analyze a parsed regexp; second argument tells whether to build a searchi
Vng
X   or an exact matcher. */
Xextern void reganalyze(struct regexp *, int);
X
X/* Compute, for each possible character, the transitions out of a given
X   state, storing them in an array of integers. */
Xextern void regstate(int, struct regexp *, int `5B`5D);
X
X/* Error handling. */
X
X/* Regerror() is called by the regexp routines whenever an error occurs.  It
X   takes a single argument, a NUL-terminated string describing the error.
X   The default regerror() prints the error message to stderr and exits.
X   The user can provide a different regfree() if so desired. */
Xextern void regerror(const char *);
X
X#else /* ! __STDC__ */
Xextern void regsyntax(), regcompile(), regfree(), reginit(), regparse();
Xextern void reganalyze(), regstate(), regerror();
Xextern char *regexecute();
X#endif /* ! __STDC__ */
$ CALL UNPACK [.GREP016]DFA.H;1 343815315
$ create 'f'
X/* Getopt for GNU.
X   NOTE: getopt is now part of the C library, so if you don't know what
X   "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
X   before changing it!
X
X   Copyright (C) 1987, 88, 89, 90, 91, 1992 Free Software Foundation, Inc.
X
X   This program is free software; you can redistribute it and/or modify
X   it under the terms of the GNU General Public License as published by
X   the Free Software Foundation; either version 2, or (at your option)
X   any later version.
X
X   This program is distributed in the hope that it will be useful,
X   but WITHOUT ANY WARRANTY; without even the implied warranty of
X   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
X   GNU General Public License for more details.
X
X   You should have received a copy of the GNU General Public License
X   along with this program; if not, write to the Free Software
X   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
X`0C
X/* AIX requires this to be the first thing in the file. */
X#ifdef __GNUC__
X#define alloca __builtin_alloca
X#else /* not __GNUC__ */
X#if defined(sparc) && !defined(USG) && !defined(SVR4) && !defined(__svr4__)
X#include <alloca.h>
X#else
X#ifdef _AIX
X #pragma alloca
X#else
Xchar *alloca ();
X#endif
X#endif /* sparc */
X#endif /* not __GNUC__ */
X
X#ifdef`09LIBC
X/* For when compiled as part of the GNU C library.  */
X#include <ansidecl.h>
X#endif
X
X#include <stdio.h>
X
X/* This needs to come after some library #include
X   to get __GNU_LIBRARY__ defined.  */
X#ifdef`09__GNU_LIBRARY__
X#undef`09alloca
X#include <stdlib.h>
X#include <string.h>
X#else`09/* Not GNU C library.  */
X#define`09__alloca`09alloca
X#endif`09/* GNU C library.  */
X
X
X#ifndef __STDC__
X#define const
X#endif
X
X/* If GETOPT_COMPAT is defined, `60+' as well as `60--' can introduce a
X   long-named option.  Because this is not POSIX.2 compliant, it is
X   being phased out. */
X#define GETOPT_COMPAT
X
X/* This version of `60getopt' appears to the caller like standard Unix `60ge
Vtopt'
X   but it behaves differently for the user, since it allows the user
X   to intersperse the options with the other arguments.
X
X   As `60getopt' works, it permutes the elements of ARGV so that,
X   when it is done, all the options precede everything else.  Thus
X   all application programs are extended to handle flexible argument order.
X
X   Setting the environment variable POSIXLY_CORRECT disables permutation.
X   Then the behavior is completely standard.
X
X   GNU application programs can use a third alternative mode in which
X   they can distinguish the relative order of options and other arguments.
V  */
X
X#include "getopt.h"
X
X/* For communication from `60getopt' to the caller.
X   When `60getopt' finds an option that takes an argument,
X   the argument value is returned here.
X   Also, when `60ordering' is RETURN_IN_ORDER,
X   each non-option ARGV-element is returned here.  */
X
Xchar *optarg = 0;
X
X/* Index in ARGV of the next element to be scanned.
X   This is used for communication to and from the caller
X   and for communication between successive calls to `60getopt'.
X
X   On entry to `60getopt', zero means this is the first call; initialize.
X
X   When `60getopt' returns EOF, this is the index of the first of the
X   non-option elements that the caller should itself scan.
X
X   Otherwise, `60optind' communicates from one call to the next
X   how much of ARGV has been scanned so far.  */
X
Xint optind = 0;
X
X/* The next char to be scanned in the option-element
X   in which the last option character we returned was found.
X   This allows us to pick up the scan where we left off.
X
X   If this is zero, or a null string, it means resume the scan
X   by advancing to the next ARGV-element.  */
X
Xstatic char *nextchar;
X
X/* Callers store zero here to inhibit the error message
X   for unrecognized options.  */
X
Xint opterr = 1;
X
X/* Describe how to deal with options that follow non-option ARGV-elements.
X
X   If the caller did not specify anything,
X   the default is REQUIRE_ORDER if the environment variable
X   POSIXLY_CORRECT is defined, PERMUTE otherwise.
X
X   REQUIRE_ORDER means don't recognize them as options;
X   stop option processing when the first non-option is seen.
X   This is what Unix does.
X   This mode of operation is selected by either setting the environment
X   variable POSIXLY_CORRECT, or using `60+' as the first character
X   of the list of option characters.
X
X   PERMUTE is the default.  We permute the contents of ARGV as we scan,
X   so that eventually all the non-options are at the end.  This allows optio
Vns
X   to be given in any order, even with programs that were not written to
X   expect this.
X
X   RETURN_IN_ORDER is an option available to programs that were written
X   to expect options and other ARGV-elements in any order and that care abou
Vt
X   the ordering of the two.  We describe each non-option ARGV-element
X   as if it were the argument of an option with character code 1.
X   Using `60-' as the first character of the list of option characters
X   selects this mode of operation.
X
X   The special argument `60--' forces an end of option-scanning regardless
X   of the value of `60ordering'.  In the case of RETURN_IN_ORDER, only
X   `60--' can cause `60getopt' to return EOF with `60optind' != ARGC.  */
X
Xstatic enum
X`7B
X  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
X`7D ordering;
X`0C
X#ifdef`09__GNU_LIBRARY__
X#include <string.h>
X#define`09my_index`09strchr
X#define`09my_bcopy(src, dst, n)`09memcpy ((dst), (src), (n))
X#else
X
X/* Avoid depending on library functions or files
X   whose names are inconsistent.  */
X
Xchar *getenv ();
X
Xstatic char *
Xmy_index (string, chr)
X     char *string;
X     int chr;
X`7B
X  while (*string)
X    `7B
X      if (*string == chr)
X`09return string;
X      string++;
X    `7D
X  return 0;
X`7D
X
Xstatic void
Xmy_bcopy (from, to, size)
X     char *from, *to;
X     int size;
X`7B
X  int i;
X  for (i = 0; i < size; i++)
X    to`5Bi`5D = from`5Bi`5D;
X`7D
X#endif`09`09`09`09/* GNU C library.  */
X`0C
X/* Handle permutation of arguments.  */
X
X/* Describe the part of ARGV that contains non-options that have
X   been skipped.  `60first_nonopt' is the index in ARGV of the first of them
V;
X   `60last_nonopt' is the index after the last of them.  */
X
Xstatic int first_nonopt;
Xstatic int last_nonopt;
X
X/* Exchange two adjacent subsequences of ARGV.
X   One subsequence is elements `5Bfirst_nonopt,last_nonopt)
X   which contains all the non-options that have been skipped so far.
X   The other is elements `5Blast_nonopt,optind), which contains all
X   the options processed since those non-options were skipped.
X
X   `60first_nonopt' and `60last_nonopt' are relocated so that they describe
X   the new indices of the non-options in ARGV after they are moved.  */
X
Xstatic void
Xexchange (argv)
X     char **argv;
X`7B
X  int nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *);
X  char **temp = (char **) __alloca (nonopts_size);
X
X  /* Interchange the two blocks of data in ARGV.  */
X
X  my_bcopy (&argv`5Bfirst_nonopt`5D, temp, nonopts_size);
X  my_bcopy (&argv`5Blast_nonopt`5D, &argv`5Bfirst_nonopt`5D,
X`09    (optind - last_nonopt) * sizeof (char *));
X  my_bcopy (temp, &argv`5Bfirst_nonopt + optind - last_nonopt`5D, nonopts_si
Vze);
X
X  /* Update records for the slots the non-options now occupy.  */
X
X  first_nonopt += (optind - last_nonopt);
X  last_nonopt = optind;
X`7D
X`0C
X/* Scan elements of ARGV (whose length is ARGC) for option characters
X   given in OPTSTRING.
X
X   If an element of ARGV starts with '-', and is not exactly "-" or "--",
X   then it is an option element.  The characters of this element
X   (aside from the initial '-') are option characters.  If `60getopt'
X   is called repeatedly, it returns successively each of the option characte
Vrs
X   from each of the option elements.
X
X   If `60getopt' finds another option character, it returns that character,
X   updating `60optind' and `60nextchar' so that the next call to `60getopt'
V can
X   resume the scan with the following option character or ARGV-element.
X
X   If there are no more option characters, `60getopt' returns `60EOF'.
X   Then `60optind' is the index in ARGV of the first ARGV-element
X   that is not an option.  (The ARGV-elements have been permuted
X   so that those that are not options now come last.)
X
X   OPTSTRING is a string containing the legitimate option characters.
X   If an option character is seen that is not listed in OPTSTRING,
X   return '?' after printing an error message.  If you set `60opterr' to
X   zero, the error message is suppressed but we still return '?'.
X
X   If a char in OPTSTRING is followed by a colon, that means it wants an arg
V,
X   so the following text in the same ARGV-element, or the text of the follow
Ving
X   ARGV-element, is returned in `60optarg'.  Two colons mean an option that
X   wants an optional arg; if there is text in the current ARGV-element,
X   it is returned in `60optarg', otherwise `60optarg' is set to zero.
X
X   If OPTSTRING starts with `60-' or `60+', it requests different methods of
X   handling the non-option ARGV-elements.
X   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
X
X   Long-named options begin with `60--' instead of `60-'.
X   Their names may be abbreviated as long as the abbreviation is unique
X   or is an exact match for some defined option.  If they have an
X   argument, it follows the option name in the same ARGV-element, separated
X   from the option name by a `60=', or else the in next ARGV-element.
X   When `60getopt' finds a long-named option, it returns 0 if that option's
X   `60flag' field is nonzero, the value of the option's `60val' field
X   if the `60flag' field is zero.
X
X   The elements of ARGV aren't really const, because we permute them.
X   But we pretend they're const in the prototype to be compatible
X   with other systems.
X
X   LONGOPTS is a vector of `60struct option' terminated by an
X   element containing a name which is zero.
X
X   LONGIND returns the index in LONGOPT of the long-named option found.
X   It is only valid when a long-named option has been found by the most
X   recent call.
X
X   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
X   long-named options.  */
X
Xint
X_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
X     int argc;
X     char *const *argv;
X     const char *optstring;
X     const struct option *longopts;
X     int *longind;
X     int long_only;
X`7B
X  int option_index;
X
X  optarg = 0;
X
X  /* Initialize the internal data when the first call is made.
X     Start processing options with ARGV-element 1 (since ARGV-element 0
X     is the program name); the sequence of previously skipped
X     non-option ARGV-elements is empty.  */
X
X  if (optind == 0)
X    `7B
X      first_nonopt = last_nonopt = optind = 1;
X
X      nextchar = NULL;
X
X      /* Determine how to handle the ordering of options and nonoptions.  */
X
X      if (optstring`5B0`5D == '-')
X`09`7B
X`09  ordering = RETURN_IN_ORDER;
X`09  ++optstring;
X`09`7D
X      else if (optstring`5B0`5D == '+')
X`09`7B
X`09  ordering = REQUIRE_ORDER;
X`09  ++optstring;
X`09`7D
X      else if (getenv ("POSIXLY_CORRECT") != NULL)
X`09ordering = REQUIRE_ORDER;
X      else
X`09ordering = PERMUTE;
X    `7D
X
X  if (nextchar == NULL `7C`7C *nextchar == '\0')
X    `7B
X      if (ordering == PERMUTE)
X`09`7B
X`09  /* If we have just processed some options following some non-options,
X`09     exchange them so that the options come first.  */
X
X`09  if (first_nonopt != last_nonopt && last_nonopt != optind)
X`09    exchange ((char **) argv);
X`09  else if (last_nonopt != optind)
X`09    first_nonopt = optind;
X
X`09  /* Now skip any additional non-options
X`09     and extend the range of non-options previously skipped.  */
X
X`09  while (optind < argc
X`09`09 && (argv`5Boptind`5D`5B0`5D != '-' `7C`7C argv`5Boptind`5D`5B1`5D ==
V '\0')
X#ifdef GETOPT_COMPAT
X`09`09 && (longopts == NULL
X`09`09     `7C`7C argv`5Boptind`5D`5B0`5D != '+' `7C`7C argv`5Boptind`5D`5B1
V`5D == '\0')
X#endif`09`09`09`09/* GETOPT_COMPAT */
X`09`09 )
X`09    optind++;
X`09  last_nonopt = optind;
X`09`7D
X
X      /* Special ARGV-element `60--' means premature end of options.
X`09 Skip it like a null option,
X`09 then exchange with previous non-options as if it were an option,
X`09 then skip everything else like a non-option.  */
X
X      if (optind != argc && !strcmp (argv`5Boptind`5D, "--"))
X`09`7B
X`09  optind++;
X
X`09  if (first_nonopt != last_nonopt && last_nonopt != optind)
X`09    exchange ((char **) argv);
X`09  else if (first_nonopt == last_nonopt)
X`09    first_nonopt = optind;
X`09  last_nonopt = argc;
X
X`09  optind = argc;
X`09`7D
X
X      /* If we have done all the ARGV-elements, stop the scan
X`09 and back over any non-options that we skipped and permuted.  */
X
X      if (optind == argc)
X`09`7B
X`09  /* Set the next-arg-index to point at the non-options
X`09     that we previously skipped, so the caller will digest them.  */
X`09  if (first_nonopt != last_nonopt)
X`09    optind = first_nonopt;
X`09  return EOF;
X`09`7D
X
X      /* If we have come to a non-option and did not permute it,
X`09 either stop the scan or describe it to the caller and pass it by.  */
X
X      if ((argv`5Boptind`5D`5B0`5D != '-' `7C`7C argv`5Boptind`5D`5B1`5D ==
V '\0')
X#ifdef GETOPT_COMPAT
X`09  && (longopts == NULL
X`09      `7C`7C argv`5Boptind`5D`5B0`5D != '+' `7C`7C argv`5Boptind`5D`5B1`5
VD == '\0')
X#endif`09`09`09`09/* GETOPT_COMPAT */
X`09  )
X`09`7B
X`09  if (ordering == REQUIRE_ORDER)
X`09    return EOF;
X`09  optarg = argv`5Boptind++`5D;
X`09  return 1;
X`09`7D
X
X      /* We have found another option-ARGV-element.
X`09 Start decoding its characters.  */
X
X      nextchar = (argv`5Boptind`5D + 1
X`09`09  + (longopts != NULL && argv`5Boptind`5D`5B1`5D == '-'));
X    `7D
X
X  if (longopts != NULL
X      && ((argv`5Boptind`5D`5B0`5D == '-'
X`09   && (argv`5Boptind`5D`5B1`5D == '-' `7C`7C long_only))
X#ifdef GETOPT_COMPAT
X`09  `7C`7C argv`5Boptind`5D`5B0`5D == '+'
X#endif`09`09`09`09/* GETOPT_COMPAT */
X`09  ))
X    `7B
X      const struct option *p;
X      char *s = nextchar;
X      int exact = 0;
X      int ambig = 0;
X      const struct option *pfound = NULL;
X      int indfound;
X
X      while (*s && *s != '=')
X`09s++;
X
X      /* Test all options for either exact match or abbreviated matches.  */
X      for (p = longopts, option_index = 0; p->name;
X`09   p++, option_index++)
X`09if (!strncmp (p->name, nextchar, s - nextchar))
X`09  `7B
X`09    if (s - nextchar == strlen (p->name))
X`09      `7B
X`09`09/* Exact match found.  */
X`09`09pfound = p;
X`09`09indfound = option_index;
X`09`09exact = 1;
X`09`09break;
X`09      `7D
X`09    else if (pfound == NULL)
X`09      `7B
X`09`09/* First nonexact match found.  */
X`09`09pfound = p;
X`09`09indfound = option_index;
X`09      `7D
X`09    else
X`09      /* Second nonexact match found.  */
X`09      ambig = 1;
X`09  `7D
X
X      if (ambig && !exact)
X`09`7B
X`09  if (opterr)
X`09    fprintf (stderr, "%s: option `60%s' is ambiguous\n",
X`09`09     argv`5B0`5D, argv`5Boptind`5D);
X`09  nextchar += strlen (nextchar);
X`09  optind++;
X`09  return '?';
X`09`7D
X
X      if (pfound != NULL)
X`09`7B
X`09  option_index = indfound;
X`09  optind++;
X`09  if (*s)
X`09    `7B
X`09      /* Don't test has_arg with >, because some C compilers don't
X`09`09 allow it to be used on enums. */
X`09      if (pfound->has_arg)
X`09`09optarg = s + 1;
X`09      else
X`09`09`7B
X`09`09  if (opterr)
X`09`09    `7B
X`09`09      if (argv`5Boptind - 1`5D`5B1`5D == '-')
X`09`09`09/* --option */
X`09`09`09fprintf (stderr,
X`09`09`09`09 "%s: option `60--%s' doesn't allow an argument\n",
X`09`09`09`09 argv`5B0`5D, pfound->name);
X`09`09      else
X`09`09`09/* +option or -option */
X`09`09`09fprintf (stderr,
X`09`09`09     "%s: option `60%c%s' doesn't allow an argument\n",
X`09`09`09     argv`5B0`5D, argv`5Boptind - 1`5D`5B0`5D, pfound->name);
X`09`09    `7D
X`09`09  nextchar += strlen (nextchar);
X`09`09  return '?';
X`09`09`7D
X`09    `7D
X`09  else if (pfound->has_arg == 1)
X`09    `7B
X`09      if (optind < argc)
X`09`09optarg = argv`5Boptind++`5D;
X`09      else
X`09`09`7B
X`09`09  if (opterr)
X`09`09    fprintf (stderr, "%s: option `60%s' requires an argument\n",
X`09`09`09     argv`5B0`5D, argv`5Boptind - 1`5D);
X`09`09  nextchar += strlen (nextchar);
X`09`09  return '?';
X`09`09`7D
X`09    `7D
X`09  nextchar += strlen (nextchar);
X`09  if (longind != NULL)
X`09    *longind = option_index;
X`09  if (pfound->flag)
X`09    `7B
X`09      *(pfound->flag) = pfound->val;
X`09      return 0;
X`09    `7D
X`09  return pfound->val;
X`09`7D
X      /* Can't find it as a long option.  If this is not getopt_long_only,
X`09 or the option starts with '--' or is not a valid short
X`09 option, then it's an error.
X`09 Otherwise interpret it as a short option. */
+-+-+-+-+-+-+-+-  END  OF PART 5 +-+-+-+-+-+-+-+-
