rosenkra@convex1.convex.com (William Rosencranz) (08/06/90)
---
This is nrchbar, a program to insert changebars in nroff/troff files based
on differences between 2 versions of the file. It works with the nroff I
just posted, v1.10p3. IT WILL ONLY WORK WITH THE NEW NROFF since it needs
the .mc command. I HAVE NOT TESTED THIS WITH MINIX but it works fine under
BSD unix. there are 3 makefiles (sheesh!) so copy Makefile.mnx to Makefile
or use make -f ...
You will need diff(1) to use this program. If you do not have diff, skip
this program. It will be useless. If you do have diff, and have nroff up
to v1.10 p3, then this could be a very handy program, especially with
minix which changes hourly :-). it works with both the -man and -ms
macro packages i just posted.
The version of nrchbar I used was a unix version and had a popen(3) call
to pipe the output of diff to a stream. I have simulated the popen call
in the TOS version. See source file for more info. Note that diff command is
hardwired to /bin/diff (unix,minix) and c:\bin\diff.ttp (TOS) so if your
diff is not that, you need to change the DIFFPROG define in the source.
Enjoy...
-bill rosenkranz
rosenkra%c1yankee@convex.com
------------------------------- cut here ---------------------------------
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# If this archive is complete, you will see the following message at the end:
# "End of shell archive."
#
# Contents:
# MANIFEST README Makefile.mnx Makefile.tos Makefile.unx
# nrchbar.1 nrchbar.c nrchbar.man tests.uu
#
# Wrapped by rosenkra%c1yankee@convex.com on Sun Aug 5 14:45:12 1990
#
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f MANIFEST -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"MANIFEST\"
else
echo shar: Extracting \"MANIFEST\" \(501 characters\)
sed "s/^X//" >MANIFEST <<'END_OF_MANIFEST'
X-rw-r--r-- 1 rosenkra 0 Aug 5 14:44 MANIFEST
X-rw-r--r-- 1 rosenkra 1848 Aug 5 14:17 Makefile.mnx
X-rw-r--r-- 1 rosenkra 1803 Aug 5 14:02 Makefile.tos
X-rw-r--r-- 1 rosenkra 1718 Aug 5 14:07 Makefile.unx
X-rw-r--r-- 1 rosenkra 3197 Aug 5 14:42 README
X-rw-r--r-- 1 rosenkra 2720 Aug 5 13:43 nrchbar.1
X-rw-r--r-- 1 rosenkra 15234 Aug 5 14:00 nrchbar.c
X-rw-r--r-- 1 rosenkra 2747 Aug 5 14:26 nrchbar.man
X-rw-r--r-- 1 rosenkra 9887 Aug 5 14:21 tests.uu
END_OF_MANIFEST
if test 501 -ne `wc -c <MANIFEST`; then
echo shar: \"MANIFEST\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f README -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"README\"
else
echo shar: Extracting \"README\" \(3197 characters\)
sed "s/^X//" >README <<'END_OF_README'
Xbelow is the original README for nrchbar. the install procedure is about
Xthe same, but look at the Makefile to be sure. this is in the archives for
Xcomp.sources.misc, circa 1987.
X
Xthis is a handy little program to put changebars in nroff-style documents,
Xdirectly in the nroff source, based on the diffs between two nroff documents.
Xin invokes /bin/diff directly or will read diff output from stdin. i have
Xused it successfully (under TOS) to generate a large-ish -ms paper with
Xchangebars (about 20 pages).
X
Xi have tested this under TOS and 4.{23}BSD with no problems. i have not
Xtested it under MINIX. it should work fine with the nroff i just posted
X(v1.10p3) and WILL NOT WORK WITH THE ORIGINAL NROFF (0.99) since it did
Xnot have the .mc command. if you do get errors, check the output from
Xminix diff(1) to see that it conforms to real unix. you also need the
Xpopen(3) call to invoke /bin/diff from within nrchbar. if not, you can
Xread the diffs from stdin. see the manpage. look at the makefile for
Xproper target locations for the manpage and executable before you "make
Xinstall". build the executable with "make -f Makefile.mnx all".
X
Xnrchbar.man is nroff source. nrchbar.1 is output of nroff.
X
Xuudecode the tests.uu to get a compressed shar file. unpack this and
Xread the file TESTING. test with:
X
X % nrchbar f1.man f2.man > f12.man
X % nroff -man f12.man
X
Xlet me know if there are any problems...
X
X-bill
Xrosenkra%c1yankee@convex.com
X
X----------------------------------------------------------------------------
X
XThe "nrchbar" program effectively inserts n/troff-style change bar commands
Xinto files which are (presumably) n/troff source. For more information,
Xconsult the man page.
X
XTo install "nrchbar":
X
X1) Inspect "Makefile" for proper destinations (currently,
X "/usr/local/bin" for the binary and "/usr/man/manl" for the man
X page). Correct these if necessary. If "diff" on your system isn't
X "/bin/diff", you'll also need to modify the "DIFFPROG" #define in
X "nrchbar.c". "nrchbar" assumes "getopt" is present, so you'll need
X to contact your friendly neighborhood comp.sources.unix archive if it
X isn't.
X
X2) In the source directory:
X
X % make install
X
X3) If everything goes well, still in the source directory:
X
X % make clean
X
XI claim that this program was written entirely by me, entitling me (with the
Xapproval of my management) to release it into the public domain, which I now
Xdo. However, I make no warrantees, either express or implied, on "nrchbar"
Xor its associated files and I do not assume responsiblity for any damages
Xresulting from its installation or use.
X
XThe software has only been compiled and tested on a Sun 3/50, but I don't
Xexpect any major problems on other UNIX machines, including System V.
X
XIn spite of the disclaimer above, I'd like to hear about bugs and/or feature
Xrequests.
X
XAcknowledgements and thanks to Robert Reed of Tektronix, who wrote the
Xoriginal shell script; and to Jeff Hahs, Ron Lunde, Charlie Mills, and Bill
Xden Beste of TSSI for encouragement, ideas, and testing.
X
X - Bob Lewis
X Test Systems Strategies, Inc.
X 8205 SW Creekside Pl.
X Beaverton, OR 97005
X (503) 643-9281
X
X ...!tektronix!tessi!bobl or bobl@tessi.UUCP
X
END_OF_README
if test 3197 -ne `wc -c <README`; then
echo shar: \"README\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Makefile.mnx -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"Makefile.mnx\"
else
echo shar: Extracting \"Makefile.mnx\" \(1848 characters\)
sed "s/^X//" >Makefile.mnx <<'END_OF_Makefile.mnx'
X# makefile for nrchbar (minix)
X#
X# date: Wed Jul 25 12:45:16 1990
X# version: 1.4
X#
X# NOTE: change SECT, BINDIR and MANDIR as you see fit...
X#
XSECT = l
XO = s
XEXT =
XTARGET = nrchbar$(EXT)
XMANPAGE = nrchbar.$(SECT)
XCATPAGE = nrchbar.cat
XMANSRC = nrchbar.man
XARCFILE = nrchbar.arc
XSHARFILE = nrchbar.shr
XUUEFILE = nrchbar.uue
XHEADERS =
XSRCS = $(HEADERS) nrchbar.c
XOTHERS = README Makefile* $(MANSRC) tests.uu
XDISTFILES = $(OTHERS) $(SRCS)
XOBJS = nrchbar.$O
XCFLAGS = -D_MINIX -D_POSIX_SOURCE
XLDFLAGS = -i
XLIBS =
X# you may need to change these locations...
XBINDIR = /usr/local/bin
XMANDIR = /usr/man/man1
XRUNPARM = f1.man f2.man
XRUNOUT = >test.out
X
X
X# directions...
X#
Xdirections:
X @echo type "make all" to built $(TARGET)
X @echo type "make install" to built/install $(TARGET)
X @echo type "make test" to test $(TARGET)
X @echo type "make clean" to remove objects
X @echo type "make clobber" to remove objects and $(TARGET)
X @echo type "make arc" to make source archive $(ARCFILE)
X @echo type "make shar" to make source shar file $(SHARFILE)
X @echo type "make uue" to make uuencoded $(TARGET) $(UUEFILE)
X
X
X# main target...
X#
Xall: $(TARGET)
X
X$(TARGET): $(OBJS)
X $(CC) $(LDFLAGS) -o $(TARGET) $(OBJS) $(LIBS)
X
X
X# manpage (nothing to do, really)
X#
X
X
X# to run it...
X#
Xtest: $(TARGET)
X $(TARGET) $(RUNPARM) $(RUNOUT)
X
X
X# to install it...
X#
Xinstall: install_bin install_man
X
Xinstall_bin: $(TARGET)
X cp $(TARGET) $(BINDIR)/$(TARGET)
X
Xinstall_man:
X cp $(MANSRC) $(MANDIR)/$(MANPAGE)
X
X
X# others...
X#
Xclean:
X rm $(OBJS) errs $(CATPAGE)
X
Xclobber: clean
X rm $(TARGET) $(MANPAGE)
X
Xarc:
X $(ARC) a $(ARCFILE) $(DISTFILES)
X @echo done making $(ARCFILE)
X
Xuue:
X $(UUENCODE) $(TARGET)
X @echo done making $(UUEFILE)
X
Xshar:
X $(SHAR) $(DISTFILES) >$(SHARFILE)
X @echo done making $(SHARFILE)
X
X
X# dependencies...
X#
Xnrchbar.o: nrchbar.c
X
END_OF_Makefile.mnx
if test 1848 -ne `wc -c <Makefile.mnx`; then
echo shar: \"Makefile.mnx\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Makefile.tos -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"Makefile.tos\"
else
echo shar: Extracting \"Makefile.tos\" \(1803 characters\)
sed "s/^X//" >Makefile.tos <<'END_OF_Makefile.tos'
X# makefile for nrchbar
X#
X# date: Wed Jul 25 12:45:16 1990
X# version: 1.4
X#
XSECT = 1
XTARGET = nrchbar.ttp
XMANPAGE = nrchbar.$(SECT)
XCATPAGE = nrchbar.cat
XMANSRC = nrchbar.man
XARCFILE = nrchbar.arc
XSHARFILE = nrchbar.shr
XUUEFILE = nrchbar.uue
XHEADERS =
XSRCS = $(HEADERS) nrchbar.c
XOTHERS = readme makefile $(MANSRC)
XDISTFILES = $(OTHERS) $(SRCS)
XOBJS = nrchbar.o
XCFLAGS =
XLDFLAGS = -s -nf
XLIBS =
XBINDIR = c:\bin
XMANDIR = c:\man\man1
XRUNPARM = test1.man test2.man
XRUNOUT = >test.out
X
X
X# directions...
X#
Xdirections:
X @echo type "make all" to built $(TARGET)
X @echo type "make install" to built/install $(TARGET)
X @echo type "make test" to test $(TARGET)
X @echo type "make clean" to remove objects
X @echo type "make clobber" to remove objects and $(TARGET)
X @echo type "make arc" to make source archive $(ARCFILE)
X @echo type "make shar" to make source shar file $(SHARFILE)
X @echo type "make uue" to make uuencoded $(TARGET) $(UUEFILE)
X
X
X# main target...
X#
Xall: $(TARGET)
X
X$(TARGET): $(OBJS)
X $(CC) $(LDFLAGS) -o $(TARGET) $(OBJS) $(LIBS)
X
X
X# manpage (use built-in .man.cat rule)...
X#
Xmanpage: $(MANPAGE)
X
X$(MANPAGE): $(CATPAGE)
X entab $(CATPAGE) $(MANPAGE)
X
X$(CATPAGE): $(MANSRC)
X
X
X
X# to run it...
X#
Xtest: $(TARGET)
X $(TARGET) $(RUNPARM) $(RUNOUT)
X
X
X# to install it...
X#
Xinstall: install_bin install_man
X
Xinstall_bin: $(TARGET)
X cp $(TARGET) $(BINDIR)\$(TARGET)
X
Xinstall_man: $(MANPAGE)
X cp $(MANPAGE) $(MANDIR)\$(MANPAGE)
X
X
X# others...
X#
Xclean:
X rm $(OBJS) errs $(CATPAGE)
X
Xclobber: clean
X rm $(TARGET) $(MANPAGE)
X
Xarc:
X $(ARC) a $(ARCFILE) $(DISTFILES)
X @echo done making $(ARCFILE)
X
Xuue:
X $(UUENCODE) $(TARGET)
X @echo done making $(UUEFILE)
X
Xshar:
X $(SHAR) $(DISTFILES) >$(SHARFILE)
X @echo done making $(SHARFILE)
X
X
X# dependencies...
X#
Xnrchbar.o: nrchbar.c
X
END_OF_Makefile.tos
if test 1803 -ne `wc -c <Makefile.tos`; then
echo shar: \"Makefile.tos\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Makefile.unx -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"Makefile.unx\"
else
echo shar: Extracting \"Makefile.unx\" \(1718 characters\)
sed "s/^X//" >Makefile.unx <<'END_OF_Makefile.unx'
X# makefile for nrchbar (unix)
X#
X# date: Wed Jul 25 12:45:16 1990
X# version: 1.4
X#
XSECT = 1
XTARGET = nrchbar
XMANPAGE = nrchbar.$(SECT)
XCATPAGE = nrchbar.cat
XMANSRC = nrchbar.man
XARCFILE = nrchbar.arc
XSHARFILE = nrchbar.shr
XUUEFILE = nrchbar.uue
XHEADERS =
XSRCS = $(HEADERS) nrchbar.c
XOTHERS = README Makefile* $(MANSRC) tests.uue
XDISTFILES = $(OTHERS) $(SRCS)
XOBJS = nrchbar.o
XCFLAGS =
XLDFLAGS =
XLIBS =
XBINDIR = /sales/rosenkra/bin
XMANDIR = /sales/rosenkra/man/man1
XRUNPARM = test1.man test2.man
XRUNOUT = >test.out
X
X
X# directions...
X#
Xdirections:
X @echo type "make all" to built $(TARGET)
X @echo type "make install" to built/install $(TARGET)
X @echo type "make test" to test $(TARGET)
X @echo type "make clean" to remove objects
X @echo type "make clobber" to remove objects and $(TARGET)
X @echo type "make arc" to make source archive $(ARCFILE)
X @echo type "make shar" to make source shar file $(SHARFILE)
X @echo type "make uue" to make uuencoded $(TARGET) $(UUEFILE)
X
X
X# main target...
X#
Xall: $(TARGET)
X
X$(TARGET): $(OBJS)
X $(CC) $(LDFLAGS) -o $(TARGET) $(OBJS) $(LIBS)
X
X
X# manpage (nothing to do, really)
X#
X
X
X# to run it...
X#
Xtest: $(TARGET)
X $(TARGET) $(RUNPARM) $(RUNOUT)
X
X
X# to install it...
X#
Xinstall: install_bin install_man
X
Xinstall_bin: $(TARGET)
X cp $(TARGET) $(BINDIR)/$(TARGET)
X
Xinstall_man:
X cp $(MANSRC) $(MANDIR)/$(MANPAGE)
X
X
X# others...
X#
Xclean:
X rm $(OBJS) errs $(CATPAGE)
X
Xclobber: clean
X rm $(TARGET) $(MANPAGE)
X
Xarc:
X $(ARC) a $(ARCFILE) $(DISTFILES)
X @echo done making $(ARCFILE)
X
Xuue:
X $(UUENCODE) $(TARGET)
X @echo done making $(UUEFILE)
X
Xshar:
X $(SHAR) $(DISTFILES) >$(SHARFILE)
X @echo done making $(SHARFILE)
X
X
X# dependencies...
X#
Xnrchbar.o: nrchbar.c
X
END_OF_Makefile.unx
if test 1718 -ne `wc -c <Makefile.unx`; then
echo shar: \"Makefile.unx\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f nrchbar.1 -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"nrchbar.1\"
else
echo shar: Extracting \"nrchbar.1\" \(2720 characters\)
sed "s/^X//" >nrchbar.1 <<'END_OF_nrchbar.1'
XNAME
X nrchbar - insert n/troff-style change bars in a file
X
XSYNOPSIS
X nrchbar [-a] [-b] [-d] [oldfile] newfile
X
XOPTIONS
X -a Put change bars around all changed sections, even if
X they consist of nothing but *roff commands.
X
X -b Do not insert breaks after changed sections.
X
X -d Show deleted text by preceding it with "[[" and
X following it with "]]".
X
XDESCRIPTION
X Nrchbar inserts commands suitable for nroff(1) or troff(1)
X (hereafter, "*roff") to produce "change bars" denoting
X differences between oldfile and newfile. It sends the result to
X standard output.
X
X If oldfile is defaulted, nrchbar assumes that its standard input
X will contain differences between oldfile and newfile in diff(1)
X format. If oldfile is given, then nrchbar will run diff(1) on
X both files and use the output generated.
X
X By default, nrchbar ignores changes to sections containing
X nothing but *roff commands, which it takes to be any lines
X beginning with ".". You can override this with the -a option.
X
X Nrchbar inserts *roff ".mc" commands to provide the change
X bars. This will place a character to the far right of each
X changed section. This character is a "+" for added sections, a
X "|" for modified sections, and a "-" for deleted sections.
X
X By default, the text of deleted sections does not appear, but
X the -d option will cause it to be inserted, surrounded by "[["
X and "]]".
X
X Also by default, nrchbar puts a break (".br") command after each
X changed section. This is the only way to guarantee that
X deletions and small changes get flagged. The -b option directs
X the program not to insert these breaks. It makes the text look
X more like *roffed newfile, but means that some change bars won't
X appear where they should.
X
XSEE ALSO
X nroff(1), troff(1)
X
XBUGS
X "." is always assumed to denote *roff commands. Nrchbar knows
X nothing about the ".cc" command.
X
X The need for the -b hack would disappear if there were a way to
X tell *roff "Turn off the change bar character at immediately
X after you put out this one.". A horizontal ".wh", perhaps?
X
X The .mc command doesn't always work, especially with
X diversions. This is actually a *roff bug, but you ought to know
X about it.
X
X Nrchbar may mess up tables, lists, or displays. For a really
X polished change bar document, you may want to edit its output
X before sending it to *roff.
X
XAUTHOR
X Unix version by:
X
X Bob Lewis
X Test Systems Strategies, Inc.
X 8205 SW Creekside Pl.
X Beaverton, OR 97005
X (503) 643-9281
X ...!tektronix!tessi!bobl or bobl@tessi.UUCP
X
X Atari ST version by:
X
X Bill Rosenkranz
X rosenkra%c1yankee@convex.com
X
END_OF_nrchbar.1
if test 2720 -ne `wc -c <nrchbar.1`; then
echo shar: \"nrchbar.1\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f nrchbar.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"nrchbar.c\"
else
echo shar: Extracting \"nrchbar.c\" \(15234 characters\)
sed "s/^X//" >nrchbar.c <<'END_OF_nrchbar.c'
X#undef NO_PIPE /* def to eliminate diff (read from stdin instead) */
X#undef USE_MALLOC /* def to malloc space for diff command line */
X
X/*
X * nrchbar - insert nroff change bar commands into a file
X *
X * note: original unix version uses popen ("diff file1 file2", "r")
X * to get diff output. i wrote an ST version of popen(3) to get the
X * job done. uses system(3) and stdio.
X *
X * note: to make this, you need getopt(3), diff(1), system(3), popen(3)
X * and pclose(3) (simulated here for ST), and ungetc(3S). if you use the
X * popen provided, DON'T #define USE_MALLOC!
X */
X
X#include <stdio.h>
X
X#ifdef ALCYON
X# define DIFFPROG "c:\\bin\\diff.ttp"
X#else
X# define DIFFPROG "/bin/diff"
X#endif
X
Xtypedef int bool;
X
X#ifdef TRUE
X# undef TRUE
X#endif
X#ifdef FALSE
X# undef FALSE
X#endif
X#define TRUE 1
X#define FALSE 0
X
X#define ADD 'a'
X#define CHANGE 'c'
X#define DELETE 'd'
X
Xtypedef struct
X{
X int lnOldFrom;
X int lnOldTo;
X int cmd;
X int lnNewFrom;
X int lnNewTo;
X} diffdescr;
X
Xchar *progname;
X#ifdef ALCYON
Xchar *_progname = "nrchbar";
X#endif
Xbool flagAll = FALSE;
Xbool flagBreakAfter = TRUE;
Xbool flagDelete = FALSE;
Xbool debugging = FALSE;
X#ifdef ALCYON
Xchar *version = "nrchbar 1.4 (TOS) 90/07/25 04:51:58 rosenkra";
X#else
X# ifdef _MINIX
Xchar *version = "nrchbar 1.4 (MINIX) 90/07/25 04:51:58 rosenkra";
X# else
Xchar *version = "nrchbar 1.4 (unix) 90/07/25 04:51:58 rosenkra";
X# endif
X#endif
X
X/*
X * forward declarations
X */
XFILE *fopenOrElse ();
Xvoid nrchbar ();
Xvoid skipLinesOrElse ();
Xvoid userErr ();
Xvoid beginChbar ();
Xbool cpLin ();
Xvoid cpLinOrElse ();
Xvoid endChbar ();
Xint getDiff ();
Xbool isRoffCmd ();
Xvoid markDiff ();
X#ifndef NO_PIPE
XFILE *pipeDiffs ();
X#endif
X
X
X#ifndef lint
X# ifdef ALCYON
Xchar *rcsid = "$Header: nrchbar.c,v 1.4(TOS) 90/07/25 04:51:58 rosenkra Exp $";
X# else
Xchar *rcsid = "$Header: nrchbar.c,v 1.3 87/03/31 16:33:16 bobl Exp $";
X# endif
X#endif
X
X
X
X/*------------------------------*/
X/* main */
X/*------------------------------*/
Xmain (argc, argv)
Xint argc;
Xchar *argv[];
X{
X extern int optind;
X extern int getopt ();
X
X int c;
X FILE *fpDiff,
X *fpNew;
X char *fnOld,
X *fnNew;
X
X#ifdef ALCYON
X progname = _progname;
X#else
X progname = argv[0];
X#endif
X
X while ((c = getopt (argc, argv, "abdv")) != EOF)
X {
X switch (c)
X {
X case 'a': /* all changes */
X flagAll = TRUE;
X break;
X
X case 'b': /* no breaks after changes */
X flagBreakAfter = FALSE;
X break;
X
X case 'd': /* show deleted sections */
X flagDelete = TRUE;
X break;
X
X case 'v':
X printf ("%s\n", version);
X exit (0);
X
X case '?':
X default:
X fprintf (stderr, "%s: unknown flag \"-%c\"\n",
X progname, (int) c);
X fprintf (stderr,
X "Usage: %s [-a] [-b] [-d] [oldfile] newfile\n",
X progname);
X exit (1);
X break;
X }
X }
X
X
X /*
X * Depending on the number of files on the command line.
X */
X switch (argc - optind)
X {
X case 1:
X fpDiff = stdin;
X fnNew = argv[optind++];
X fpNew = fopenOrElse (fnNew, "r");
X break;
X
X case 2:
X#ifdef NO_PIPE
X fprintf (stderr,
X "%s: sorry, no pipes. use stdin.\n", progname);
X exit (1);
X#else
X fnOld = argv[optind++];
X fnNew = argv[optind++];
X fpDiff = pipeDiffs (fnOld, fnNew);
X fpNew = fopenOrElse (fnNew, "r");
X#endif
X break;
X
X default:
X fprintf (stderr,
X "Usage: %s [-a] [-b] [-d] [oldfile] newfile\n",
X progname);
X exit (1);
X }
X
X /*
X * Now the real work begins.
X */
X nrchbar (fpDiff, fpNew);
X
X /*
X * clean up and exit...
X */
X if (fpDiff != stdin)
X pclose (fpDiff);
X
X exit (0);
X}
X
X
X
X/*------------------------------*/
X/* beginChbar */
X/*------------------------------*/
Xvoid beginChbar (chMark)
Xint chMark; /* in: use this character */
X{
X
X/*
X * beginChbar -- put out a *roff command to begin a change bar
X */
X
X/*!!! if (flagBreakAfter)
X printf (".br\n");
X*/
X printf (".mc %c\n", chMark);
X return;
X}
X
X
X
X/*------------------------------*/
X/* cpLin */
X/*------------------------------*/
Xbool cpLin (nLn, nSkip, fpFrom)
Xint nLn; /* in: copy this many lines ... */
Xint nSkip; /* in: ... skipping this many characters
X at the start of each one ... */
XFILE *fpFrom; /* in: ... from this file to stdout */
X{
X
X/*
X * cpLin -- copy a given number of lines from one file to standard
X * output
X */
X
X int ch;
X int iSkip;
X
X while (nLn-- > 0)
X {
X for (iSkip = 0; iSkip < nSkip; iSkip++)
X {
X if (getc (fpFrom) == EOF)
X return (FALSE);
X }
X do
X {
X ch = getc (fpFrom);
X if (ch == EOF)
X return (FALSE);
X putchar (ch);
X
X } while (ch != '\n');
X }
X
X return (TRUE);
X}
X
X
X
X/*------------------------------*/
X/* cpLinOrElse */
X/*------------------------------*/
Xvoid cpLinOrElse (nLn, nSkip, fpFrom)
Xint nLn; /* in: copy this many lines ... */
Xint nSkip; /* in: ... skipping this many characters
X at the start of each one ... */
XFILE *fpFrom; /* in: ... from this file to stdout */
X{
X
X/*
X * cpLinOrElse -- copy a given number of lines from one file to
X * standard output; exit if unable
X */
X
X if (!cpLin (nLn, nSkip, fpFrom))
X userErr ("unexpected EOF"); /* exits! */
X return;
X}
X
X
X
X/*------------------------------*/
X/* endChbar */
X/*------------------------------*/
Xvoid endChbar ()
X{
X
X/*
X * endChbar -- put out a *roff command to end a change bar section
X */
X
X /*
X * make sure the previous change bar is visible
X */
X if (flagBreakAfter)
X printf (".br\n");
X
X printf (".mc\n");
X
X return;
X}
X
X
X
X/*------------------------------*/
X/* fopenOrElse */
X/*------------------------------*/
XFILE *fopenOrElse (fname, type)
Xchar *fname; /* in: file name to open */
Xchar *type; /* in: way in which to open fname */
X{
X
X/*
X * fopenOrElse -- open a file or else exit with an error message
X */
X
X FILE *fp;
X
X
X fp = fopen (fname, type);
X
X if (fp == (FILE *) NULL)
X {
X fprintf (stderr, "%s: can't open \"%s\" for mode \"%s\"\n",
X progname, fname, type);
X exit (1);
X }
X return (fp);
X}
X
X
X
X/*------------------------------*/
X/* getDiff */
X/*------------------------------*/
X
X#define EOA 0
X#define START_ACCUM 1
X#define ACCUM 2
X#define SETOLDFROM 3
X#define SETOLDTO 4
X#define SETCMD 5
X#define SETNEWFROM 6
X#define SETNEWTO 7
X#define MXN_ACTION 8
X
Xstruct FSM
X{
X int state;
X char *trig;
X int stateNext;
X int action[MXN_ACTION];
X};
X
Xstruct FSM *fsmCur;
Xstruct FSM fsm[16] =
X{
X/* state trig stateNext action */
X
X {0, "0123456789", 1, {START_ACCUM, EOA} },
X {1, "0123456789", 1, {ACCUM, EOA} },
X {1, ",", 2, {SETOLDFROM, EOA} },
X {1, "acd", 4, {SETOLDFROM, SETOLDTO, SETCMD, EOA} },
X {2, "123456789", 3, {START_ACCUM, EOA} },
X {3, "0123456789", 3, {ACCUM, EOA} },
X {3, "acd", 4, {SETOLDTO, SETCMD, EOA} },
X {4, "0123456789", 5, {START_ACCUM, EOA} },
X {5, "0123456789", 5, {ACCUM, EOA} },
X {5, ",", 6, {SETNEWFROM, EOA} },
X {5, "\n", -1, {SETNEWFROM, SETNEWTO, EOA} },
X {6, "123456789", 7, {START_ACCUM, EOA} },
X {7, "0123456789", 7, {ACCUM, EOA} },
X {7, "\n", -1, {SETNEWTO, EOA} },
X {-1, 0L, -1, {EOA} } /* sentinal */
X};
X
Xint getDiff (fp, ddscr)
XFILE *fp; /* in: file containing "diff" output */
Xdiffdescr *ddscr; /* in: a diff section descriptor */
X{
X
X/*
X * getDiff -- get a "diff" description line
X *
X * diff output looks like this:
X *
X * 12 c 12 range
X * < (hereafter, "*roff") first file
X * --- seperator
X * > (hereafter, "_roff") second file
X *
X * range can be like these:
X *
X * n l n
X * n,n l n
X * n l n,n
X *
X * where n is a number, l is a letter (a, d, c)
X */
X
X
X extern char *index ();
X
X int stateCur = 0;
X int ch,
X accum = 0;
X int *action;
X int len = 0;
X
X do
X {
X /*
X * get a char, skip spaces
X */
XGET_A_CHAR:
X ch = getc (fp);
X if (ch == EOF)
X return (EOF);
X if (ch == ' ' || ch == '\t')
X goto GET_A_CHAR;
X
X
X /*
X * set current fsm to first one
X */
X len++;
X fsmCur = (struct FSM *) &fsm[0];
X
X /*
X * find a state where ch is in trig. don't go past the end
X */
X while (fsmCur->state != -1
X && (fsmCur->state != stateCur
X || index (fsmCur->trig, (char) ch) == (char *) NULL))
X {
X if (debugging == TRUE)
X fprintf (stderr,
X "state loop: fsmCur->state = %d, stateCur = %d, index (|%s|, |%c|)\n",
X fsmCur->state, stateCur, fsmCur->trig, (int) ch);
X
X fsmCur++;
X }
X
X /*
X * if we reached the end, there was no match (error)
X */
X if (fsmCur->state == -1)
X userErr ("illegal syntax in 'diff' output");
X
X /*
X * do the work for each action in this state
X */
X for (action = fsmCur->action; *action != EOA; action++)
X {
X if (debugging == TRUE)
X fprintf (stderr,
X "action loop: action = %d\n", action);
X
X switch (*action)
X {
X case START_ACCUM: /* get a number */
X accum = ch - '0';
X break;
X
X case ACCUM: /* continue on number */
X accum = 10 * accum + (ch - '0');
X break;
X
X case SETCMD: /* a command (a,c,d) */
X ddscr->cmd = ch;
X break;
X
X case SETNEWFROM: /* new, range start */
X ddscr->lnNewFrom = accum;
X break;
X
X case SETNEWTO: /* new, range end */
X ddscr->lnNewTo = accum;
X break;
X
X case SETOLDFROM: /* old, range start */
X ddscr->lnOldFrom = accum;
X break;
X
X case SETOLDTO: /* old, range end */
X ddscr->lnOldTo = accum;
X break;
X }
X }
X
X /*
X * set current state to next state and continue reading
X * the diff "command"
X */
X stateCur = fsmCur->stateNext;
X
X } while (stateCur != -1);
X
X return (len);
X}
X
X
X
X/*------------------------------*/
X/* isRoffCmd */
X/*------------------------------*/
Xbool isRoffCmd (fp)
XFILE *fp; /* in: file to examine for *roff command */
X{
X
X/*
X * isRoffCmd -- return TRUE iff the next line begins with a *roff
X * command
X */
X
X int ch;
X
X if ((ch = getc (fp)) == EOF)
X userErr ("unexpected EOF");
X
X ungetc (ch, fp);
X
X return (ch == '.'); /* don't know about ".cc" command */
X}
X
X
X
X/*------------------------------*/
X/* markDiff */
X/*------------------------------*/
Xvoid markDiff (ddscr, fpDiff, fpNew)
Xdiffdescr *ddscr; /* in: descriptor of the differing sections */
XFILE *fpDiff; /* in: the diff file */
XFILE *fpNew; /* in: the new file */
X{
X
X/*
X * markDiff -- note a changed section of a file; return # of lines
X * copied from fpNew
X */
X
X int nLnNew;
X int nLnOld;
X int nLnNewCopy;
X
X nLnNew = ddscr->lnNewTo - ddscr->lnNewFrom + 1;
X nLnOld = ddscr->lnOldTo - ddscr->lnOldFrom + 1;
X nLnNewCopy = nLnNew;
X
X switch (ddscr->cmd)
X {
X case ADD:
X if (!flagAll)
X {
X while (nLnNewCopy > 0 && isRoffCmd (fpNew))
X {
X cpLinOrElse (1, 0, fpNew);
X nLnNewCopy--;
X }
X }
X if (nLnNewCopy > 0)
X {
X beginChbar ('+');
X cpLinOrElse (nLnNewCopy, 0, fpNew);
X endChbar ();
X }
X skipLinesOrElse (nLnNew, fpDiff);
X return;
X
X case CHANGE:
X if (!flagAll)
X {
X while (nLnNewCopy > 0 && isRoffCmd (fpNew))
X {
X cpLinOrElse (1, 0, fpNew);
X nLnNewCopy--;
X }
X }
X if (nLnNewCopy > 0)
X {
X beginChbar ('|');
X cpLinOrElse (nLnNewCopy, 0, fpNew);
X endChbar ();
X }
X skipLinesOrElse (nLnNew + 1 + nLnOld, fpDiff);
X /* allow for "---" in diff */
X return;
X
X case DELETE:
X beginChbar ('-');
X if (flagDelete)
X {
X putchar ('[');
X putchar ('[');
X putchar ('\n');
X cpLinOrElse (nLnOld, 2, fpDiff);
X /* strip off the "< " */
X putchar (']');
X putchar (']');
X putchar ('\n');
X }
X else
X skipLinesOrElse (nLnOld, fpDiff);
X endChbar ();
X return;
X }
X}
X
X
X
X/*------------------------------*/
X/* nrchbar */
X/*------------------------------*/
Xvoid nrchbar (fpDiff, fpNew)
XFILE *fpDiff; /* in: diff file */
XFILE *fpNew; /* in: original file */
X{
X
X/*
X * nrchbar -- produce *roff change bar file
X */
X
X int lnNew = 1;
X int nLines;
X diffdescr ddscr;
X
X /*
X * read diff "commands"
X */
X while (getDiff (fpDiff, &ddscr) != EOF)
X {
X /*
X * line count from command
X */
X nLines = ddscr.lnNewFrom - lnNew;
X if (ddscr.cmd == DELETE)
X nLines++;
X
X /*
X * copy the lines from new file
X */
X cpLinOrElse (nLines, 0, fpNew);
X
X /*
X * add any change bars...
X */
X markDiff (&ddscr, fpDiff, fpNew);
X lnNew = ddscr.lnNewTo + 1;
X }
X
X /*
X * last line...
X */
X while (cpLin (1, 0, fpNew))
X ;
X
X return;
X}
X
X
X
X#ifndef NO_PIPE
X
X/*------------------------------*/
X/* pipeDiffs */
X/*------------------------------*/
XFILE *pipeDiffs (fnOld, fnNew)
Xchar *fnOld; /* in: old file name */
Xchar *fnNew; /* in: new file name */
X{
X
X/*
X * pipeDiffs -- return a pipe with a diff run on the other end
X */
X
X FILE *popen ();
X char *malloc ();
X
X char *cmd;
X FILE *fpPipe;
X#ifndef USE_MALLOC
X char cmdbuf[1000]; /* need more space to append ">file" */
X#endif
X
X /*
X * make up the diff command...
X */
X#ifdef USE_MALLOC
X cmd = (char *) malloc ((unsigned int) (strlen (DIFFPROG) + 1 + strlen (fnOld) + 1 + strlen (fnNew) + 1));
X#else
X cmd = &cmdbuf[0];
X#endif
X sprintf (cmd, "%s %s %s", DIFFPROG, fnOld, fnNew);
X
X /*
X * do it with a pipe
X */
X fpPipe = popen (cmd, "r");
X if (fpPipe == (FILE *) NULL)
X {
X fprintf (stderr, "%s: can't open pipe for \"%s\"\n",
X progname, cmd);
X exit (1);
X }
X
X /*
X * clean up...
X */
X#ifdef USE_MALLOC
X free (cmd);
X#endif
X
X /*
X * return descriptor of pipe
X */
X return (fpPipe);
X}
X
X
X
X#ifdef ALCYON
X
X/*------------------------------*/
X/* popen */
X/*------------------------------*/
X
X#define PIPE_FILE "__NRCH__.PIP"
X
XFILE *popen (cmd, mode)
Xchar *cmd;
Xchar *mode;
X{
X
X/*
X * simulate pipes on the ST (alcyon). pipe output of cmd to file.
X * return file descriptor of fopen'd file as the pipe descriptor.
X *
X * pclose should close the descriptor, then delete the pipe file...
X * note: abnormal exits to nrchbar may cause the pipe file to linger.
X */
X
X FILE *fp;
X
X /*
X * only read pipes needed here...
X */
X if (*mode == 'r')
X {
X /*
X * delete the "pipe"
X */
X unlink (PIPE_FILE);
X
X /*
X * cat an output redirect to the command
X */
X strcat (cmd, " >");
X strcat (cmd, PIPE_FILE);
X
X /*
X * do it! we could be more selective here: if diff returns
X * 0, there were no diffs so there should be no need to
X * do this.
X */
X system (cmd);
X
X /*
X * now open the "pipe" as a file and return its descriptor
X * don't need to check as NULL is a valid return...
X */
X fp = fopen (PIPE_FILE, "r");
X
X return (fp);
X }
X else
X {
X fprintf (stderr, "%s: sorry, no support for write pipes!\n", progname);
X return ((FILE *) 0);
X }
X}
X
X
X
X/*------------------------------*/
X/* pclose */
X/*------------------------------*/
Xpclose (fp)
XFILE *fp;
X{
X /*
X * close the pipe (open file). delete the pipe file
X */
X close (fp);
X unlink (PIPE_FILE);
X}
X
X#endif /*ALCYON*/
X
X#endif /*!NO_PIPE*/
X
X
X
X/*------------------------------*/
X/* skipLinesOrElse */
X/*------------------------------*/
Xvoid skipLinesOrElse (nLn, fp)
Xint nLn; /* in: skip this many lines ... */
XFILE *fp; /* in: ... in this file */
X{
X
X/*
X * skipLinesOrElse -- skip a given number of lines in a file; exit if
X * errors
X */
X
X int ch;
X
X while (nLn-- > 0)
X {
X do
X {
X if ((ch = getc (fp)) == EOF)
X userErr ("unexpected EOF");
X
X#ifdef ALCYON
X } while (ch != '\n' && ch != '\r');
X#else
X } while (ch != '\n');
X#endif
X }
X return;
X}
X
X
X
X/*------------------------------*/
X/* userErr */
X/*------------------------------*/
Xvoid userErr (msg)
Xchar *msg;
X{
X
X/*
X * userErr -- note an error and politely exude
X */
X
X fprintf (stderr, "%s: %s\n", progname, msg);
X exit (1);
X}
X
END_OF_nrchbar.c
if test 15234 -ne `wc -c <nrchbar.c`; then
echo shar: \"nrchbar.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f nrchbar.man -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"nrchbar.man\"
else
echo shar: Extracting \"nrchbar.man\" \(2747 characters\)
sed "s/^X//" >nrchbar.man <<'END_OF_nrchbar.man'
X.\" $Header: nrchbar.1,v 1.2 87/03/31 16:33:02 bobl Exp $
X.TH NRCHBAR 1
X.SH NAME
Xnrchbar \- insert n/troff-style change bars in a file
X.SH SYNOPSIS
Xnrchbar [\-a] [\-b] [\-d] [oldfile] newfile
X.SH OPTIONS
X.IP \-a
XPut change bars around all changed sections, even if they consist of
Xnothing but *roff commands.
X.IP \-b
XDo not insert breaks after changed sections.
X.IP \-d
XShow deleted text by preceding it with "[[" and following it with "]]".
X.SH DESCRIPTION
XNrchbar
Xinserts commands suitable for
Xnroff(1)
Xor
Xtroff(1)
X(hereafter, "*roff") to produce "change bars" denoting
Xdifferences between oldfile and newfile.
XIt sends the result to standard output.
X.LP
XIf
Xoldfile
Xis defaulted,
Xnrchbar
Xassumes that its standard
Xinput will contain differences between
Xoldfile
Xand
Xnewfile
Xin
Xdiff(1)
Xformat.
XIf
Xoldfile
Xis given, then
Xnrchbar
Xwill run
Xdiff(1)
Xon both files and use the output generated.
X.LP
XBy default, nrchbar ignores changes to sections containing nothing
Xbut *roff commands, which it takes to be any lines beginning with "\.".
XYou can override this with the \-a option.
X.LP
XNrchbar inserts *roff ".mc" commands to provide the change
Xbars.
XThis will place a character to the far right of each changed section.
XThis character is a "+" for added sections, a "|" for
Xmodified sections, and a "-" for deleted sections.
X.LP
XBy default, the text of deleted sections does not appear, but the
X\-d option will cause it to be inserted, surrounded by "[[" and "]]".
X.LP
XAlso by default, nrchbar puts a break (".br") command after each
Xchanged section.
XThis is the only way to guarantee that deletions and small changes
Xget flagged.
XThe \-b option directs the program not to insert these breaks.
XIt makes the text look more like *roffed
Xnewfile, but means that some change bars won't appear where
Xthey should.
X.\".SH PRONUNCIATION
X.\"NERCH-bar
X.\".SH ETYMOLOGY
X.\"NRoff CHange BAR
X.SH "SEE ALSO"
Xnroff(1), troff(1)
X.SH BUGS
X"." is always assumed to denote *roff commands.
XNrchbar knows nothing about the ".cc" command.
X.LP
XThe need for the \-b hack would disappear if there were a way
Xto tell *roff "Turn off the change bar character at
Ximmediately after you put out this one.".
XA horizontal "\.wh", perhaps?
X.LP
XThe \.mc command doesn't always work, especially with diversions.
XThis is actually a *roff bug, but you ought to know about it.
X.LP
XNrchbar may mess up tables, lists, or displays.
XFor a really polished change bar document, you may want to edit
Xits output before sending it to *roff.
X.SH AUTHOR
X.nf
XUnix version by:
X
XBob Lewis
XTest Systems Strategies, Inc.
X8205 SW Creekside Pl.
XBeaverton, OR 97005
X(503) 643-9281
X\&...!tektronix!tessi!bobl or bobl@tessi.UUCP
X
XMINIX and Atari ST version by:
X
XBill Rosenkranz
Xrosenkra%c1yankee@convex.com
X.fi
END_OF_nrchbar.man
if test 2747 -ne `wc -c <nrchbar.man`; then
echo shar: \"nrchbar.man\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f tests.uu -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"tests.uu\"
else
echo shar: Extracting \"tests.uu\" \(9887 characters\)
sed "s/^X//" >tests.uu <<'END_OF_tests.uu'
Xbegin 644 tests.shar.Z
XM'YV0(T*`>"$FC9L7<]`H&`&""IHT<T!`!!$&1,(R;-A0E#/FH9TR+D"`D%*F
XMS9N/%-WDH?/0S1D08LJ8>2.G#`B6$]D8+,/B)IHR;D#4<0,GS)@U"R72@9G'
XM8A@[!E^F66J0SAN*(,RD86,SC!LR-_/`B0I"1,*L6\N("-GPZLDR<N[(F6JS
XM#!Z(=*(F36+&Y\0P'#W:G#CF31LX7.GP!)'G31T0=[9JG%/&)DN;,S.^B>P2
XM1)LR<^:$.=-UZ6400,GH6)@@@8@B7T&\Z7LQX\:.:3ZZ$+$PZ9`W;A0'G[.:
XMH4@J1:902>+D2-88+<S(<$$F35\ST*6[:./U>?3ICI=BW]Y=.W<WO1E>D1,&
XM#IPR8,4TE?.&LILU[(&,89_'1>$VL@4UQ5`@!%''2R#4`$(,-.@00PXZP'##
XM@CGD`$-O4`1!!1(]$&20#B_4,8<<'KH!HH@DUC&&&"#L@!H><-"T5(8;*F#=
XM3:`M%5U#R2W7'`@M5"0""7O$T(<(((300UDMC(&DBY<%I8!(971T54*`Z0#"
XM%9*!X,8;2[TE1PMRT?4B7F1IQ14(7(B`G'+,'=&F`AA11J>5%J&1)0A%X$$'
XM>V/DU5F;;_HH)Y)<H$####F`T!%@1BDFQQQ<I*``96"9]8(76+SP`I(^%!HG
XM"#SP<$(13A#QQ1-&?"%J<R<H@(5#F+VA&6=2923BGV$H%E%%OH;9EQN!B0$8
XM"C&DX(*LLAZ1&U!H<44<LU@D,-YYK8E`4QIG(*FF32A4=%Y1I%E:K7E>9>M&
XM&7=XFQ8(*)A4G5;P/>>"#.;*2L0;9.$T+1:R)E""E\4"!B18UY8WW7D@^(#=
XM=^2A!S`6-%$K,`CS7A=#Q%DMW)W#V4TW;\`#$]N1L7(<W#''/#RLW;P-N^RQ
XMQ+*2MBY[OF*U[AV>>46N39&QY*B>+I6!<D0HR!RQL@3/IE5G4T$V%1JK37PQ
XML4X#R;#2#(,,<7C4PD$?&2J"YI--.V=%$W=T*`;6N*,!/?707I%V-+Q*AZ>L
XM`JBJRJJK/<9I8U_!@K!HHRVL"P(8=XP!I.,\O'H$&%#^A)Y(5.*)I1Q:$AIX
XM<VT*1911:]0;-!J0T=?9'&GH448("FB55&JR]25FF8*^U%&52,E^8^$[*@US
XMD&41:2222C+I9(MG2YDY&E?JR?F677X9YD=CXE[777/D'JU-;0IOW9QUEG$G
XM]'GNV2>O@9(5?LC4C8\HLC+8$`/=@$I*J:68EC7'IIWZ5,S@![-2G2I5JVJ5
XM^,P0*RS$0`:.6I`,9,4#>/VD)F$P@Z1Z(@(5T,<,9A!!"FYR%;&]@6QCL(D(
XM'E4TF`!F#D@B`U#`I!<LM."&LO*!!>%2A@QNL"Q?^&`(1V@5$)@0A2ID(6E<
XM.*D8SC!WLHJ!@BH2`QNP0`8QR&%;<-0]+9H,#2C3HK^,"*DSL`<.J--31&("
XMK3"0089D6!86=)B$I6`P(TU1HY?`U)*7%)$,5SD="*!W!R\6+&5WH,D:YM`3
XM->P**\&2HPY=P`0HR$H&,XB@#')`09C482D>S-I_SD,&1D+F(1U1RDW"4+J(
XM%#$F*6F*3M:UQC*<P2!N(,OI9'7#%FA1#)\$01!%:1A2FO(.J$1=U.C`2K.]
XMLBLJ`<$LS1:36[HAEYW9)19D,"''S6`&G73"(27B!LK(@0X1"24(R[*=Y8W2
XM*Z4DH1'I`Q49GHUN1>,E#N<(`G&>S&`&,2<ZA2E$=K;!G<6$IRM+2,\TV/,T
XM2C0?%FAP/\?1X`:=K&//6GE/Q?A)FF]XPQH\0Q.;Z*1T(%"G&>"C3U_R4Z/<
XMX>AI/+H4-H1TI":IB333@-)A@I"E$Z4!"RZ*,<-Q$@L5=,$4D``"*$CA"4ZH
XM@A.&D`0-)0&JX2R"%(:`A!:$$:D@4"I3BT"%+#3A"4QXPA&R$$XI9(VK=;.)
XM$((@!5G5H*()`B=8K=='3X*RH._\RASDV$LO\I$LP%R*3_L2V%+*L0:-<IS]
XM.KD6)/V%#7<(0QY^%9HZ?`8L?WRB353JJ(0*EK#[U&%E)?(KS&J6LW/P;+U"
XM:SV;++:T;3"F'&V02<G6H)-%5(QM2.NF.L@A*%F#*-&6B#+\10HN%*%#2\5X
XM%>%JY+;%/6[M"/<3?#+78(_*'W1[)2L;X"""-[@06!TRD;\$J@YAP"-62`O,
XM,_0DL8QQC&P.A`;37&4-7^)9&,00'J6@UJ4Z9&]$W$L'^,JW(K>M[WV#V9C'
XM..8,_94G@#=#$0('<RIRO`$$'7<#&G1R*A$)#QR"&9.9Z-0^U8&:?U,JQ`-K
XM$<7[I<.*E]+BDEHD-619YE46NZR^)?`+"QP<%Y?R0/L!27&,<UR32+5`RC5O
XM2IBK$OHVUSD1+#!T0RG*44PW-[D`YR6L<QWL9,<0VLU&-MC#'5EV=Y38I4')
XMP-,8Q!A&O"$5Z4A)6I((FO2DYH$`RUJ.WIZX9!OKP1DN9)J+8L[4O32]ZWU[
XM]@KYV&"G1*=O>NO+G_N\#+_SA"Y1];M!-Z7WW$E5ZE+UTA2G/`4JKG7'@$;^
XMFZW=T$`7A(X$2.BA#*?W192Y(`8LL,."[@4"'-S@!3"8P0MF<+\JZN";$8(@
XM@<6@D3[!`00DD)4+-M3/K2)AKE)84%F0)`)VLQNJ3&!.$7B#!;'V,PA-*(*L
XMBFTP+K2`G`+UT@O^Y+06="\/:XHH$Q<<E(I\2]Q+!<$4LN"$)T!A"DF8PK['
XMN05_AZ$+(.BX5T$N<C*0W%9D^!;(=_;P>D><",D9@A22`(7E8!4+_@0C0,L)
XMEX$V-B*QG<J`U^3BC3L-6>:J&!8(#D*DB_N@(."#K%!PP1YJ$"X<7*P(Y7G$
XMLI5%X4=SHO5JZ`(QR.'I8Y!5QGCHAA36D@YWJ`QRV9#R=\'32^SZEAPU"F-7
XM=K<FL67#C+L'3\"`1<6?E",E+5EOJ*]`5E2H;HXV_L^S+_TA$2D*>\S8GC2&
XMH99M?"-\]F[''LI7CWSMUU4`*36A$9+R.D>D(DWIR.Y!,D>*KZ2XS8YV6?%%
XM-G3_%FLQ)I,PU$'P\.D)OU/V^=A^QN^]4@K0F?D5P\O*(#N6FFT*$YPP&`1C
XMUEEI3=I.S3+`7>[`K_N:[L[RM%Q?8AES.A9<S+;<,UX(39&A&8PO>.6/DUM?
XM`GC>Y4Q74B5Y`1P1P7W,9!!DD7HN@791)ROX=5L_UQ/(E`:IM$S-M%`P`4VR
XMM!.U9$W8]!+:5':6UTZR4EERE`7Z-0;=(29S\5"8UWJH<QH>)QMP<(!N8'\0
XM*'4X]W\\=TX1@5WMA"0_QW4-)8,V$5&[=X(')8$O)$<*IGT:@1A&T17.%2C0
XM%5S=M7\I,Q<8)BRH812H$U%@01GM`QQ2.(/AU6K#)R0KX"TT01&B=X8&F`8(
XMV!-"P@=R:'GR8AUI4"]HJ(.F='="T@)]2'R)(8AWB(`\B`7X1WS[=WQTT!,S
XM91=B*$.+:(=I6$X8\P9FXVCM\1Z`,6&F\1.RXF^'EX-X&!21L7W&1QFJ]$P`
XMUW/)9Q'&11]#`4=,419;L`5(<G<BT`5=L!;BIGM8$`2<=A7R(8G\5XD$4WE&
XM]$F_`A,8-%(HL!9FMW6-11%7ES(]U!&R8H8_UHEKV%Y^9Q/`P09-D5E-441G
XM`%_L$1R5X1/1IXGFUXJ_$AMSP!W;MUR@43/FEQ5L,!JD$4>0UUW^QB)OP(K`
XM`7XU$2CI.$]OP'D`XFA%%%`]=S:R:'8]M$B*!W4^"%,;V%&8"%(B15(Z=5*V
XM)41`98*]AP7MQQ6FZ!D]Y(DL$7US8!A+")`+!QG`<0)+,8H]A$A5)RN7T10)
XMX1AT%Y)2)BN_"'%,Y510)554954WYP1:Q55>!1A2R2=E=59IM5:RX@1NM4YP
XMU4+H)BO$V(0Q:6\69W-.H''U1G-L$B2R`@7!!'8OM!&.$1OQI1'D.(CZV!-E
XM\!%!\3L_T13<QSJV-QL]N&^'U1D3"%BFY5ANV7AI5Y=0<)=BH"]7X6@:>4[6
XM^)&_\HT#R(F$J'AVJ8JR,@6$I(CF-ULGV8QB4R7P$61+(4@B\(O!&!N985.X
XMHDJ\28S&Z'),-05%4`1<4"!,,`5/8'1-ERR6*$3R9V]"4`5'0)?M%(%8L%J7
XMY8ZP)5N@M7JB15#$E%L*I7B\IYEE.4X;=@<1X8`O,6`%=AIK,08(I9Y?\8BT
XM@G?UXF+WM)"#1#I`>7Q@41VBX1Y%*1'<Q4.0`:$5X8Z1N7229QO8107&A5SK
XMI%QQQ419*"G1E9DHB`5ID%NYV2L8T10^!%T5-HUA$DQC!!P@<9Q!,$C;H@?`
XMP4P:L1;()`(]\1YRH"=P,`<_<(R,]Y]K<5!&>)F?"!J\-I2NM5E`*0=K8)AS
XM\!YCD`:!V8YS4QW8PSJ.6*%3R&`.QHY8$6$'4I,O>F$95D3QV6$%!F(D^H3U
XMAHPYUUS<T13/%Q%U\&W,Q&V@T1,ZT3VF-(<*:H6;)4=&,(<5<4=H&B.%^A-@
XMP9<I`TAC(%O!T1,ONJ>0X14SEIO2I9G>B6.(QV,RX6,PIIOR1&1UNIDN4`0`
XMDVL*5&I>@6<Y`@*I-B&)8Q-1]CA49JMN8&51@F7/HVC3@VGHX@9@-CIC!A:"
XM9&:KTSJO8V>S$QMO=CN2-F<_46>^0SBY&CSP4V!]9CR`ECR#MCR5`RV(ICG2
XMHR6,IA&.)B:19B9V@2:=(7S*"AZ?M&F=YJ[JXR>B-BBD]C7].C\SH&JK!BE:
XMZ&K\$VO_,VL"Y#7:46"XAD"Z-JZ?U$!EB6]%(!*R@CDB&XVQ!R2U2)H'P71F
XM8'!T@'`]^:%W\WT.]R[4,G$5=W$9T1;5T1=ET)?YY-A1WQCUQEIBSEH*[5K-WYNUX'G!RU&:W>Q
XM,9,@(1)\EQH3"7B4*$\A*[6$5WUR<'B?M&-L02UI&WE+1K+--4::-QIGY'F@
XMUW!UR!8@H%$@`*E-4:`1`0*/M[-22Y_RQ'J"%)L^FTA62GN/!"RXE[=2^[J^
XM&[S".[S$2[S`*[6_-[AK,A'Z]XRWZ+/-)UO01Q4#%;ED8'CDE'V/R[.OJ!&E
XMU7W?U[=`\;<Q$;ASIW[0!!:&2T[@%[;;.[+TURN7.S%I&XG-2XD]P;E5"X`E
XMU;H1U;I%5(Z$*!(*Z'TC^+XB*[M^)1*WA;4*E;\7F$JJM$HRQ8P>N%.T=+8(
XMC#G5A$NZ-#?%&\(BK+<;+!(J*!(L^!@NB%S8$X.6,8."=!K$TY`Z.+\EW$]`
XM*%!#6%!+NI]9"[=)^,(OVT)2N[<\>S1L,87=:T0%*;<5T88-*T_WE!55"X89
XM5CM40H8W/)B-N(.8,X50+*)_419QZ+5TR(N$F8<4<<,BP(=F_(?THIJ%F1)@
XM<8B)B(]N(\#Z:,.PR[/V6WSX:Y(?]69XS(B=&!&`9#9[M!04P:"E*!*)=<.G
XMH3(XJ(-4Z"BQ.!@S!DNCZ38]$5MRH(M?42_-V)O`>,/":)Q\G+;*N).]>+_]
XMI[\ILV/5Z)&L!"_:*`?<Z*0M"HYD>&A]/+)<;(Y?/(/#-\7KN+KN*!(!'(^0
XM0H\V88^CFK9XK(]TK+7^*)@`&1&D(1X%>08'F<3=Y565W(H0:8!S(,G=94(6
XMN<CRU,D<:1.V#)*(NQ0QY4S=15,B85,IZ9UIFU,FQ5,MZ33U,L(&';Q&/+*&
XM6Y.?X173:Q$\.8`_F4A1VLBD:)00FI3`G+9+B:!L\8L''=+$ZU(B7=(F/;(N
XM1951-555!;4G_=)Y2])2JY7FUI5?"],X+=,XO=/%ZU)D959HI599P--$+;(Z
XM/;)F^59(\*'H!@+$6-0]32UQ>55SJ;,W3#P;7;QZR<@*]Y-^N8LB$9BIJ<=J
XM?)C08ATWG+8:W9AX@<6R6YGIJ5O%ZX-7S2)93;S[XL[P/,^G*:+#O)I6'<Q&
XM#19W/;RPR6&RF<<X\E&].$^X&6,($C4T:,*^B3GPE-92&YR;P:K%68Q\K)P?
XM&P3/^011&[O629TW<=HC1"W4DIW;6=H\"YZM)9X4T5F?-;OG28&7.5@&G=`B
XM2[4I$Y_S.9GUZ6&GJ$+^X</PM,I2^Y\`BC!S*,,LHB='<:!T!WX+>M$.>C8Z
XM%7<Z-:&:)<6^C3G6A9[KE%T<^J`2W5QA/%Z,',+C+1(G^EE<*EPLBIHOFGWW
XM.8,TNAML<:,X.A<ZVGW>ZZ-H`*0W+*1$:J2!G;G=9<)%B#G=*!*)/`<531%3
XMVKJX>Z54DJ55PJ7R18,W#*9P(:;E),[H2!'OU:5I6E`2ML!MRE\S%J?^++7V
XM^6%T8+I0'=)T+=B8`]P]PZ>@X:>`.G2#NE.&VA.("A&*RMLBT:A?6Q&I:WKL
XMF."V`A&42L`^":*?F*F?L:GY]1B>FEG!(4^B*GTYEGTU?L2I^F)`)F.M6F,[
XM/K)T3:M(IK'2]3NYFK"J]F2^VCC`VC)X3JR68ZRH`;#)6K`5>["B(V:E`ZUE
XMICIH1JUK=F=MAJVV$V?;VAETUCMWIN>V)ZX<4ZY_ACR"1FC,$R6'=JR?!J_5
XM`R:/ECV2MCWX^A+Z2FH1XZ_FXVE<QB<"&RFCEC#,.C\R0`,P4%&LUK#[`VN9
XM$K$!5&L;PS`7ZS>U&C&]]FO!YD9PH27+=VS)MFP0Y&S0)FW4MB`V<&TSD&TP
XM\0;<YNO?%F[U1FYFR55-?3_MMF[X+@+P)F_T9F].X+&PUUS^9K4"I[(LZ[+K
XMW9<R^SU?:;,6AW%TZ;,B]W$AMY`DIXHG%WQIL7)YYW[("0),Z[0U1]7O*8V=
XMG("[C8M")ZA>*YUF(']*5[;),G55U\L<I%)ORU`GY'4K1+<O)'8T](!8(+[D
XM]W9Q)[@:OWZ%V_%<07H_)ECWQ+B")T_6B[VG^HC)F_2#@<B`C'QDX'_2&+W/
XM)\UH7O63^W[9M\0%'+[AQW;D:WY'?[["QWY,+U$&H7;A)W_QF^-(*BM_/(FQ
XM[+/\*X#_2_5=C/+@.X*+W$<2&$RD58&GA('*9!HE28M>\8$9W,'7],$LD8+^
XM+2LIC,DL#!<N[!<1$<,*.<,.N8-]_X,F'X0#15P1?H1`?!(.)<0#"(63<HZG
XMWR56Z,0ANH75U84&8\5B&(YE")!RK(8)21C)+L;5*`)E+*!NA,:'KX=EX<9%
XMAP5P'(C+7TYZ")A,<L<8,9O?/UBM__?/:(GY?)*$7/YYG,:>6.'N3)2/C%^7
XMD8HML(J6K/:9/(L6S&K=(E`FRGA1*:MLJ<RSM;Y6QHSR3]>#1CZ+EF&%>8;+
XM3-`NXT]U##4AOW&D_,@:ZYL5,V@BG(9D]JG>T55P9O-(,;RP>P3_K-G=Z4=B
XM[7\))&]FD$9/0@(?Y(R&F;/J$)$&RFE@9^SA(L&ZC`3[XEEI8B7H#PN0))G2
XM_CX*/\,I/H8ET1B"1@;V3=UC:#?IH>VDSY#P)@50JFCV#Z/5!*2TF/($4T)(
XM'T^E6:661O)PSE;J*E_%WOPTL234RM)9Z@MI:8FLI8\WU:`*=VI->`D+;+4N
XM^"L*((;39G'E_!DFQ+3=UAH":FN02281MP7V^'8;:^I,"PDTZ;4BR->\D5_K
XM@/(O";H`0%@%L<!AXQF%#+34IJ9PFU((9"-.<\.4_2;H=BLX6RQ490UO.34G
XMT0:=7![2J4Y'9^9]/-=&EV0;AJ-M8F^VF*?:,@77R<^1(T!.N"T^LG#CCAL[
XMT4]-"@/ZI^ZR+@)4=$M]T\U`)1($A=W"8".L.A'JNY5`I'2A-`)QT5#:);ET
XM%TL5_)C/J)IO*<J^>4(7I5_TFXSB;^OB\R6C`-<Z=E1\82<_*DC!A05WI.Y4
XMDNHN/2P;DI(G9>&$TC%\+56*PX$&+07BT)0@(7&38H\UOP7S*U;<@VF&?>'%
XMX9<8%X8T3("14SCN$0$Y3]6GA$*1$U2FI%"A$R5WJ9A<05I4L@+*8075942N
XMW$6H5#[O4KT!+P<4H%&G"F]D+E15AWLX4$Y5!W(Q-F%5P;DBHE(4CZSB&QBK
XMVIT'7&5[BMVQ\W.+`]!-&4$7,0@=4#!TO.Y=L0E<9VJ01)@A'61&:$BK2:=F
XMK-6E.SR9#B[(&4[7K3P=6=01UV%F``DA8:Y,G?(H-*JN76T9N1BOW!F]TAZ4
XMQGO<NF6EZ\X'LM(2H0;8$2S.2.QH0`TX+^W-83$[_P%`:$W,4(S3[L@LJVN'
XM)("-L-EVLLS;*9N-$>Z>3;29-M7FW&$;&*!MV%VW@1'@1MS(.W-3[_*=NRD+
XM^TXK];N(\^_R3<#K-_\&GJ4L(7+P$DY29#A8H>78&X>'LR(>Q_$X%T]HE9R,
XMA[XX7M+R>/8FY,V<D9>5<EC/07D8$.C4@95'=)0.UG!?%,/RR#QS075XB,T#
XM(FZ+B.@\)#*W8-;/LUM![PS@O9_BM\J/^4H_<V_IO<>FYWN60M^)>J"A<141
XMLT>Y=$SB:7V:*UA<1P$Y@SX7YT$CK*L#A1XXXO2((NJ9A'\DD,R-UR.3QLF&
XMTUVVAW=U#ZQG.[3>\(%EGDR6U3;G@\^B#XXAD6@OF*@]@\CV*.3XLI!Q#T,2
XM+O55]][/A'QYPG#O/2+U%\@$WQD(0&:C\(W(P_>]%I#BHT^-3[%8IOQH@9+)
XM+*I\`?#R8;#R(X(XGT+X3@(Q]*VP6%?ZQ@CJPX$500<R/X=8\DK6R3-O?2$B
XM.C"H5_OJ">YC0E@`B8W$2_;[L%!JE">GP0NE+FZ18=X,\AMK\H_WU<,W1,82
XM4?4S9(0(^[6Q/B0KNA^LG&.&:/R9L53H`44A,B*3L>P2#;*^P"M#(46L?XY,
XM#M2D_(<%5%$Y>TC^3T1H,GG"R6#?`,Q%?\D`-@59>,V&D0)DE,EH&;VR!PCV
XM2I8$K`@4,!M9P!'2C7K9&!)'6."OM2)5*0*["PE<9O!('H&J>I23ED(U0T#7
XM#`;^H[B2SK!`-R-(-1`-_B<"I2B#`@]$9_<$"(8!(3ACX-EEZ$C7*`DN07QF
XM&4[2$U1)`:VGN*12N-`66$/#27K"0T8T2W7Z@M)02I:GA(>0P3*@E*"'1_M*
XM?7`NB1M`&`;RTE[ZCE\-,`W,HJ$(40,C5$PT\WLY)F$AF7`"90HFNBT_7D+/
XMI`E%$R?,F/LP9<C+,<69[E(I/(6)C39]%-L4D7(3G.--"!`XV0KA9`N%AK<\
XM3N-1%SJG7M@C@V$*`(8`$CMIIV*X&]Y0AEN2Y`FW,<.HJ5L:97.1AK*K&MZ3
XM_*3<^A.*Y(:5`;J1+7!8H*K;.+QN"LH<(LWN)J'6H87"$1B*A\'#]'9/Z.&G
XM)"\F"D55!Q6%IMQE?@LF^VTB]#<;11`''(]"B`=.(0ZI]F"D'B=R8U*3,D&!
XMHHHHI6C;AL-2')'%?<1G$1*Y9IDJB0V&Q4$8%[>F8)Q^<5,S[B4J3CH%+F=B
XM>*N)?VJ5X$1"A1<.54_,4C\Q"0K%1T7E6*%1S'+T$%-I*J>H7\8<J#)S4_'Z
XM5,7*Q6+:7%9\<U)AQKBJ>O,5[=RR.HRZRC2>EUZ5%J4,Y%A6;O%R9!E$UV5(
XM8Z/#BY!.+THZBT#I_")JP'2Q;C#JCL)HK>*B^@"AM4$C``;<H!OHQ%U8"A<"
X`
Xend
END_OF_tests.uu
if test 9887 -ne `wc -c <tests.uu`; then
echo shar: \"tests.uu\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0
Bill Rosenkranz |UUCP: {uunet,texsun}!convex!c1yankee!rosenkra
Convex Computer Corp. |ARPA: rosenkra%c1yankee@convex.com