From:	MERC::"uunet!WKUVX1.BITNET!FILESERV-Mgr" 12-JUN-1992 15:22:38.77
To:	galaxy::gleeve
CC:	
Subj:	GREP.08_OF_12

-+-+-+-+-+-+-+-+ START OF PART 8 -+-+-+-+-+-+-+-+
Xthe names of matching files.
X.sk
X.literal
X4.  $ create tmp.tmp
X    search-string1
X    search-string2
X    `5EZ
X    $ fgrep -f tmp.tmp *.c
X.end literal
X.sk
XIn this example, a file containing more than one search string is created
Xand used as input to fgrep.
$ CALL UNPACK [.GREP016]GREP.RNH;1 290734874
$ create 'f'
XThis is a generic INSTALL file for utilities distributions.
XIf this package does not come with, e.g., installable documentation or
Xdata files, please ignore the references to them below.
X
XTo compile this package:
X
X1.  Configure the package for your system.  In the directory that this
Xfile is in, type `60./configure'.  If you're using `60csh' on an old
Xversion of System V, you might need to type `60sh configure' instead to
Xprevent `60csh' from trying to execute `60configure' itself.
X
XThe `60configure' shell script attempts to guess correct values for
Xvarious system-dependent variables used during compilation, and
Xcreates the Makefile(s) (one in each subdirectory of the source
Xdirectory).  In some packages it creates a C header file containing
Xsystem-dependent definitions.  It also creates a file `60config.status'
Xthat you can run in the future to recreate the current configuration.
XRunning `60configure' takes a minute or two.
X
XTo compile the package in a different directory from the one
Xcontaining the source code, you must use GNU make.  `60cd' to the
Xdirectory where you want the object files and executables to go and
Xrun `60configure' with the option `60--srcdir=DIR', where DIR is the
Xdirectory that contains the source code.  Using this option is
Xactually unnecessary if the source code is in the parent directory of
Xthe one in which you are compiling; `60configure' automatically checks
Xfor the source code in `60..' if it does not find it in the current
Xdirectory.
X
XBy default, `60make install' will install the package's files in
X/usr/local/bin, /usr/local/lib, /usr/local/man, etc.  You can specify
Xan installation prefix other than /usr/local by giving `60configure' the
Xoption `60--prefix=PATH'.  Alternately, you can do so by changing the
X`60prefix' variable in the Makefile that `60configure' creates (the
XMakefile in the top-level directory, if the package contains
Xsubdirectories).
X
XYou can specify separate installation prefixes for
Xarchitecture-specific files and architecture-independent files.  If
Xyou give `60configure' the option `60--exec_prefix=PATH', the package will
Xuse PATH as the prefix for installing programs and libraries.  Data
Xfiles and documentation will still use the regular prefix.  Normally,
Xall files are installed using the regular prefix.
X
X`60configure' ignores any other arguments that you give it.
X
XIf your system requires unusual options for compilation or linking
Xthat `60configure' doesn't know about, you can give `60configure' initial
Xvalues for some variables by setting them in the environment.  In
XBourne-compatible shells, you can do that on the command line like
Xthis:
X`09CC='gcc -traditional' DEFS=-D_POSIX_SOURCE ./configure
X
XThe `60make' variables that you might want to override with environment
Xvariables when running `60configure' are:
X
X(For these variables, any value given in the environment overrides the
Xvalue that `60configure' would choose:)
XCC`09`09C compiler program.
X`09`09Default is `60cc', or `60gcc' if `60gcc' is in your PATH.
XINSTALL`09`09Program to use to install files.
X`09`09Default is `60install' if you have it, `60cp' otherwise.
XINCLUDEDIR`09Directory for `60configure' to search for include files.
X`09`09Default is /usr/include.
X
X(For these variables, any value given in the environment is added to
Xthe value that `60configure' chooses:)
XDEFS`09`09Configuration options, in the form '-Dfoo -Dbar ...'
XLIBS`09`09Libraries to link with, in the form '-lfoo -lbar ...'
X
XIf you need to do unusual things to compile the package, we encourage
Xyou to teach `60configure' how to do them and mail the diffs to the
Xaddress given in the README so we can include them in the next
Xrelease.
X
X2.  Type `60make' to compile the package.
X
X3.  Type `60make install' to install programs, data files, and
Xdocumentation.
X
X4.  You can remove the program binaries and object files from the
Xsource directory by typing `60make clean'.  To also remove the
XMakefile(s), the header file containing system-dependent definitions
X(if the package uses one), and `60config.status' (all the files that
X`60configure' created), type `60make distclean'.
X
XThe file `60configure.in' is used as a template to create `60configure' by
Xa program called `60autoconf'.  You will only need it if you want to
Xregenerate `60configure' using a newer version of `60autoconf'.
$ CALL UNPACK [.GREP016]INSTALL.;1 185080853
$ create 'f'
X# Makefile for GNU e?grep
X# Copyright (C) 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
XSHELL = /bin/sh
X
X#### Start of system configuration section. ####
X
Xsrcdir = @srcdir@
X@VPATH@
X
XCC = @CC@
X
XINSTALL = @INSTALL@
XINSTALL_PROGRAM = @INSTALL_PROGRAM@
XINSTALL_DATA = @INSTALL_DATA@
X
X# Things you might add to DEFS:
X# -DSTDC_HEADERS`09If you have ANSI C headers and libraries.
X# -DHAVE_UNISTD_H`09If you have unistd.h.
X# -DUSG`09`09`09If you have System V/ANSI C string
X#`09`09`09and memory functions and headers.
X# -D__CHAR_UNSIGNED__`09If type `60char' is unsigned.
X#`09`09`09gcc defines this automatically.
X
XDEFS = @DEFS@
X
X# Any libraries that are needed, such as to get alloca.
XLIBS = @LIBS@
X
XCDEBUG = -g
XCFLAGS = $(CDEBUG) -I$(srcdir) $(DEFS)
XLDFLAGS = -g
X
Xprefix = /usr/local
Xexec_prefix = $(prefix)
X
X# Prefix for installed program, normally empty or `60g'.
Xbinprefix =`20
X# Prefix for installed man page, normally empty or `60g'.
Xmanprefix =`20
X
X# Where to install executables.
Xbindir = $(exec_prefix)/bin
X
X# Where to put Unix-style manual pages.
Xmandir = $(prefix)/man/man1
X# Extension (not including `60.') for the Unix-style manual page filenames.
Xmanext = 1
X
X#### End of system configuration section. ####
X
XMISC = README INSTALL grep.man COPYING Makefile.in configure configure.in \
X README.cray README.sunos4
XSRCS = grep.c dfa.c regex.c getopt.c alloca.c
XHDRS = dfa.h getopt.h regex.h
XDISTFILES = $(MISC) $(SRCS) $(HDRS)
XTESTFILES = khadafy.lines khadafy.regexp regress.sh scriptgen.awk spencer.te
Vsts
X
XOBJS = dfa.o regex.o getopt.o @ALLOCA@
XGOBJ = ggrep.o
XEOBJ = egrep.o
X
Xall: grep egrep check.done
X
Xinstall: all
X`09$(INSTALL_PROGRAM) grep $(bindir)/$(binprefix)grep
X`09$(INSTALL_PROGRAM) egrep $(bindir)/$(binprefix)egrep
X`09-$(INSTALL_DATA) $(srcdir)/grep.man $(mandir)/$(manprefix)grep.$(manext)
X
Xcheck:
X`09builddir=`60pwd`60; cd $(srcdir)/tests; sh regress.sh $$builddir
X`09touch check.done
X
Xcheck.done: grep egrep
X`09builddir=`60pwd`60; cd $(srcdir)/tests; sh regress.sh $$builddir
X`09touch check.done
X
Xgrep: $(OBJS) $(GOBJ)
X`09$(CC) $(LDFLAGS) -o $@ $(OBJS) $(GOBJ) $(LIBS)
X
Xegrep: $(OBJS) $(EOBJ)
X`09$(CC) $(LDFLAGS) -o $@ $(OBJS) $(EOBJ) $(LIBS)
X
Xggrep.o: grep.c
X`09$(CC) $(CFLAGS) -c $(srcdir)/grep.c
X`09mv grep.o ggrep.o
X
Xegrep.o: grep.c
X`09$(CC) $(CFLAGS) -DEGREP -c $(srcdir)/grep.c
X`09mv grep.o egrep.o
X
XTAGS: $(SRCS)
X`09etags $(SRCS)
X
Xclean:
X`09rm -f grep egrep check.done *.o core tests/core tests/tmp.script \
X`09tests/khadafy.out
X
Xmostlyclean: clean
X
Xdistclean: clean
X`09rm -f Makefile config.status
X
Xrealclean: distclean
X`09rm -f TAGS
X
Xdfa.o egrep.o ggrep.o: dfa.h
Xegrep.o ggrep.o regex.o: regex.h
Xegrep.o ggrep.o: getopt.h
Xregex.o: regex.c regex.h
Xgetopt.o: getopt.h
X
Xdist:
X`09echo grep-`60sed -e '/char version/!d' -e 's/`5B`5E0-9.`5D*\(`5B0-9a-zA-Z
V.`5D*\).*/\1/' -e q < grep.c`60 > .fname
X`09rm -rf `60cat .fname`60
X`09mkdir `60cat .fname`60  `60cat .fname`60/tests
X`09ln $(DISTFILES) `60cat .fname`60
X`09cd tests; ln $(TESTFILES) ../`60cat ../.fname`60/tests
X`09tar chZf `60cat .fname`60.tar.Z `60cat .fname`60
X`09rm -rf `60cat .fname`60 .fname
$ CALL UNPACK [.GREP016]MAKEFILE.IN;1 2000119974
$ create 'f'
XThis README documents GNU e?grep version 1.6.  All bugs reported for
Xprevious versions have been fixed.
X
XSee the file INSTALL for compilation and installation instructions.
X
XSend bug reports to bug-gnu-utils@prep.ai.mit.edu.
X
XGNU e?grep is provided "as is" with no warranty.  The exact terms
Xunder which you may use and (re)distribute this program are detailed
Xin the GNU General Public License, in the file COPYING.
X
XGNU e?grep is based on a fast lazy-state deterministic matcher (about
Xtwice as fast as stock Unix egrep) hybridized with a Boyer-Moore-Gosper
Xsearch for a fixed string that eliminates impossible text from being
Xconsidered by the full regexp matcher without necessarily having to
Xlook at every character.  The result is typically many times faster
Xthan Unix grep or egrep.  (Regular expressions containing backreferencing
Xmay run more slowly, however.)
X
XGNU e?grep is brought to you by the efforts of several people:
X
X`09Mike Haertel wrote the deterministic regexp code and the bulk
X`09of the program.
X
X`09James A. Woods is responsible for the hybridized search strategy
X`09of using Boyer-Moore-Gosper fixed-string search as a filter
X`09before calling the general regexp matcher.
X
X`09Arthur David Olson contributed code that finds fixed strings for
X`09the aforementioned BMG search for a large class of regexps.
X
X`09Richard Stallman wrote the backtracking regexp matcher that is
X`09used for \<digit> backreferences, as well as the getopt that
X`09is provided for 4.2BSD sites.  The backtracking matcher was
X`09originally written for GNU Emacs.
X
X`09D. A. Gwyn wrote the C alloca emulation that is provided so
X`09System V machines can run this program.  (Alloca is used only
X`09by RMS' backtracking matcher, and then only rarely, so there
X`09is no loss if your machine doesn't have a "real" alloca.)
X
X`09Scott Anderson and Henry Spencer designed the regression tests
X`09used in the "regress" script.
X
X`09Paul Placeway wrote the manual page, based on this README.
X
XIf you are interested in improving this program, you may wish to try
Xany of the following:
X
X1.  Replace the fast search loop with a faster search loop.
X    There are several things that could be improved, the most notable
X    of which would be to calculate a minimal delta2 to use.
X
X2.  Make backreferencing \<digit> faster.  Right now, backreferencing is
X    handled by calling the Emacs backtracking matcher to verify the partial
X    match.  This is slow; if the DFA routines could handle backreferencing
X    themselves a speedup on the order of three to four times might occur
X    in those cases where the backtracking matcher is called to verify nearly
X    every line.  Also, some portability problems due to the inclusion of the
X    emacs matcher would be solved because it could then be eliminated.
X    Note that expressions with backreferencing are not true regular
X    expressions, and thus are not equivalent to any DFA.  So this is hard.
X
X3.  Handle POSIX style regexps.  I'm not sure if this could be called an
X    improvement; some of the things on regexps in the POSIX draft I have
X    seen are pretty sickening.  But it would be useful in the interests of
X    conforming to the standard.
X
X4.  Replace the main driver program grep.c with the much cleaner main driver
X    program used in GNU fgrep.
$ CALL UNPACK [.GREP016]README.;1 1292142352
$ create 'f'
X(Message inbox:135)
XDate:    Mon, 17 Oct 88 16:53:33 PDT
XTo:      mike@wheaties.ai.mit.edu
Xcc:      darin%pioneer@eos.arc.nasa.gov, luzmoor@violet.berkeley.edu
XFrom:    James A. Woods <jaw@eos.arc.nasa.gov>
XSubject: README.cray for GNU e?grep
X
XI just sent this out to comp.unix.cray:
X
X-------------------------------------------------------------------
XFrom: jaw@eos.UUCP (James A. Woods)
XNewsgroups: comp.unix.cray
XSubject: GNU e?grep on Cray machines
XMessage-ID: <1750@eos.UUCP>
XDate: 17 Oct 88 23:47:29 GMT
XOrganization: NASA Ames Research Center, California
XLines: 66
X
X# "What comes after silicon?  Oh, gallium arsenide, I'd guess.  And after`20
X   that, there's a thing called indium phosphide."
X`09-- Seymour Cray, Datamation interview, circa 1980
X
X     Now that most Cray software development is done on Crays themselves,`20
Xthanks to Unix, GNU e?grep should come in handy.  Of course, if you're
Xscanning GENBANK for the Human Genome Project at 10 MB/second (the raw
XX/MP Unix I/O rate), you really do need the speed.
X
X     Sample, from one of the Ames Cray 2 machines:
X
X`09stokes> time ./egrep astrian web2`09`09# GNU egrep
X`09alabastrian
X`09Lancastrian
X`09Zoroastrian
X`09Zoroastrianism
X`090.5980u 0.0772s 0:01 35%
X`09stokes> time /usr/bin/egrep astrian web2`09# ATT egrep
X`09alabastrian
X`09Lancastrian
X`09Zoroastrian
X`09Zoroastrianism
X`097.6765u 0.1373s 0:15 49%
X
X(web2 is a 2.4 MB wordlist, standard on BSD Unix.)
X
X     To bring up GNU E?GREP, ftp Mike Haertel's version 1.1 package from
X'prep.ai.mit.edu' or 'ames.arc.nasa.gov'.  Mention -DUSG in the Makefile,
Xand specify`20
X
X`09#define SIGN_EXTEND_CHAR(c) ((c)>(char)127?(c)-256:(c))
X
Xin regex.c. `5BCray characters, like MIPS chars, are unsigned, but the
Xcompiler won't allow ... #define SIGN_EXTEND_CHAR(c) ((signed char) (c))`5D
X`09
X     However, at least on the Cray 2, there's a compiler bug involving the
Xincrement operator in complex expressions, which requires the following
Xmodification (also in regex.c):
X
Xchange
X        m->elems`5Bm->nelem++`5D.constraint `7C= s2->elems`5Bj++`5D.constrai
Vnt;
Xto
X        m->elems`5Bm->nelem`5D.constraint `7C= s2->elems`5Bj`5D.constraint;
X        m->nelem++;
X        j++;
X
XThanks go to Darin Okuyama of NASA ARC for providing this workaround.
X
X-- James A. Woods (ames!jaw)
X   NASA Ames Research Center
X
XP.S. `20
XThough Crays are not at their best pushing bytes, the timing difference
Xis even more exaggerated with heavier regexpr processing, to wit:
X
X`09time ./egrep -i 'as.*Trian' web2
X`09...
X`090.7677u 0.0769s 0:01 44%
Xvs.
X`09time /usr/bin/egrep -i 'as.*Trian' web2
X`09...
X`0916.1327u 0.1379s 0:32 49%
X
Xwhich is a mite unfair given a known System 5 egrep -i gaffe.  You get
Xextra credit for vectorizing the inner loop of the Boyer/Moore/Gosper
Xcode, though changing all chars to ints might help also.
$ CALL UNPACK [.GREP016]README.CRAY;1 892804966
$ create 'f'
X`5B N.B. This bug strikes on a Sun 3 running SunOS 4 with the cc -O4 option
X  as well as on the sparc.  -Mike `5D
X
XDate:    Fri, 24 Feb 89 15:36:40 -0600
XTo:      mike@wheaties.ai.mit.edu
XFrom:    Dave Cohrs <dave@cs.wisc.edu>
XSubject: bug + fix in gnu grep 1.2 (from prep.ai.mit.edu)
X
XI tried installing the GNU grep 1.2 on a Sun4 running 4.0.1 and
X"Spencer test #36" failed.  After some experimenting, I found and
Xfixed the bug.  Well, actually, the bug in the the C compiler, but
XI managed a workaround.
X
XDescription:
X
XThe Sun4 4.0.1 C compiler with -O doesn't generate the correct for
Xstatements of the form
X`09if("string")
X`09`09x;
X`09else
X`09`09y;
XTo be exact, "y;" gets executed, while "x;" should.  This causes the
X#define FETCH() to fail for test #36.
X
XFix:
X
XIn an #ifdef sparc in dfa.c, I made two versions of FETCH, FETCH0() and
Xthe regular FETCH().  The former takes only one argument, the latter
Xexpects its 2nd argument to contain a non-nil string.  This removes
Xthe need to test the constant strings, and the compiler bug isn't
Xexercised.  I then changed the one instance of FETCH() with a nil
Xsecond argument to be FETCH0() instead.
X
Xdave cohrs
X
X===================================================================
XRCS file: RCS/dfa.c,v
Xretrieving revision 1.1
Xdiff -c -r1.1 dfa.c
X*** /tmp/,RCSt1a05930`09Fri Feb 24 15:32:33 1989
X--- dfa.c`09Fri Feb 24 15:23:34 1989
X***************
X*** 285,293 ****
X--- 285,315 ----
X  `09`09`09`09   is turned off). */
X `20
X  /* Note that characters become unsigned here. */
X+ #ifdef sparc
X+ /*
X+  * Sun4 4.0.1 C compiler can't compare constant strings correctly.
X+  * e.g. if("test") `7B x; `7D else `7B y; `7D
X+  * the compiler will not generate code to execute `7B x; `7D, but
X+  * executes `7B y; `7D instead.
X+  */
X+ #define FETCH0(c)   `09`09      \
X+   `7B`09`09`09   `09      \
X+     if (! lexleft)`09   `09      \
X+       return _END;`09   `09      \
X+     (c) = (unsigned char) *lexptr++;  \
X+     --lexleft;`09`09   `09      \
X+   `7D
X  #define FETCH(c, eoferr)   `09      \
X    `7B`09`09`09   `09      \
X      if (! lexleft)`09   `09      \
X+       regerror(eoferr);  `09      \
X+     (c) = (unsigned char) *lexptr++;  \
X+     --lexleft;`09`09   `09      \
X+   `7D
X+ #else
X+ #define FETCH(c, eoferr)   `09      \
X+   `7B`09`09`09   `09      \
X+     if (! lexleft)`09   `09      \
X        if (eoferr)`09   `09      \
X  `09regerror(eoferr);  `09      \
X        else`09`09   `09      \
X***************
X*** 295,300 ****
X--- 317,323 ----
X      (c) = (unsigned char) *lexptr++;  \
X      --lexleft;`09`09   `09      \
X    `7D
X+ #endif sparc
X `20
X  static _token
X  lex()
X***************
X*** 303,309 ****
X--- 326,336 ----
X    int invert;
X    _charset cset;
X `20
X+ #ifdef sparc
X+   FETCH0(c);
X+ #else
X    FETCH(c, (char *) 0);
X+ #endif sparc
X    switch (c)
X      `7B
X      case '`5E':
$ CALL UNPACK [.GREP016]README.SUNOS4;1 91893192
$ create 'f'
X/* Extended regular expression matching and search library.
X   Copyright (C) 1985, 1989 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
X
X   In other words, you are welcome to use, share and improve this program.
X   You are forbidden to forbid anyone else to use, share and improve
X   what you give them.   Help stamp out software-hoarding!  */
X
X
X/* To test, compile with -Dtest.
X This Dtestable feature turns this into a self-contained program
X which reads a pattern, describes how it compiles,
X then reads a string and searches for it.  */
X
X/* AIX requires this to be the first thing in the file. */
X#ifdef __GNUC__
X#undef alloca
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
X#ifdef emacs
X
X/* The `60emacs' switch turns on certain special matching commands
X that make sense only in emacs. */
X
X#include "config.h"
X#include "lisp.h"
X#include "buffer.h"
X#include "syntax.h"
X
X#else  /* not emacs */
X
X#if defined(USG) `7C`7C defined(STDC_HEADERS) `7C`7C defined(VAXC)
X#include <string.h>
X#ifndef bcopy
X#define bcopy(s,d,n)`09memcpy((d),(s),(n))
X#endif
X#ifndef bcmp
X#define bcmp(s1,s2,n)`09memcmp((s1),(s2),(n))
X#endif
X#ifndef bzero
X#define bzero(s,n)`09memset((s),0,(n))
X#endif
X#endif
X
X#ifdef STDC_HEADERS
X#include <stdlib.h>
X#else
Xchar *malloc ();
X#endif
X
X/*
X * Define the syntax stuff, so we can do the \<...\> things.
X */
X
X#ifndef Sword /* must be non-zero in some of the tests below... */
X#define Sword 1
X#endif
X
X#define SYNTAX(c) re_syntax_table`5Bc`5D
X
X#ifdef SYNTAX_TABLE
X
Xchar *re_syntax_table;
X
X#else
X
Xstatic char re_syntax_table`5B256`5D;
X
Xstatic void
Xinit_syntax_once ()
X`7B
X   register int c;
X   static int done = 0;
X
X   if (done)
X     return;
X
X   bzero (re_syntax_table, sizeof re_syntax_table);
X
X   for (c = 'a'; c <= 'z'; c++)
X     re_syntax_table`5Bc`5D = Sword;
X
X   for (c = 'A'; c <= 'Z'; c++)
X     re_syntax_table`5Bc`5D = Sword;
X
X   for (c = '0'; c <= '9'; c++)
X     re_syntax_table`5Bc`5D = Sword;
X
X   done = 1;
X`7D
X
X#endif /* SYNTAX_TABLE */
X#endif /* not emacs */
X
X#include "regex.h"
X
X/* Number of failure points to allocate space for initially,
X when matching.  If this number is exceeded, more space is allocated,
X so it is not a hard limit.  */
X
X#ifndef NFAILURES
X#define NFAILURES 80
X#endif /* NFAILURES */
X
X/* width of a byte in bits */
X
X#define BYTEWIDTH 8
X
X#ifndef SIGN_EXTEND_CHAR
X#ifdef __CHAR_UNSIGNED__
X#define SIGN_EXTEND_CHAR(c) ((c)>(char)127?(c)-256:(c))
X#else
X#define SIGN_EXTEND_CHAR(x) (x)
X#endif
X#endif
X`0C
Xstatic int obscure_syntax = 0;
X
X/* Specify the precise syntax of regexp for compilation.
X   This provides for compatibility for various utilities
X   which historically have different, incompatible syntaxes.
X
X   The argument SYNTAX is a bit-mask containing the two bits
X   RE_NO_BK_PARENS and RE_NO_BK_VBAR.  */
X
Xint
Xre_set_syntax (syntax)
X     int syntax;
X`7B
X  int ret;
X
X  ret = obscure_syntax;
X  obscure_syntax = syntax;
X  return ret;
X`7D
X`0C
X/* re_compile_pattern takes a regular-expression string
X   and converts it into a buffer full of byte commands for matching.
X
X  PATTERN   is the address of the pattern string
X  SIZE      is the length of it.
X  BUFP`09    is a  struct re_pattern_buffer *  which points to the info
X`09    on where to store the byte commands.
X`09    This structure contains a  char *  which points to the
X`09    actual space, which should have been obtained with malloc.
X`09    re_compile_pattern may use  realloc  to grow the buffer space.
X
X  The number of bytes of commands can be found out by looking in
X  the  struct re_pattern_buffer  that bufp pointed to,
X  after re_compile_pattern returns.
X*/
X
X#define PATPUSH(ch) (*b++ = (char) (ch))
X
X#define PATFETCH(c) \
X `7Bif (p == pend) goto end_of_pattern; \
X  c = * (unsigned char *) p++; \
X  if (translate) c = translate`5Bc`5D; `7D
X
X#define PATFETCH_RAW(c) \
X `7Bif (p == pend) goto end_of_pattern; \
X  c = * (unsigned char *) p++; `7D
X
X#define PATUNFETCH p--
X
X#define EXTEND_BUFFER \
X  `7B char *old_buffer = bufp->buffer; \
X    if (bufp->allocated == (1<<16)) goto too_big; \
X    bufp->allocated *= 2; \
X    if (bufp->allocated > (1<<16)) bufp->allocated = (1<<16); \
X    if (!(bufp->buffer = (char *) realloc (bufp->buffer, bufp->allocated)))
V \
X      goto memory_exhausted; \
X    c = bufp->buffer - old_buffer; \
X    b += c; \
X    if (fixup_jump) \
X      fixup_jump += c; \
X    if (laststart) \
X      laststart += c; \
X    begalt += c; \
X    if (pending_exact) \
X      pending_exact += c; \
X  `7D
X
Xstatic void store_jump (), insert_jump ();
X
Xchar *
Xre_compile_pattern (pattern, size, bufp)
X     char *pattern;
X     int size;
X     struct re_pattern_buffer *bufp;
X`7B
X  register char *b = bufp->buffer;
X  register char *p = pattern;
X  char *pend = pattern + size;
X  register unsigned c, c1;
X  char *p1;
X  unsigned char *translate = (unsigned char *) bufp->translate;
X
X  /* address of the count-byte of the most recently inserted "exactn" comman
Vd.
X    This makes it possible to tell whether a new exact-match character
X    can be added to that command or requires a new "exactn" command. */
X    `20
X  char *pending_exact = 0;
X
X  /* address of the place where a forward-jump should go
X    to the end of the containing expression.
X    Each alternative of an "or", except the last, ends with a forward-jump
X    of this sort. */
X
X  char *fixup_jump = 0;
X
X  /* address of start of the most recently finished expression.
X    This tells postfix * where to find the start of its operand. */
X
X  char *laststart = 0;
X
X  /* In processing a repeat, 1 means zero matches is allowed */
X
X  char zero_times_ok;
X
X  /* In processing a repeat, 1 means many matches is allowed */
X
X  char many_times_ok;
X
X  /* address of beginning of regexp, or inside of last \( */
X
X  char *begalt = b;
X
X  /* Stack of information saved by \( and restored by \).
X     Four stack elements are pushed by each \(:
X       First, the value of b.
X       Second, the value of fixup_jump.
X       Third, the value of regnum.
X       Fourth, the value of begalt.  */
X
X  int stackb`5B40`5D;
X  int *stackp = stackb;
X  int *stacke = stackb + 40;
X  int *stackt;
X
X  /* Counts \('s as they are encountered.  Remembered for the matching \),
X     where it becomes the "register number" to put in the stop_memory comman
Vd */
X
X  int regnum = 1;
X
X  bufp->fastmap_accurate = 0;
X
X#ifndef emacs
X#ifndef SYNTAX_TABLE
X  /*
X   * Initialize the syntax table.
X   */
X   init_syntax_once();
X#endif
X#endif
X
X  if (bufp->allocated == 0)
X    `7B
X      bufp->allocated = 28;
X      if (bufp->buffer)
X`09/* EXTEND_BUFFER loses when bufp->allocated is 0 */
X`09bufp->buffer = (char *) realloc (bufp->buffer, 28);
X      else
X`09/* Caller did not allocate a buffer.  Do it for him */
X`09bufp->buffer = (char *) malloc (28);
X      if (!bufp->buffer) goto memory_exhausted;
X      begalt = b = bufp->buffer;
X    `7D
X
X  while (p != pend)
X    `7B
X      if (b - bufp->buffer > bufp->allocated - 10)
X`09/* Note that EXTEND_BUFFER clobbers c */
X`09EXTEND_BUFFER;
X
X      PATFETCH (c);
X
X      switch (c)
X`09`7B
X`09case '$':
X`09  if (obscure_syntax & RE_TIGHT_VBAR)
X`09    `7B
X`09      if (! (obscure_syntax & RE_CONTEXT_INDEP_OPS) && p != pend)
X`09`09goto normal_char;
X`09      /* Make operand of last vbar end before this `60$'.  */
X`09      if (fixup_jump)
X`09`09store_jump (fixup_jump, jump, b);
X`09      fixup_jump = 0;
X`09      PATPUSH (endline);
X`09      break;
X`09    `7D
X
X`09  /* $ means succeed if at end of line, but only in special contexts.
X`09    If randomly in the middle of a pattern, it is a normal character. */
X`09  if (p == pend `7C`7C *p == '\n'
X`09      `7C`7C (obscure_syntax & RE_CONTEXT_INDEP_OPS)
X`09      `7C`7C (obscure_syntax & RE_NO_BK_PARENS
X`09`09  ? *p == ')'
X`09`09  : *p == '\\' && p`5B1`5D == ')')
X`09      `7C`7C (obscure_syntax & RE_NO_BK_VBAR
X`09`09  ? *p == '`7C'
X`09`09  : *p == '\\' && p`5B1`5D == '`7C'))
X`09    `7B
X`09      PATPUSH (endline);
X`09      break;
X`09    `7D
X`09  goto normal_char;
X
X`09case '`5E':
X`09  /* `5E means succeed if at beg of line, but only if no preceding patter
Vn. */
X
X`09  if (laststart && p`5B-2`5D != '\n'
X`09      && ! (obscure_syntax & RE_CONTEXT_INDEP_OPS))
X`09    goto normal_char;
X`09  if (obscure_syntax & RE_TIGHT_VBAR)
X`09    `7B
X`09      if (p != pattern + 1
X`09`09  && ! (obscure_syntax & RE_CONTEXT_INDEP_OPS))
X`09`09goto normal_char;
X`09      PATPUSH (begline);
X`09      begalt = b;
X`09    `7D
X`09  else
X`09    PATPUSH (begline);
X`09  break;
X
X`09case '+':
X`09case '?':
X`09  if (obscure_syntax & RE_BK_PLUS_QM)
X`09    goto normal_char;
X`09handle_plus:
X`09case '*':
X`09  /* If there is no previous pattern, char not special. */
X`09  if (!laststart && ! (obscure_syntax & RE_CONTEXT_INDEP_OPS))
X`09    goto normal_char;
X`09  /* If there is a sequence of repetition chars,
X`09     collapse it down to equivalent to just one.  */
X`09  zero_times_ok = 0;
X`09  many_times_ok = 0;
X`09  while (1)
X`09    `7B
X`09      zero_times_ok `7C= c != '+';
X`09      many_times_ok `7C= c != '?';
X`09      if (p == pend)
X`09`09break;
X`09      PATFETCH (c);
X`09      if (c == '*')
X`09`09;
X`09      else if (!(obscure_syntax & RE_BK_PLUS_QM)
X`09`09       && (c == '+' `7C`7C c == '?'))
X`09`09;
X`09      else if ((obscure_syntax & RE_BK_PLUS_QM)
X`09`09       && c == '\\')
X`09`09`7B
X`09`09  int c1;
X`09`09  PATFETCH (c1);
X`09`09  if (!(c1 == '+' `7C`7C c1 == '?'))
X`09`09    `7B
X`09`09      PATUNFETCH;
X`09`09      PATUNFETCH;
X`09`09      break;
X`09`09    `7D
X`09`09  c = c1;
X`09`09`7D
+-+-+-+-+-+-+-+-  END  OF PART 8 +-+-+-+-+-+-+-+-
