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