[comp.sources.unix] v16i068: Spiff, find approximate differences in files, Part02/04

rsalz@uunet.uu.net (Rich Salz) (11/12/88)

Submitted-by: Daniel W Nachbar <daniel@wind.bellcore.com>
Posting-number: Volume 16, Issue 68
Archive-name: spiff/part02

#! /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
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 2 (of 4)."
# Contents:  Makefile comment.c compare.c line.c line.h output.c
#   spiff.c tol.c visual.c
# Wrapped by rsalz@papaya.bbn.com on Fri Nov 11 13:12:24 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(4147 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X#
X#	START OF LOCAL CONFIGURATION INFORMATION
X#	change the following lines to reflect your local environment
X#
X
X#
X#	name of the directory into which the binary should be installed
X#		used only when you use  'make install'
X#
XINSDIR=/usr/tmp
X
X#
X#	choose one from each of 1) 2) and 3) below
X#
X
X#
X#	1) SELECTION OF OPERATING SYSTEM VARIETY
X#		choose a) b) or c)
X#
X# a) for BSD derivitives, enable the following line
XOSFLAG=
X
X# b) for XENIX systems, enable the following line
X#OSFLAG=-DXENIX
X
X# b) for other A.T. and T. derivitives, enable the following line
X#OSFLAG=-DATT
X
X#
X# 	2) SELECTION OF TERMINAL CONTROL LIBRARY
X#		choose either of a) b) or c)
X#
X# a) if you use termcap, enable the following lines
XTFLAG=-DM_TERMCAP
XTLIB=termcap
X
X# b) if you are using terminfo on a XENIX machine, enable the following lines
X#TFLAG=-DM_TERMINFO
X#TLIB=tinfo
X
X# c) if you use terminfo on any other type of machine,
X#    enable the following lines
X#TFLAG=-DM_TERMINFO
X#TLIB=curses
X
X#
X#	3) SELECTION OF WINDOW MANAGER AVAILABILITY
X#
X# if you have the Bellcore's MGR window manager, enable the following lines
X#VISFLAG=-DMGR
X#VISLIB=/usr/public/pkg/mgr/lib/libmgr.a
X#MGRINCDIR=-I/usr/public/pkg/mgr/include
X#MGRINCS=$(MGRINC)/dump.h $(MGRINC)/term.h $(MGRINC)/restart.h $(MGRINC)/window.h
X
X#
X#	END OF LOCAL CONFIGRATION INFORMATION, the rest of this
X#	file may be modified only at great risk
X#		-- caveat hackor
X#
X
X#                        Copyright (c) 1988 Bellcore
X#                            All Rights Reserved
X#       Permission is granted to copy or use this program, EXCEPT that it
X#       may not be sold for profit, the copyright notice must be reproduced
X#       on copies, and credit should be given to Bellcore where it is due.
X#       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
X#
X
XCC=cc
XOBJ= spiff.o output.o compare.o float.o strings.o exact.o miller.o parse.o command.o comment.o tol.o line.o token.o floatrep.o misc.o visual.o
XCFILES= spiff.c output.c compare.c float.c strings.c exact.c miller.c parse.c command.c comment.c tol.c line.c floatrep.c token.c misc.c visual.c
XHFILES=misc.h strings.h line.h float.h floatrep.h tol.h command.h comment.h token.h edit.h parse.h compare.h flagdefs.h exact.h miller.h visual.h output.h
XOTHER=README Makefile Sample.1 Sample.2 Sample.3 Sample.4 paper.ms paper.out
XMANPAGE=spiff.1
X
XCFLAGS=-O $(OSFLAG) $(TFLAG) $(VISFLAG)
X
Xdefault: spiff
X
Xspiff: $(OBJ)
X	$(CC) $(CFLAGS) -o spiff $(OBJ) $(VISLIB) -l$(TLIB)
X
Xspiff.o: spiff.c misc.h line.h token.h tol.h command.h edit.h parse.h compare.h flagdefs.h exact.h miller.h visual.h
X
Xvisual.o: visual.c misc.h visual.h $(MGRINCS)
X	$(CC) -c $(CFLAGS) $(MGRINCDIR) visual.c
X
Xmisc.o: misc.c visual.h misc.h
X
Xparse.o:  parse.c misc.h line.h command.h float.h tol.h comment.h parse.h token.h flagdefs.h
X	@echo compiler may report 4 statement not reached warning messages for parse.c
X	$(CC) $(CFLAGS) -c parse.c
X
Xcommand.o: command.c float.h tol.h misc.h
X
Xcomment.o: comment.c misc.h comment.h
X
Xtol.o: tol.c tol.h float.h
X
Xoutput.o: output.c output.h misc.h edit.h flagdefs.h
X
Xcompare.o: compare.c misc.h strings.h float.h tol.h token.h line.h compare.h flagdefs.h
X	@echo compiler may report 1 statement not reached warning message for compare.c
X	$(CC) $(CFLAGS) -c compare.c
X
Xfloat.o: float.c misc.h strings.h float.h floatrep.h
X
Xfloatrep.o: floatrep.c misc.h strings.h floatrep.h
X
Xstrings.o: strings.c  misc.h strings.h
X
Xexact.o: exact.c exact.h misc.h edit.h
X
Xmiller.o: miller.c miller.h misc.h edit.h token.h
X
Xtoken.o: token.c token.h misc.h
X
Xline.o: line.c line.h misc.h
X
Xclean:
X	rm -f *.o
Xclobber: clean
X	rm -f spiff
Xci:
X	ci -l -q  '-m $(CIMSG)' $(CFILES) $(HFILES) $(OTHER) $(MANPAGE)
Xcol:
X	co -l  $(CFILES) $(HFILES) $(OTHER) $(MANPAGE)
Xcirev:
X	ci -l -r$(REV)  '-m $(CIMSG)' $(CFILES) $(HFILES) $(OTHER) $(MANPAGE)
Xcirel:
X	ci -l -q  -sRel  $(CFILES) $(HFILES) $(OTHER) $(MANPAGE)
Xlint: 
X	lint  $(CFLAGS) $(CFILES)
Xcpio:
X	for i in $(CFILES) $(HFILES) $(OTHER) $(MANPAGE); do echo $$i; done | cpio -ocv  > spiff.cpio
X
Xcmd:
X	-$(CMD) $(CFILES) $(HFILES) $(OTHER) $(MANPAGE)
Xinstall:
X	mv spiff $(INSDIR)/bin
X	cp $(MANPAGE) $(INSDIR)/man/man1
X	
END_OF_FILE
if test 4147 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'comment.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'comment.c'\"
else
echo shar: Extracting \"'comment.c'\" \(4943 characters\)
sed "s/^X//" >'comment.c' <<'END_OF_FILE'
X/*                        Copyright (c) 1988 Bellcore
X**                            All Rights Reserved
X**       Permission is granted to copy or use this program, EXCEPT that it
X**       may not be sold for profit, the copyright notice must be reproduced
X**       on copies, and credit should be given to Bellcore where it is due.
X**       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
X*/
X
X
X#ifndef lint
Xstatic char rcsid[]= "$Header: comment.c,v 1.1 88/09/15 11:33:58 daniel Rel $";
X#endif
X
X
X#include "misc.h"
X#include "comment.h"
X#include "strings.h"
X
X/*
X**	storage for the comment specifiers that can appear
X**		anywhere on a line
X*/
Xstatic int _W_nextcom = 0;
X_W_comstruct _W_coms[_W_COMMAX];
X
X/*
X**	storage for comment specifiers that are examined only at the
X**		beginning of each line
X*/
Xstatic int _W_nextbol = 0;
X_W_bolstruct _W_bols[_W_BOLMAX];
X
X/*
X**	storage for delimiters of literal strings
X*/
Xstatic int _W_nextlit = 0;
X_W_litstruct _W_lits[_W_LITMAX];
X
X/*
X**	storage for characters to specify beginning and end of line
X**	in the comment and literal commands
X*/
Xchar _W_bolchar = '^';
Xchar _W_eolchar = '$';
X
X
X/*
X**	build up a list of comment delimiters
X*/
Xvoid
XW_addcom(str,nestflag)
Xchar *str;
Xint nestflag;
X{
X	/*
X	**	check for comments that begin at the beginning of line
X	*/
X	if (*str ==  _W_bolchar)
X	{
X		if (_W_nextbol >= _W_BOLMAX)
X			Z_fatal("too many beginning of line comment delimiter sets");
X
X		str++;	/*skip the bol char */
X		S_wordcpy(_W_bols[_W_nextbol].begin,str);
X
X		S_nextword(&str);
X
X		if (*str == _W_eolchar)
X		{
X			(void) strcpy(_W_bols[_W_nextbol].end,"\n");
X		}
X		else
X		{
X			S_wordcpy(_W_bols[_W_nextbol].end,str);
X		}
X
X		S_nextword(&str);
X		S_wordcpy(_W_bols[_W_nextbol].escape,str);
X
X		/*
X		**
X		*/
X		if (nestflag)
X			Z_complain("begining of line comment won't nest");
X
X		_W_nextbol++;
X	}
X	else
X	{
X		if (_W_nextcom >= _W_COMMAX)
X			Z_fatal("too many comment delimiter sets");
X
X		S_wordcpy(_W_coms[_W_nextcom].begin,str);
X
X		S_nextword(&str);
X
X		if (*str == _W_eolchar)
X		{
X			(void) strcpy(_W_coms[_W_nextbol].end,"\n");
X		}
X		else
X		{
X			S_wordcpy(_W_coms[_W_nextbol].end,str);
X		}
X
X		S_nextword(&str);
X		S_wordcpy(_W_coms[_W_nextcom].escape,str);
X
X		_W_coms[_W_nextcom].nestbit = nestflag;
X
X		_W_nextcom++;
X	}
X	return;
X}
X
X
X/*
X**	clear the comment delimiter storage
X*/
Xvoid
XW_clearcoms()
X{
X	_W_nextcom = 0;
X	_W_nextbol = 0;
X	return;
X}
X
X/*
X**	build up the list of literal delimiters
X*/
Xvoid
XW_addlit(str)
Xchar *str;
X{
X	if (_W_nextlit >= _W_LITMAX)
X		Z_fatal("too many literal delimiter sets");
X
X	S_wordcpy(_W_lits[_W_nextlit].begin,str);
X
X	S_nextword(&str);
X	S_wordcpy(_W_lits[_W_nextlit].end,str);
X
X	S_nextword(&str);
X	S_wordcpy(_W_lits[_W_nextlit].escape,str);
X
X	_W_nextlit++;
X	return;
X}
X
X/*
X**	clear the literal delimiter storage
X*/
Xvoid
XW_clearlits()
X{
X	_W_nextlit = 0;
X	return;
X}
X
X
X
Xstatic _W_bolstruct bol_scratch;
X
Xstatic void
X_W_copybol(to,from)
XW_bol to,from;
X{
X	(void) strcpy(to->begin,from->begin);
X	(void) strcpy(to->end,from->end);
X	(void) strcpy(to->escape,from->escape);
X}
X
XW_bol
XW_isbol(str)
Xchar *str;
X{
X	int i;
X
X	for(i=0;i<_W_nextbol;i++)
X	{
X		if(!S_wordcmp(str,_W_bols[i].begin))
X		{
X			_W_copybol(&bol_scratch,&_W_bols[i]);
X			return(&bol_scratch);
X		}
X	}
X	return(W_BOLNULL);
X}
X
XW_is_bol(ptr)
XW_bol ptr;
X{
X	int i;
X
X	for(i=0;i<_W_nextbol;i++)
X	{
X		if(!S_wordcmp(ptr->begin,_W_bols[i].begin) &&
X			!S_wordcmp(ptr->end,_W_bols[i].end) &&
X			!S_wordcmp(ptr->escape,_W_bols[i].escape))
X		{
X			return(1);
X		}
X
X	}
X	return(0);
X}
X
X
Xstatic _W_litstruct lit_scratch;
X
Xstatic void
X_W_copylit(to,from)
XW_lit to,from;
X{
X	(void) strcpy(to->begin,from->begin);
X	(void) strcpy(to->end,from->end);
X	(void) strcpy(to->escape,from->escape);
X}
X
XW_lit
XW_islit(str)
Xchar *str;
X{
X	int i;
X
X	for(i=0;i<_W_nextlit;i++)
X	{
X		if(!S_wordcmp(str,_W_lits[i].begin))
X		{
X			_W_copylit(&lit_scratch,&_W_lits[i]);
X			return(&lit_scratch);
X		}
X	}
X	return(W_LITNULL);
X}
X
XW_is_lit(ptr)
XW_lit ptr;
X{
X	int i;
X
X	for(i=0;i<_W_nextlit;i++)
X	{
X		if(!S_wordcmp(ptr->begin,_W_lits[i].begin) &&
X			!S_wordcmp(ptr->end,_W_lits[i].end) &&
X			!S_wordcmp(ptr->escape,_W_lits[i].escape))
X		{
X			return(1);
X		}
X
X	}
X	return(0);
X}
X
Xstatic _W_comstruct com_scratch;
X
Xstatic void
X_W_copycom(to,from)
XW_com to,from;
X{
X	(void) strcpy(to->begin,from->begin);
X	(void) strcpy(to->end,from->end);
X	(void) strcpy(to->escape,from->escape);
X	to->nestbit = from->nestbit;
X}
X
XW_com
XW_iscom(str)
Xchar *str;
X{
X	int i;
X
X	for(i=0;i<_W_nextcom;i++)
X	{
X		if(!S_wordcmp(str,_W_coms[i].begin))
X		{
X			_W_copycom(&com_scratch,&_W_coms[i]);
X			return(&com_scratch);
X		}
X	}
X	return(W_COMNULL);
X}
X
XW_is_com(ptr)
XW_com ptr;
X{
X	int i;
X
X	for(i=0;i<_W_nextcom;i++)
X	{
X		if(!S_wordcmp(ptr->begin,_W_coms[i].begin) &&
X			!S_wordcmp(ptr->end,_W_coms[i].end) &&
X			!S_wordcmp(ptr->escape,_W_coms[i].escape) &&
X			ptr->nestbit == _W_coms[i].nestbit)
X		{
X			return(1);
X		}
X
X	}
X	return(0);
X}
X
XW_is_nesting(ptr)
XW_com ptr;
X{
X	return(ptr->nestbit);
X}
END_OF_FILE
if test 4943 -ne `wc -c <'comment.c'`; then
    echo shar: \"'comment.c'\" unpacked with wrong size!
fi
# end of 'comment.c'
fi
if test -f 'compare.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'compare.c'\"
else
echo shar: Extracting \"'compare.c'\" \(4024 characters\)
sed "s/^X//" >'compare.c' <<'END_OF_FILE'
X/*                        Copyright (c) 1988 Bellcore
X**                            All Rights Reserved
X**       Permission is granted to copy or use this program, EXCEPT that it
X**       may not be sold for profit, the copyright notice must be reproduced
X**       on copies, and credit should be given to Bellcore where it is due.
X**       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
X*/
X
X
X#ifndef lint
Xstatic char rcsid[]= "$Header: compare.c,v 1.1 88/09/15 11:33:53 daniel Rel $";
X#endif
X
X#include "misc.h"
X#include "flagdefs.h"
X#include "tol.h"
X#include "token.h"
X#include "line.h"
X#include "float.h"
X#include "compare.h"
X
X#include <ctype.h>
X
XX_com(a,b,flags)
Xint a,b,flags;
X{
X	K_token atmp,btmp;
X
X	atmp = K_gettoken(0,a);
X	btmp = K_gettoken(1,b);
X	if(flags & U_BYTE_COMPARE)
X	{
X		return(_X_strcmp(K_gettext(atmp),K_gettext(btmp),flags));
X	}
X	else
X	{
X		return(_X_cmptokens(atmp,btmp,flags));
X	}
X#ifndef lint 
X	Z_fatal("this line should never be reached in com");
X	return(-1);	/* Z_fatal never returns, but i need a this line
X				here to stop lint from complaining */
X#endif
X}
X
X/*
X**	same as strcmp() except that case can be optionally ignored
X*/
Xstatic int
X_X_strcmp(s1,s2,flags)
Xchar *s1,*s2;
Xint flags;
X{
X	if (flags & U_NO_CASE)
X	{
X		
X		for (;('\0' != s1) && ('\0' !=  *s2);s1++,s2++)
X		{
X			if(isalpha(*s1) && isalpha(*s2))
X			{
X				if(tolower(*s1) != tolower(*s2))
X				{
X					return(1);
X				}
X			}
X			else
X			{
X				if(*s1!=*s2)
X				{
X					return(1);
X				}
X			}
X		}
X		return(*s1 != *s2);
X	}
X	else
X	{
X		return(strcmp(s1,s2));
X	}
X}
X
X
X/*
X**	routine to compare two tokens
X*/
Xstatic int
X_X_cmptokens(p1,p2,flags)
XK_token p1, p2;
Xint flags;
X{
X	if (K_gettype(p1) !=  K_gettype(p2))
X	{
X		return(1);
X	}
X
X	switch (K_gettype(p1))
X	{
X		case K_LIT:
X			return(_X_strcmp(K_gettext(p1),K_gettext(p2),flags));
X		case K_FLO_NUM:
X			return(_X_floatdiff(K_getfloat(p1),
X					   K_getfloat(p2),
X					   T_picktol(K_gettol(p1),
X						     K_gettol(p2))));
X		default:
X			Z_fatal("fell off switch in _X_cmptokens");
X			return(-1);	/* Z_fatal never returns, but i need a this line
X						here to stop lint from complaining */
X	}
X
X}
X
X/*
X**	compare two F_floats using a tolerance
X*/
Xstatic int
X_X_floatdiff(p1,p2,the_tol)
XF_float p1,p2;
XT_tol the_tol;
X{
X	F_float diff, float_tmp;
X	T_tol tol_tmp;
X
X	/*
X	** 	check for null tolerance list
X	*/
X	if (T_isnull(the_tol))
X	{
X		Z_fatal("_X_floatdiff called with a null tolerance");
X	}
X
X	/*
X	**	look for an easy answer. i.e -- check
X	**		to see if any of the tolerances are of type T_IGNORE
X	**		or if the numbers are too small to exceed an absolute
X	**		tolerance.
X	**		if so, return immediately
X	*/
X	for(tol_tmp=the_tol; !(T_isnull(tol_tmp)) ;tol_tmp=T_getnext(tol_tmp))
X	{
X		if ((T_IGNORE == T_gettype(tol_tmp)) || 
X			/*
X			**	take a look at the exponents before you bother
X			**	with the mantissas
X			*/
X			((T_ABSOLUTE == T_gettype(tol_tmp))
X				   && !F_zerofloat(T_getfloat(tol_tmp))
X				   && (F_getexp(p1) <
X					F_getexp(T_getfloat(tol_tmp))-1)
X				   && (F_getexp(p2) <
X					F_getexp(T_getfloat(tol_tmp))-1)))
X		{
X				return(0);
X		}
X	}
X
X	
X	/*
X	**	ok, we're going to have to do some arithmetic, so
X	**		first find the magnitude of the difference
X	*/
X	if (F_getsign(p1) != F_getsign(p2))
X	{
X		diff = F_floatmagadd(p1,p2);
X	}
X	else
X	{
X		diff = F_floatsub(p1,p2);
X	}
X
X	/*
X	**	now check to see if the difference exceeds any tolerance
X	*/
X	for(tol_tmp=the_tol; !(T_isnull(tol_tmp)) ;tol_tmp=T_getnext(tol_tmp))
X	{
X		float_tmp = T_getfloat(tol_tmp);
X
X		if (T_gettype(tol_tmp) == T_ABSOLUTE)
X		{
X			/* do nothing */
X		}
X		else if (T_gettype(tol_tmp) == T_RELATIVE)
X		{
X			if (F_floatcmp(p1,p2) > 0)
X			{
X				float_tmp = F_floatmul(p1, float_tmp);
X			}
X			else
X			{
X				float_tmp = F_floatmul(p2, float_tmp);
X			}
X		}
X		else
X		{
X			Z_fatal("bad value for type of tolerance in floatdiff");
X		}
X		/*
X		**	if we pass this tolerance, then we're done
X		*/
X		if (F_floatcmp(diff,float_tmp) <= 0)
X		{
X			return(0);
X		}
X	}
X	/*
X	**	all of the tolerances were exceeded
X	*/
X	return(1);
X}
END_OF_FILE
if test 4024 -ne `wc -c <'compare.c'`; then
    echo shar: \"'compare.c'\" unpacked with wrong size!
fi
# end of 'compare.c'
fi
if test -f 'line.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'line.c'\"
else
echo shar: Extracting \"'line.c'\" \(3570 characters\)
sed "s/^X//" >'line.c' <<'END_OF_FILE'
X/*                        Copyright (c) 1988 Bellcore
X**                            All Rights Reserved
X**       Permission is granted to copy or use this program, EXCEPT that it
X**       may not be sold for profit, the copyright notice must be reproduced
X**       on copies, and credit should be given to Bellcore where it is due.
X**       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
X*/
X
X
X#ifndef lint
Xstatic char rcsid[]= "$Header: line.c,v 1.1 88/09/15 11:34:00 daniel Rel $";
X#endif
X
X#include <stdio.h>
X#include "misc.h"
X#include "token.h"
X#include "line.h"
X
Xchar *_L_al[_L_MAXLINES];  /* storage for lines */
Xchar *_L_bl[_L_MAXLINES];
X
Xint   _L_ai[_L_MAXLINES];  /* index from token line number to first token */
Xint   _L_bi[_L_MAXLINES];
X
Xint   _L_ac[_L_MAXLINES];  /* count of tokens on this token line */
Xint   _L_bc[_L_MAXLINES];
X
Xint   _L_arlm;		/* count of real lines in the file */
Xint   _L_brlm;
X
Xint   _L_aclm;		/* count of content lines in the file */
Xint   _L_bclm;
X
Xint   _L_atlm;		/* count of token lines in the file */
Xint   _L_btlm;
X
Xint   _L_aclindex[_L_MAXLINES]; /* mapping from content lines to real lines*/
Xint   _L_bclindex[_L_MAXLINES]; 
X
Xint   _L_atlindex[_L_MAXLINES]; /*mapping from token lines to content lines */
Xint   _L_btlindex[_L_MAXLINES];
X
X
Xstatic void
X_L_setrline(file,X,str)
Xint file;
Xint X;
Xchar *str;
X{
X	if (file)
X	{
X		S_savestr(&_L_bl[X],str);
X	}
X	else
X	{
X		S_savestr(&_L_al[X],str);
X	}
X	return;
X}
X/*
X**	returns 1 if we reached the end of file
X**	returns 0 if there is more to do
X**
X**	stores data and sets maximum counts
X*/
XL_init_file(fnumber,fname)
Xint fnumber;
Xchar *fname;
X{
X	extern char *fgets();
X	FILE *fp;
X	static char buf[Z_LINELEN+2];	/* +2 is to leave room for us to add
X						a newline if we need to */
X	int ret_val = 1;
X	int tmplen;
X
X	if ((fp = fopen(fname,"r")) == (FILE*) NULL)
X	{
X		(void) sprintf(Z_err_buf, "Cannot open file %s.\n",fname);
X		Z_fatal(Z_err_buf);
X	}
X
X	/*
X	**	clear the line count
X	*/
X	_L_setrlmx(fnumber,0);
X
X	/*
X	**	read in the entire file
X	*/
X	while (fgets(buf,Z_LINELEN+1,fp) != (char *) NULL)
X	{
X		tmplen = strlen(buf);
X		if (tmplen <= 0)
X		{
X			(void) sprintf(Z_err_buf,
X			  "fatal error -- got 0 length line %d in file %s\n",
X				L_getrlmax(fnumber)+1,
X				fname);
X			Z_fatal(Z_err_buf);
X		}
X		else if (tmplen > Z_LINELEN)
X		{
X			(void) sprintf(Z_err_buf,
X  "got fatally long line %d in file %s length is %d, must be a bug\n",
X				L_getrlmax(fnumber)+1,
X				fname,tmplen);
X			Z_fatal(Z_err_buf);
X		}
X		/*
X		**	look for newline as last character
X		*/
X		if ('\n' != buf[tmplen-1])
X		{
X			/*
X			**	did we run out room in the buffer?
X			*/
X			if (tmplen == Z_LINELEN)
X			{
X			(void) sprintf(Z_err_buf,
X	"line %d too long in file %s, newline added after %d characters\n",
X				L_getrlmax(fnumber)+1,
X				fname,Z_LINELEN);
X			Z_complain(Z_err_buf);
X			}
X			else
X			{
X			(void) sprintf(Z_err_buf,
X	"didn't find a newline at end of line %d in file %s, added one\n",
X				L_getrlmax(fnumber)+1,
X				fname);
X			Z_complain(Z_err_buf);
X			}
X
X			buf[tmplen] = '\n';
X			buf[tmplen+1] = '\0';
X		}
X
X		_L_setrline(fnumber,L_getrlmax(fnumber),buf);
X
X		if (L_getrlmax(fnumber) >= _L_MAXLINES-1)
X		{
X			(void) sprintf(Z_err_buf,
X	"warning -- ran out of space reading %s, truncated to %d lines\n",
X				fname,_L_MAXLINES);
X			Z_complain(Z_err_buf);
X			ret_val= 0;
X			break;
X		}
X		else
X		{
X			/*
X			**	increment the line count
X			*/
X			_L_incrlmx(fnumber);
X		}
X
X	}
X
X	(void) fclose(fp);
X	/*
X	**	reset line numbers
X	*/
X	L_setclmax(fnumber,0);
X	L_settlmax(fnumber,0);
X
X	return(ret_val);
X}
X
END_OF_FILE
if test 3570 -ne `wc -c <'line.c'`; then
    echo shar: \"'line.c'\" unpacked with wrong size!
fi
# end of 'line.c'
fi
if test -f 'line.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'line.h'\"
else
echo shar: Extracting \"'line.h'\" \(3621 characters\)
sed "s/^X//" >'line.h' <<'END_OF_FILE'
X/*                        Copyright (c) 1988 Bellcore
X**                            All Rights Reserved
X**       Permission is granted to copy or use this program, EXCEPT that it
X**       may not be sold for profit, the copyright notice must be reproduced
X**       on copies, and credit should be given to Bellcore where it is due.
X**       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
X*/
X
X
X#ifndef L_INCLUDED
X
X#define _L_MAXLINES	10000
X
X/*
X**	oh god, is this an ugly implementation.
X**	I really should have a two dimensional array of structures
X**		the history of the current arrangement is too long
X**		and ugly to record here.
X**		Someday when I have too much time on my hands . . .
X*/
X
Xextern char *_L_al[];	/* storage for text in first file */
Xextern char *_L_bl[];	/* storage for text in second file */
X
Xextern int _L_ai[];	/* pointer from token line to first token */
Xextern int _L_bi[];
X
Xextern int _L_ac[];	/* number of tokens on a given token line */
Xextern int _L_bc[];
X
Xextern int _L_aclindex[]; /* mapping from content lines to real lines */
Xextern int _L_bclindex[];
X
Xextern int _L_atlindex[]; /* mapping from lines with tokens to content lines */
Xextern int _L_btlindex[];
X
Xextern int _L_arlm;	/* count of real lines */
Xextern int _L_brlm;
X
Xextern int _L_aclm;	/* count of content lines */
Xextern int _L_bclm;
X
Xextern int _L_atlm;	/* count of lines with tokens */
Xextern int _L_btlm;
X
X/*
X**	routines to set up mappings from token lines to content lines
X**	  and from content lines to real lines
X*/
X#define L_setclindex(file,content,real) (file?(_L_bclindex[content]=real):\
X					     (_L_aclindex[content]=real))
X
X#define L_settlindex(file,token,content) (file?(_L_btlindex[token]=content):\
X					      (_L_atlindex[token]=content))
X/*
X**	get line number X from file
X*/
X#define L_getrline(file, X)	 (file?(_L_bl[X]):(_L_al[X]))
X#define L_getcline(file, X)	 (file?(_L_bl[_L_bclindex[X]]):\
X				       (_L_al[_L_aclindex[X]]))
X#define L_gettline(file, X)	 (file?(_L_bl[_L_bclindex[_L_btlindex[X]]]):\
X				       (_L_al[_L_aclindex[_L_atlindex[X]]]))
X
X#define L_cl2rl(file, X)	 (file?(_L_bclindex[X]):\
X				       (_L_aclindex[X]))
X#define L_tl2cl(file, X)	 (file?(_L_btlindex[X]):\
X				       (_L_atlindex[X]))
X#define L_tl2rl(file, X)	 (file?(_L_bclindex[_L_btlindex[X]]):\
X				       (_L_aclindex[_L_atlindex[X]]))
X
X/*
X**	get number of first token on line X of the file
X*/
X#define L_getindex(file,X)	(file?(_L_bi[X]):(_L_ai[X]))
X
X/*
X**	get count of number of tokens on line X of first file
X*/
X#define L_getcount(file,X)	(file?(_L_bc[X]):(_L_ac[X]))
X
X/*
X**	save number of first token for line X of file
X*/
X#define L_setindex(file,index,value)	(file?(_L_bi[index]=value):(_L_ai[index]=value))
X/*
X**	save count of tokens on line X of file
X*/
X#define L_setcount(file,index,value)	(file?(_L_bc[index]=value):(_L_ac[index]=value))
X#define	L_inccount(file,index)		(file?(_L_bc[index]++):(_L_ac[index]++))
X
X/*
X**	retrieve line and token counts
X*/
X#define L_getrlmax(file)	(file?_L_brlm:_L_arlm)
X#define L_getclmax(file)	(file?_L_bclm:_L_aclm)
X#define L_gettlmax(file)	(file?_L_btlm:_L_atlm)
X
X/*
X**	set line and token counts
X*/
X#define _L_setrlmx(file,value)	(file?(_L_brlm=(value)):(_L_arlm=(value)))
X#define L_setclmax(file,value)	(file?(_L_bclm=(value)):(_L_aclm=(value)))
X#define L_settlmax(file,value)	(file?(_L_btlm=(value)):(_L_atlm=(value)))
X
X/*
X**	increment line and token counts
X*/
X#define	_L_incrlmx(file)		(file?(_L_brlm++):(_L_arlm++))
X#define	L_incclmax(file)		(file?(_L_bclm++):(_L_aclm++))
X#define	L_inctlmax(file)		(file?(_L_btlm++):(_L_atlm++))
X
X#define L_INCLUDED
X#endif
END_OF_FILE
if test 3621 -ne `wc -c <'line.h'`; then
    echo shar: \"'line.h'\" unpacked with wrong size!
fi
# end of 'line.h'
fi
if test -f 'output.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'output.c'\"
else
echo shar: Extracting \"'output.c'\" \(10536 characters\)
sed "s/^X//" >'output.c' <<'END_OF_FILE'
X/*                        Copyright (c) 1988 Bellcore
X**                            All Rights Reserved
X**       Permission is granted to copy or use this program, EXCEPT that it
X**       may not be sold for profit, the copyright notice must be reproduced
X**       on copies, and credit should be given to Bellcore where it is due.
X**       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
X*/
X
X
X#ifndef lint
Xstatic char rcsid[]= "$Header: output.c,v 1.1 88/09/15 11:33:52 daniel Rel $";
X#endif
X
X#include <stdio.h>
X
X#ifdef M_TERMINFO
X#include <curses.h>
X#include <term.h>
X#endif
X
X#ifdef M_TERMCAP
X#ifdef XENIX
X#include <tcap.h>
X#endif
X#endif
X
X#include "misc.h"
X#include "flagdefs.h"
X#include "edit.h"
X#include "line.h"
X#include "token.h"
X
Xstatic int _O_need_init = 1;
Xstatic int _O_st_ok = 0;
Xstatic int _O_doing_ul = 0;
Xstatic	char *_O_st_tmp;
X#ifdef M_TERMCAP
Xstatic	char _O_startline[Z_WORDLEN];
Xstatic	char _O_endline[Z_WORDLEN];
X#endif
X
Xstatic void
X_O_st_init()
X{
X	char termn[Z_WORDLEN];
X#ifdef M_TERMCAP
X	static	char entry[1024];
X#endif
X
X	/*
X	**	see if standard out is a terminal
X	*/
X	if (!isatty(1))
X	{
X		_O_need_init = 0;
X		_O_st_ok = 0;
X		return;
X	}
X
X	if (NULL == (_O_st_tmp = (char*) getenv("TERM")))
X	{
X		Z_complain("can't find TERM entry in environment\n");
X		_O_need_init = 0;
X		_O_st_ok = 0;
X		return;
X	}
X	(void) strcpy(termn,_O_st_tmp);
X
X#ifdef M_TERMCAP
X	if (1 != tgetent(entry,termn))
X	{
X		Z_complain("can't get TERMCAP info for terminal\n");
X		_O_need_init = 0;
X		_O_st_ok = 0;
X		return;
X	}
X
X	_O_st_tmp = _O_startline;
X	_O_startline[0] = '\0';
X	tgetstr("so",&_O_st_tmp);
X
X	_O_st_tmp = _O_endline;
X	_O_endline[0] = '\0';
X	tgetstr("se",&_O_st_tmp);
X
X	_O_st_ok = (strlen(_O_startline) > 0) && (strlen(_O_endline) > 0);
X#endif
X
X#ifdef M_TERMINFO
X	setupterm(termn,1,&_O_st_ok);
X#endif
X	_O_need_init = 0;
X}
X
Xvoid
XO_cleanup()
X{
X	/*
X	**	this probably isn't necessary, but in the
X	**	name of compeleteness.
X	*/
X#ifdef M_TERMINFO
X	resetterm();
X#endif
X}
X
Xstatic void
X_O_start_standout()
X{
X	if (_O_need_init)
X	{
X		_O_st_init();
X	}
X	if (_O_st_ok)
X	{
X#ifdef M_TERMCAP
X		(void) printf("%s",_O_startline);
X#endif 
X#ifdef M_TERMINFO
X		vidattr(A_STANDOUT);
X#endif
X	}
X	else
X	{
X		_O_doing_ul = 1;
X	}
X}
X
Xstatic void
X_O_end_standout()
X{
X	if (_O_need_init)
X	{
X		_O_st_init();
X	}
X	if (_O_st_ok)
X	{
X#ifdef M_TERMCAP
X		(void) printf("%s",_O_endline);
X#endif 
X#ifdef M_TERMINFO
X		vidattr(0);
X#endif
X	}
X	else
X	{
X		_O_doing_ul = 0;
X	}
X}
X
Xstatic void
X_O_pchars(line,start,end)
Xchar *line;
Xint start,end;
X{
X	int cnt;
X
X	for(cnt=start;cnt < end; cnt++)
X	{
X		if (_O_doing_ul)
X		{
X			(void) putchar('_');
X			(void) putchar('\b');
X		}
X		(void) putchar(line[cnt]);
X	}
X}
X
X
X/*
X**	convert a 0 origin token number to a 1 orgin token
X**		number or 1 origin line number as appropriate
X*/
Xstatic
X_O_con_line(numb,flags,filenum)
Xint numb, flags,filenum;
X{
X	if (flags & U_TOKENS)
X	{
X		return(numb+1);
X	}
X	else
X	{
X		/*
X		**	 check to make sure that this is a real
X		**	line number. if not, then return 0
X		**	on rare occasions, (i.e. insertion/deletion
X		**	of the first token in a file) we'll get
X		**	line numbers of -1.  the usual look-up technique
X		**	won't work since we have no lines before than 0.
X		*/
X		if (numb < 0)
X			return(0);
X		/*
X		**	look up the line number the token and then
X		**	add 1 to make line number 1 origin
X		*/
X		return(L_tl2cl(filenum,numb)+1);
X	}
X}
X
Xstatic char *
X_O_convert(ptr)
Xchar *ptr;
X{
X	static char spacetext[Z_WORDLEN];
X
X	if (1 == strlen(ptr))
X	{
X		switch (*ptr)
X		{
X			default:
X				break;
X			case '\n' :
X				(void) strcpy(spacetext,"<NEWLINE>");
X				return(spacetext);
X			case '\t' :
X				(void) strcpy(spacetext,"<TAB>");
X				return(spacetext);
X			case ' ' :
X				(void) strcpy(spacetext,"<SPACE>");
X				return(spacetext);
X		}
X				
X	}
X	return(ptr);
X}
X
Xstatic char*
X_O_get_text(file,index,flags)
Xint file,index,flags;
X{
X	static char buf[Z_LINELEN*2];	/* leave lots of room for both
X						the token text and the
X						chatter that preceeds it */
X	char *text;
X	K_token tmp;
X
X	if (flags & U_TOKENS)
X	{
X		tmp = K_gettoken(file,index);
X		text = _O_convert(K_gettext(tmp));
X		(void) sprintf(buf,"%s -- line %d, character %d\n",
X				text,
X				/*
X				**	add 1 to make output start at line 1 
X				**	and character numbers start at 1
X				*/
X				L_tl2cl(file,K_getline(tmp))+1,
X				K_getpos(tmp)+1);
X		return(buf);
X	}
X	else
X	{
X		return(L_gettline(file,index));
X	}
X}
X#define	_O_APP		1
X#define _O_DEL		2
X#define _O_CHA		3
X#define _O_TYPE_E	4
X
Xstatic void
X_O_do_lines(start,end,file)
Xint start,end,file;
X{
X	int cnt;
X	int lastline = -1;
X	int nextline;
X	K_token nexttoken;
X	for (cnt=start;cnt <= end; cnt++)
X	{
X		nexttoken = K_get_token(file,cnt);
X		nextline = K_getline(nexttoken);
X		if (lastline != nextline)
X		{
X			int lastone,lastchar;
X			K_token lasttok;
X			char linetext[Z_LINELEN+1];	/* leave room for
X							   terminator */
X			if (0 == file)
X			{
X				(void) printf("< ");
X			}
X			else
X			{
X				(void) printf("> ");
X			}
X
X			/*
X			**	put loop here if you want to print
X			**	out any intervening lines that don't
X			**	have any tokens on them
X			*/
X
X			/*
X			**	following line is necessary because
X			**	L_gettline is a macro, and can't be passed
X			*/
X			(void) strcpy(linetext,L_gettline(file,nextline));
X			_O_pchars(linetext,0,K_getpos(nexttoken));
X			_O_start_standout();
X			/*
X			** 	look for last token on this line to be
X			**	highlighted
X			*/
X			for ( lastone=cnt,lasttok = K_get_token(file,lastone);
X			      (lastone<=end)&&(nextline == K_getline(lasttok));
X				lastone++,lasttok = K_get_token(file,lastone))
X			{
X			}
X			lastone--;
X			lasttok = K_get_token(file,lastone);
X			lastchar = K_getpos(lasttok)
X					+ strlen(K_gettext(lasttok));
X			_O_pchars(linetext,K_getpos(nexttoken),lastchar);
X			_O_end_standout();
X			_O_pchars(linetext,lastchar,strlen(linetext));
X			
X			lastline = nextline;
X		}
X	}
X}
X
Xvoid
XO_output(start,flags)
XE_edit start;
Xint flags;
X{
X	int type = _O_TYPE_E;	/* initialize to error state
X				** this is to make sure that type is set
X				** somewhere
X				*/
X	int t_beg1, t_beg2, t_end1, t_end2; /* token numbers */
X	int first1, last1, first2, last2;
X
X	E_edit ep, behind, ahead, a, b;
X
X	/*
X	**	reverse the list of edits
X	*/
X	ahead = start;
X	ep = E_NULL;
X	while (ahead != E_NULL) {
X		/*
X		**	set token numbers intentionally out of range
X		**		as boilerplate
X		*/
X		t_beg1 = t_beg2 = t_end1 = t_end2 = -1;
X		/*
X		**	edit script is 1 origin, all of
X		**	 our routines are zero origin
X		*/
X		E_setl1(ahead,(E_getl1(ahead))-1);
X		E_setl2(ahead,(E_getl2(ahead))-1);
X
X		behind = ep;
X		ep = ahead;
X		ahead = E_getnext(ahead);
X		E_setnext(ep,behind);
X	}
X
X	/*
X	**	now run down the list and collect the following information
X	**	type of change (_O_APP, _O_DEL or _O_CHA)
X	**	start and length for each file
X	*/
X	while (ep != E_NULL)
X	{
X		b = ep;
X		/*
X		**	operation always start here
X		*/
X		t_beg1 = E_getl1(ep);
X		/*
X		**	any deletions will appear before any insertions,
X		**	so, if the first edit is an E_INSERT, then this
X		**	this is an _O_APP
X		*/
X		if (E_getop(ep) == E_INSERT)
X			type = _O_APP;
X		else {
X			/*
X			**	run down the list looking for the edit
X			**	that is not part of the current deletion
X			*/	
X			do {
X				a = b;
X				b = E_getnext(b);
X			} while ((b != E_NULL) &&
X				 (E_getop(b) == E_DELETE) &&
X				 ((E_getl1(b)) == ((E_getl1(a))+1)));
X			/*
X			**	if we have an insertion at the same place
X			**	as the deletion we just scanned, then
X			**	this is a change
X			*/
X			if ((b != E_NULL) &&
X				((E_getop(b)) == E_INSERT) &&
X				((E_getl1(b))==(E_getl1(a))))
X			{
X				type = _O_CHA;
X			}
X			else
X			{
X				type = _O_DEL;
X			}
X			/*
X			**	set up start and length information for
X			**	first file
X			*/
X			t_end1 = E_getl1(a);
X			/*
X			**	move pointer to beginning of insertion
X			*/
X			ep = b;
X			/*
X			**	if we are showing only a deletion,
X			**	then we're all done, so skip ahead
X			*/ 
X			if (_O_DEL == type)
X			{
X				t_beg2 = E_getl2(a);
X				t_end2 = -1;	/* dummy number, won't
X							ever be printed */
X						   
X				goto skipit;
X			}
X		}
X		t_beg2 = E_getl2(ep);
X		t_end2 = t_beg2-1;
X		/*
X		**	now run down the list lookingfor the
X		**	end of this insertion and keep count
X		**	of the number of times we step along
X		*/
X		do {
X			t_end2++;
X			ep = E_getnext(ep);
X		} while ((ep != E_NULL) && ((E_getop(ep)) == E_INSERT) &&
X					((E_getl1(ep)) == (E_getl1(b))));
X
Xskipit:;
X		if (flags & U_TOKENS)
X		{
X			/*
X			**	if we are dealing with tokens individually,
X			**	then just print then set printing so
X			*/
X				first1 = t_beg1;
X				last1 = t_end1;
X				first2 = t_beg2;
X				last2 = t_end2;
X		}
X		else
X		{
X			/*
X			**	we are printing differences in terms of lines
X			**	so find the beginning and ending lines of the
X			**	changes and print header in those terms
X			*/
X			if ( t_beg1 >= 0)
X				first1 = K_getline(K_get_token(0,t_beg1));
X			else
X				first1 = t_beg1;
X
X			if ( t_end1 >= 0)
X				last1 = K_getline(K_get_token(0,t_end1));
X			else
X				last1 = t_end1;
X
X			if ( t_beg2 >= 0)
X				first2 = K_getline(K_get_token(1,t_beg2));
X			else
X				first2 = t_beg2;
X
X			if ( t_end2 >= 0)
X				last2 = K_getline(K_get_token(1,t_end2));
X			else
X				last2 = t_end2;
X
X		}
X		/*
X		**	print the header for this difference
X		*/
X		(void) printf("%d",_O_con_line(first1,flags,0));
X		switch (type)
X		{
X		case _O_APP :
X			(void) printf("a%d",_O_con_line(first2,flags,1));
X			if (last2 > first2)
X			{
X				(void) printf(",%d",_O_con_line(last2,flags,1));
X			}
X			(void) printf("\n");
X			break;
X		case _O_DEL :
X			if (last1 > first1)
X			{
X				(void) printf(",%d",_O_con_line(last1,flags,0));
X			}
X			(void) printf("d%d\n",_O_con_line(first2,flags,1));
X			break;
X		case _O_CHA :
X			if (last1 > first1)
X			{
X				(void) printf(",%d",_O_con_line(last1,flags,0));
X			}
X			(void) printf("c%d",_O_con_line(first2,flags,1));
X			if (last2 > first2)
X			{
X				(void) printf(",%d",_O_con_line(last2,flags,1));
X			}
X			(void) printf("\n");
X			break;
X		default:
X			Z_fatal("type in O_output wasn't set\n");
X		}
X		if (_O_DEL == type || _O_CHA == type)
X		{
X			if (flags & U_TOKENS)
X			{
X				int cnt;
X				for(cnt=first1;cnt <= last1; cnt++)
X				{
X		(void) printf("< %s",
X							_O_get_text(0,cnt,flags));
X				}
X			}
X			else
X			{	
X				_O_do_lines(t_beg1,t_end1,0);
X			}
X		}
X		if (_O_CHA == type)
X		{
X			(void) printf("---\n");
X		}
X		if (_O_APP == type || _O_CHA == type)
X		{
X			if (flags & U_TOKENS)
X			{
X				int cnt;
X				for(cnt=first2;cnt <= last2; cnt++)
X				{
X					(void) printf("> %s",
X						_O_get_text(1,cnt,flags));
X				}
X			}
X			else
X			{
X				_O_do_lines(t_beg2,t_end2,1);
X			}
X		}
X	}
X	O_cleanup();
X	return;
X}
END_OF_FILE
if test 10536 -ne `wc -c <'output.c'`; then
    echo shar: \"'output.c'\" unpacked with wrong size!
fi
# end of 'output.c'
fi
if test -f 'spiff.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'spiff.c'\"
else
echo shar: Extracting \"'spiff.c'\" \(6721 characters\)
sed "s/^X//" >'spiff.c' <<'END_OF_FILE'
X/*                        Copyright (c) 1988 Bellcore
X**                            All Rights Reserved
X**       Permission is granted to copy or use this program, EXCEPT that it
X**       may not be sold for profit, the copyright notice must be reproduced
X**       on copies, and credit should be given to Bellcore where it is due.
X**       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
X*/
X
X
X#ifndef lint
Xstatic char rcsid[]= "$Header: spiff.c,v 1.1 88/09/15 11:33:51 daniel Rel $";
X#endif
X
X
X#include <stdio.h>
X#include "misc.h"
X#include "flagdefs.h"
X#include "parse.h"
X#include "edit.h"
X#include "line.h"
X#include "token.h"
X#include "tol.h"
X#include "command.h"
X#include "compare.h"
X#include "exact.h"
X#include "miller.h"
X#include "visual.h"
X#include "output.h"
X
Xextern void _Y_doargs();
X
Xstatic int _Y_eflag = 0;	/* use exact match algorithm */
Xstatic int _Y_vflag = 0;	/* use visual mode */
X
X/*
X**	this is the set of flags that gets used throughout the top module
X**	as well as being used to communicate between modules.
X*/
Xstatic int _Y_flags;
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X	E_edit edit_end;
X	char *filename[2];
X
X	int max_d; 	/* max number of differences allowed */
X	int i;		/* loop counter */
X
X	/*
X	**	parse the command line
X	*/
X	_Y_doargs(argc,argv,&(filename[0]),&(filename[1]),&max_d);
X
X	/*
X	**	initialize the default tolerance if it
X	**		hasn't been set already.
X	*/
X	T_initdefault();
X
X	/*
X	**	read and then parse the files
X	*/
X
X	/*
X	**	L_initfile return a code that indicates if the
X	**	entire file was read or not
X	**
X	**	P_fileparse also knows how to start at someplace other
X	**		than the first line of file
X	**
X	**	Taken together, this is enough to do step our way
X	**		through the file using an exact match algorithm.
X	**
X	**	Oh well, someday . . .
X	*/
X	for(i=0;i<=1;i++)
X	{
X		/*
X		**	read the file into core
X		*/
X		(void) L_init_file(i,filename[i]);
X		K_settmax(i,0);		/* start tokens at 0 */
X		/*
X		**	and parse the files into tokens
X		*/
X		P_file_parse(i,0,L_getrlmax(i),_Y_flags);
X	}
X
X	if (_Y_vflag)
X	{
X		return(V_visual(_Y_flags));
X	}
X
X	/*
X	**	if max_d was not set on the command line
X	**		set it to be as large as is possible
X	**		since the most changes possible would
X	**		be to delete all the tokens in the
X	**		first file and add all the tokens from
X	**		the second, the max possible is the
X	**		sum of the number of tokens in the
X	**		two files.
X	*/
X	if (-1 == max_d)
X		max_d = K_gettmax(0) + K_gettmax(1);
X
X	if (_Y_eflag)
X	{
X		edit_end = Q_do_exact(K_gettmax(0),K_gettmax(1),
X					max_d,_Y_flags);
X	}
X	else
X	{
X		edit_end = G_do_miller(K_gettmax(0), K_gettmax(1),
X				     max_d,_Y_flags);
X	}
X
X	if (E_NULL != edit_end)
X	{
X		O_output(edit_end,_Y_flags);
X		return(1);
X	}
X	return(0);
X}
X
X/*
X**	break a string into individual lines and feed
X**		them to the command module
X*/
Xstatic void
X_Y_cmdlines(from)
Xchar *from;
X{
X	char buf[Z_LINELEN]; 
X	char *to;
X	while ('\0' != *from)
X	{
X		/*
X		**	copy line into buf
X		*/
X		to = buf;
X		while (('\0' != *from) && ('\n' != *from))
X		{
X			*to++ = *from++;
X		}
X		*to = '\0';	/* terminate the line */
X
X		/*
X		**	hand the line to the command module
X		*/
X		C_addcmd(buf);
X		/*
X		**	skip the newline
X		*/
X		if ('\n' == *from)
X		{
X			from++;
X		}
X	}
X}
X
X/*
X**	this useful macro handle arguements that are adjacent
X**	to a flag or in the following word e.g --
X**
X**		-a XXX 
X**	and
X**		-aXXX 
X**
X**	both work when SETPTR is used. 
X*/
X#define SETPTR	{if(strlen(argv[1]) == 2) {argv++;argc--;ptr=argv[1];}else ptr=(&argv[1][2]);}
X
Xstatic void
X_Y_doargs(argc,argv,file1,file2,max_d)
Xint argc;
Xchar *argv[];
Xchar **file1,**file2;
Xint *max_d;
X{
X	char *ptr;
X
X	/*
X	**	mark maximum number of tokens as being unset
X	*/
X	*max_d = -1;
X
X	while (argc > 1 && argv[1][0] == '-')
X	{
X		switch (argv[1][1])
X		{
X			case 't':
X				_Y_flags |= U_TOKENS;
X				break;
X			case 'w':
X				_Y_flags |= U_INCLUDE_WS;
X				break;
X
X			case 'b':
X				_Y_flags |= U_BYTE_COMPARE;
X				break;
X
X			case 'c':
X				_Y_flags |= U_NO_CASE;
X				break;
X			case 'd' :
X				_Y_flags |= U_NEED_DECIMAL;
X				break;
X			case 'm' :
X				_Y_flags |= U_INC_SIGN;
X				break;
X			case 'a':
X				SETPTR;
X				T_defatol(ptr);
X				break;
X			case 'r':
X				SETPTR;
X				T_defrtol(ptr);
X				break;
X			case 'i':
X				T_defitol();
X				break;
X			case 'e' :
X				_Y_eflag = 1;
X				break;
X			case 'v' :
X				_Y_vflag = 1;
X				break;
X			case 'q' :
X				Z_setquiet();
X				break;
X			case 's' :
X				SETPTR;
X				_Y_cmdlines(ptr);
X				break;
X			case 'f' :
X			{
X				extern FILE *fopen();
X				char buf[Z_LINELEN];
X				FILE *cmdfile;
X				SETPTR;
X				if ((FILE*) NULL ==
X					(cmdfile = fopen(ptr,"r")))
X				{
X					Z_fatal("can't open command file\n");
X				}
X				while ((char*) NULL !=
X					(char*) fgets(buf,Z_LINELEN,cmdfile))
X				{
X					C_addcmd(buf);
X				}
X				(void) fclose(cmdfile);
X				break;
X			}
X			/*
X			**	useful commands for
X			**	 the C programming language
X			*/
X			case 'C' :
X				C_addcmd("literal  \"   \"    \\ ");
X				C_addcmd("comment  /*  */	 ");
X				C_addcmd("literal  &&		 ");
X				C_addcmd("literal  ||		 ");
X				C_addcmd("literal  <=		 ");
X				C_addcmd("literal  >=		 ");
X				C_addcmd("literal  !=		 ");
X				C_addcmd("literal  ==		 ");
X				C_addcmd("literal  --		 ");
X				C_addcmd("literal  ++		 ");
X				C_addcmd("literal  <<		 ");
X				C_addcmd("literal  >>		 ");
X				C_addcmd("literal  ->		 ");
X				C_addcmd("addalpha _		 ");
X				C_addcmd("tol      a0 		 ");
X				break;
X			/*
X			**	useful commands for
X			**	 the Bourne shell programming language
X			*/
X			case 'S' :
X				C_addcmd("literal  '    '    \\	");
X				C_addcmd("comment  #    $	");
X				C_addcmd("tol      a0 		");
X				break;
X			/*
X			**	useful commands for
X			**	 the Fortran programming language
X			*/
X			case 'F' :
X				C_addcmd("literal  '	'     ' ");
X				C_addcmd("comment  ^C   $	");
X				C_addcmd("tol      a0 		");
X				break;
X			/*
X			**	useful commands for
X			**	 the Lisp programming language
X			*/
X			case 'L' :
X				C_addcmd("literal  \" 	\"	");
X				C_addcmd("comment  ; 	$	");
X				C_addcmd("tol      a0 		");
X				break;
X			/*
X			**	useful commands for
X			**	 the Modula-2 programming language
X			*/
X			case 'M' :
X				C_addcmd("literal ' 	'	");
X				C_addcmd("literal \"	\"	");
X				C_addcmd("comment (*	*)	");
X				C_addcmd("literal :=		");
X				C_addcmd("literal <>		");
X				C_addcmd("literal <=		");
X				C_addcmd("literal >=		");
X				C_addcmd("tol      a0 		");
X				break;
X			case '0':
X			case '1':
X			case '2':
X			case '3':
X			case '4':
X			case '5':
X			case '6':
X			case '7':
X			case '8':
X			case '9':
X				*max_d = atoi(&argv[1][1]);
X				break;
X			default:
X				Z_fatal("don't understand arguments\n");
X		}
X		++argv;
X		--argc;
X	}
X	if (argc != 3)
X		Z_fatal ("spiff requires two file names.\n");
X	*file1 = argv[1];
X	*file2 = argv[2];
X}
END_OF_FILE
if test 6721 -ne `wc -c <'spiff.c'`; then
    echo shar: \"'spiff.c'\" unpacked with wrong size!
fi
# end of 'spiff.c'
fi
if test -f 'tol.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tol.c'\"
else
echo shar: Extracting \"'tol.c'\" \(5820 characters\)
sed "s/^X//" >'tol.c' <<'END_OF_FILE'
X/*                        Copyright (c) 1988 Bellcore
X**                            All Rights Reserved
X**       Permission is granted to copy or use this program, EXCEPT that it
X**       may not be sold for profit, the copyright notice must be reproduced
X**       on copies, and credit should be given to Bellcore where it is due.
X**       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
X*/
X
X
X#ifndef lint
Xstatic char rcsid[]= "$Header: tol.c,v 1.1 88/09/15 11:33:59 daniel Rel $";
X#endif
X
X#include "misc.h"
X#include "float.h"
X#include "tol.h"
X#include "token.h"
X
X/*
X**	storage for the default tolerances
X*/
XT_tol _T_gtol = _T_null;
X
X/*
X**	tolerances that can be set in the command script and attached to floating
X**		point numbers at parse time
X*/
Xstatic T_tol _T_tols[_T_TOLMAX];
X
X/*
X**	initialize the global tolerance
X**	should be called only once at the beginning of the program
X*/
Xvoid
XT_initdefault()
X{
X	static int called_before = 0;
X
X	if (called_before)
X	{
X		Z_fatal("T_initdefault called more than once\n");
X	}
X
X	/*
X	**	if the default tolerance was set somewhere else
X	**	don't set it here
X	*/
X	if (T_isnull(_T_gtol))
X	{
X		T_defatol(_T_ADEF);
X		T_defrtol(_T_RDEF);
X	}
X	called_before = 1;
X}
X
Xstatic void
X_T_tolclear(addr)
XT_tol *addr;
X{
X	*addr = _T_null;
X}
X
X/*
X**	clear the parse time tolerances
X*/
Xvoid
XT_clear_tols()
X{
X	int i;
X	for(i=0;i<_T_TOLMAX;i++)
X	{
X		_T_tolclear(&_T_tols[i]);
X	}
X}
X
Xstatic void
X_T_defclear()
X{
X	_T_tolclear(&_T_gtol);
X}
X
X/*
X**	take a series of specifiers and add them to the tolerance
X*/
Xstatic void
X_T_settol(toladdr,str)
XT_tol *toladdr;
Xchar *str;
X{
X	char typechar;
X	while ('\0' != *str)
X	{
X		/*
X		**	find the first non-whitespace character
X		*/
X		S_skipspace(&str);
X		/*
X		**	snarf up the type specifier
X		*/
X		typechar = *str;
X		/*
X		**	now skip the first char
X		*/
X		str++;
X		/*
X		**	skip any possibly intervening whitespace
X		*/
X		S_skipspace(&str);
X		switch (typechar)
X		{
X			case 'a':
X				_T_addtol(toladdr,T_ABSOLUTE,str);
X				break;
X			case 'r':
X				_T_addtol(toladdr,T_RELATIVE,str);
X				break;
X			case 'i':
X				_T_addtol(toladdr,T_IGNORE,(char*)0);
X				break;
X			case 'd':
X				_T_appendtols(toladdr,_T_gtol);
X				break;
X			default:
X				(void) sprintf(Z_err_buf,
X				  "don't understand tolerance type '%c'\n",typechar);
X				Z_fatal(Z_err_buf);
X		}
X		/*
X		**	and skip to next tolerance
X		*/
X		S_nextword(&str);
X	}
X}
X
X/*
X**	set the default tolerance 
X*/
Xvoid
XT_setdef(str)
Xchar *str;
X{
X	_T_defclear();
X	_T_settol(&_T_gtol,str);
X}
X
X
Xstatic char*
X_T_nextspec(ptr)
Xchar *ptr;
X{
X	/*
X	**	find the end of the current spec
X	*/
X	for(;(_T_SEPCHAR != *ptr) && ('\0' != *ptr);ptr++)
X	{
X	}
X
X	/*
X	**	and step over the seperator if necessary
X	*/
X	if (_T_SEPCHAR == *ptr)
X		ptr++;
X
X	return(ptr);
X}
X
X/*
X**	return just the next set of specs
X**		ie the string up to end of line or
X**			the first _T_SEPCHAR
X**	returned string does not include the _T_SEPCHAR
X*/
Xstatic char *
X_T_getspec(from)
Xchar *from;
X{
X	static char retval[Z_LINELEN];
X	char *ptr = retval;
X
X	while((_T_SEPCHAR != *from) && ('\0' != *from))
X	{
X		*ptr++ = *from++;
X	}
X	*ptr = '\0';	/* terminate the line */
X	return(retval);
X}
X
X/*
X**	parse a series of _T_SEPCHAR separated tolerance specifications
X*/
Xvoid
XT_tolline(str)
Xchar *str;
X{
X	int nexttol;
X
X	T_clear_tols();
X
X	for(nexttol=0;'\0' != *str;nexttol++,str = _T_nextspec(str))
X	{
X		/*
X		**	make sure we haven't run off the end
X		*/
X		if (nexttol >= _T_TOLMAX)
X		{
X			Z_fatal("too many tolerances per line");
X		}
X
X		/*
X		**	and set the tolerance
X		*/
X		_T_settol(&_T_tols[nexttol],_T_getspec(str));
X	}
X}
X
XT_moretols(next_tol)
X{
X	return((next_tol >= 0) &&
X		(_T_TOLMAX-1 > next_tol) &&
X		(!T_isnull( _T_tols[next_tol+1])));
X}
X
XT_tol
XT_gettol(index)
Xint index;
X{
X	return(_T_tols[index]);
X}
X
X/*
X**	chose which tolerance to use
X**		 precidence is
X**			first tolerance
X**			second tolerance
X**			default tolerance
X*/
XT_tol
XT_picktol(p1,p2)
XT_tol p1, p2;
X{
X	if (!(T_isnull(p1)))
X		return(p1);
X
X	if (!(T_isnull(p2)))
X		return(p2);
X
X	return(_T_gtol);
X}
X
Xvoid
X_T_appendtols(to,from)
XT_tol *to,from;
X{
X
X	T_tol last;
X
X	/*
X	**	are there any elements on the list yet
X	*/
X	if (T_isnull(*to))
X	{
X		/*
X		**	it's a null list, so allocat space for the
X		**		first element and set pointer to it.
X		*/
X
X		*to = from;
X	}
X	else
X	{
X		/*
X		**	find the last element on the list
X		*/
X		for(last= *to;!T_isnull(T_getnext(last));last = T_getnext(last))
X		{
X		}
X		/*
X		**	add an element on the end
X		*/
X		T_setnext(last,from);
X	}
X}
X
X/*
X**	add a tolerance to a list
X*/
Xvoid
X_T_addtol(listptr,type,str)
XT_tol *listptr;
Xint type;
Xchar *str;
X{
X	T_tol last;
X
X	/*
X	**	are there any elements on the list yet
X	*/
X	if (T_isnull(*listptr))
X	{
X		/*
X		**	it's a null list, so allocat space for the
X		**		first element and set pointer to it.
X		*/
X
X		last = *listptr = Z_ALLOC(1,_T_struct);
X	}
X	else
X	{
X		/*
X		**	find the last element on the list
X		*/
X		for(last= *listptr;!T_isnull(T_getnext(last));last = T_getnext(last))
X		{
X		}
X		/*
X		**	add an element on the end
X		*/
X		T_setnext(last,Z_ALLOC(1,_T_struct));
X
X		/*
X		**	and point to the new element
X		*/
X		last = T_getnext(last);
X	}
X
X	T_settype(last,type);
X	T_setnext(last,_T_null);
X
X	/*
X	**	set the float value only if necessary
X	*/
X	if (T_IGNORE == type)
X	{
X		T_setfloat(last,F_null);
X	}
X	else
X	{
X		T_setfloat(last,F_atof(str,NO_USE_ALL));
X
X		/*
X		**	test new tolerance for sanity
X		*/
X		if (F_getsign(T_getfloat(last)))
X		{
X			(void) sprintf(Z_err_buf,
X			"%s : negative tolerances don't make any sense\n",str);
X			Z_fatal(Z_err_buf);
X		}
X		/*
X		**	check for excessively large relative tolerances
X		*/
X		if ((T_RELATIVE == type) &&
X			 (F_floatcmp(T_getfloat(last),
X				     F_atof("2.0",USE_ALL)) > 0))
X		{
X			(void) sprintf(Z_err_buf,
X	"%s : relative tolerances greater than 2 don't make any sense\n",str);
X			Z_fatal(Z_err_buf);
X		}
X	}
X}
END_OF_FILE
if test 5820 -ne `wc -c <'tol.c'`; then
    echo shar: \"'tol.c'\" unpacked with wrong size!
fi
# end of 'tol.c'
fi
if test -f 'visual.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'visual.c'\"
else
echo shar: Extracting \"'visual.c'\" \(7697 characters\)
sed "s/^X//" >'visual.c' <<'END_OF_FILE'
X/*                        Copyright (c) 1988 Bellcore
X**                            All Rights Reserved
X**       Permission is granted to copy or use this program, EXCEPT that it
X**       may not be sold for profit, the copyright notice must be reproduced
X**       on copies, and credit should be given to Bellcore where it is due.
X**       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
X*/
X
X
X#ifndef lint
Xstatic char rcsid[]= "$Header: visual.c,v 1.1 88/09/15 11:34:02 daniel Rel $";
X#endif
X
X#ifdef MGR
X
X#include "misc.h"
X#include "line.h"
X#include "token.h"
X#include "/usr/public/pkg/mgr/include/term.h"
X#include "/usr/public/pkg/mgr/include/restart.h"
X
X#define OTHER		0
X#define ON_DEBUG	1
X#define OFF_DEBUG	2
X#define DO_QUIT		3
X#define DO_PAGE		4
X#define NEW_PREC	5
X
X
X#define NROW	60
X#define NCOL	80
X
Xint isdiff[MAXTOKENS];	/* flag showing if a token pair was shown different*/
X
Xint comwin,wina, winb;	/* location to store window numbers */
Xint fontx,fonty;	/* size of the font in pixels */
X
Xint debug =0;
X
X
Xint firsttoken = 0;	/* index of first token pair being displayed */
Xint tokencnt;		/* count of the number of token pairs being displayed */
X
XV_visual(flags)
Xint flags;
X{
X
X	int moretodo = 1;	/* flag to clear when we're finished */
X
X	messup();
X
X	m_selectwin(comwin);
X	m_setmode(W_ACTIVATE);
X
X	showpages(comroutine,flags);
X
X	do
X	{
X		switch(getinput())
X		{
X			case ON_DEBUG:
X				debug = 0;
X				break;
X			case OFF_DEBUG:
X				debug = 1;
X				break;
X			case DO_QUIT:
X				moretodo = 0;
X				break;
X			case DO_PAGE:
X				if((firsttoken+tokencnt>= K_gettmax(0))||
X				   (firsttoken+tokencnt>= K_gettmax(1)))
X				{
X					m_selectwin(comwin);
X					m_printstr("\007this is the last page\n");
X					break;
X				}
X				firsttoken += tokencnt;
X				showpages(comroutine,flags);
X				break;
X			case NEW_PREC:
X				updatepages(comroutine,flags);
X				break;
X			case OTHER:
X				break;
X			default :
X				Z_fatal("bad value in main switch");
X				
X		}
X	} while (moretodo);
X
X	V_cleanup();
X	return(0);
X}
X
Xgetinput()
X{
X	char ibuf[Z_LINELEN];	/* input buffer */
X	char *ptr;
X
X	m_selectwin(comwin);
X	m_setmode(W_ACTIVATE);
X	switch (m_getchar())
X	{
X		case 't':
X			m_gets(ibuf);
X			/*
X			**	skip the 'tol'
X			*/
X			ptr = ibuf;
X			S_nextword(&ptr);
X			T_setdef(ptr);
X			return(NEW_PREC);
X		case 'q':
X			return(DO_QUIT);
X		case 'd':
X			return(OFF_DEBUG);
X		case 'D':
X			return(ON_DEBUG);
X		case 'm':
X			return(DO_PAGE);
X		default:
X			return(OTHER);
X	}
X	
X}
X
Xshowpages(comroutine,flags)
Xint (*comroutine)();
Xint flags;
X{
X	int i;
X		m_selectwin(wina);
X		m_clear();
X		m_selectwin(winb);
X		m_clear();
X		showlines();
X
X		for(i=firsttoken;i<tokencnt+firsttoken; i++)
X		{
X			isdiff[i] = 0;
X		}
X		updatepages(comroutine,flags);
X}
X
Xupdatepages(comroutine,flags)
Xint (*comroutine)();
Xint flags;
X{
X	int i;
X
X	for(i=firsttoken;i<tokencnt+firsttoken; i++)
X	{
X		if (isdiff[i])
X		{
X
X			if (0 == X_com(i,i,flags))
X			{
X				m_selectwin(wina);
X				un_highlight(0,K_gettoken(0,i),K_getline(K_gettoken(0,firsttoken)));
X				m_selectwin(winb);
X				un_highlight(1,K_gettoken(1,i),K_getline(K_gettoken(1,firsttoken)));
X				isdiff[i] = 0;
X			}
X		}
X		else
X		{
X			if (0 != X_com(i,i,flags))
X			{
X				m_selectwin(wina);
X				highlight(0,K_gettoken(0,i),K_getline(K_gettoken(0,firsttoken)));
X				m_selectwin(winb);
X				highlight(1,K_gettoken(1,i),K_getline(K_gettoken(1,firsttoken)));
X				isdiff[i] = 1;
X			}
X		}
X	}
X}
X
Xun_highlight(file,ptr,firstline)
Xint file;
XK_token ptr;
Xint firstline;
X{
X	highlight(file,ptr,firstline);
X}
X
X/*
X**	argument expressed in terms of token lines
X*/
Xhighlight(file,ptr,firstline)
Xint file;
XK_token ptr;
Xint firstline;
X{
X	int startx = K_getpos(ptr)*fontx;
X	int starty = (L_tl2cl(file,K_getline(ptr))-L_tl2cl(file,firstline))*fonty;
X
X	int sizex = fontx*strlen(K_gettext(ptr));
X	int sizey = fonty;
X	m_bitwrite(startx,starty,sizex,sizey);
X}
X
Xshowlines()
X{
X	int Alinecnt = 0;
X	int Blinecnt = 0;
X
X	int Atfirstline = K_getline(K_gettoken(0,firsttoken));
X	int Btfirstline = K_getline(K_gettoken(1,firsttoken));
X	int Afirstline =  L_tl2cl(0,K_getline(K_gettoken(0,firsttoken)));
X	int Bfirstline =  L_tl2cl(1,K_getline(K_gettoken(1,firsttoken)));
X	int Anexttoken = L_getindex(0,Atfirstline);
X	int Bnexttoken = L_getindex(1,Btfirstline);
X	int i;
X	/*
X	**	first print the lines on the screen
X	*/
X	for(i=0;i < NROW;i++)
X	{
X		if(Afirstline+i < L_getclmax(0))
X		{
X			m_selectwin(wina);
X			showline(0,Afirstline+i,i);
X			Alinecnt++;
X		}
X
X		if(Bfirstline+i < L_getclmax(1))
X		{
X			m_selectwin(winb);
X			showline(1,Bfirstline+i,i);
X			Blinecnt++;
X		}
X	}
X	/*
X	**	now figure out how many tokens we actually printed
X	*/
X	for(i=Atfirstline;Anexttoken<K_gettmax(0) && L_tl2cl(0,i) < Afirstline+Alinecnt;i++)
X	{
X			Anexttoken += L_getcount(0,i);
X	}
X
X	for(i=Btfirstline;Bnexttoken<K_gettmax(1) && L_tl2cl(1,i) < Bfirstline+Blinecnt;i++)
X	{
X			Bnexttoken += L_getcount(1,i);
X	}
X	tokencnt = MIN(Anexttoken,Bnexttoken) - firsttoken;
X
X	/*
X	**	draw a line through any tokens that come before the first
X	**		token that is being compared
X	*/
X	if (L_getindex(0,Atfirstline) != firsttoken)
X	{
X		m_selectwin(wina);
X		for(i=L_getindex(0,Atfirstline);i<firsttoken;i++)
X		{
X			drawline(K_gettoken(0,i),0);
X		}
X	}
X
X	if (L_getindex(1,Btfirstline) != firsttoken)
X	{
X		m_selectwin(winb);
X
X		for(i=L_getindex(1,Btfirstline);i<firsttoken;i++)
X		{
X			drawline(K_gettoken(1,i),0);
X		}
X/*
Xm_line(Bt[Bindex[Bfirstline]]->pos*fontx,fonty/2,(Bt[firsttoken]->pos*fontx)-2,fonty/2);
X*/
X	}
X
X	if (Anexttoken > Bnexttoken)
X	{
X		m_selectwin(wina);
X		for(i=Bnexttoken;i<Anexttoken;i++)
X		{
X			drawline(K_gettoken(0,i),L_tl2cl(0,K_getline(K_gettoken(0,i)))-Afirstline);
X		}
X	}
X
X	if (Anexttoken < Bnexttoken)
X	{
X		m_selectwin(winb);
X		for(i=Anexttoken;i<Bnexttoken;i++)
X		{
X			drawline(K_gettoken(1,i),L_tl2cl(1,K_getline(K_gettoken(1,i)))-Bfirstline);
X		}
X	}
X
X}
X
X/*
X**	line is given in conten line
X*/
Xdrawline(ptr,line)
XK_token ptr;
Xint line;
X{
X		m_line(K_getpos(ptr)*fontx,
X			(line*fonty)+fonty/2,
X			(K_getpos(ptr)+strlen(K_gettext(ptr)))*fontx,
X			(line*fonty)+fonty/2);
X}
X
X/*
X**	takes arguments in terms of content lines
X*/
Xshowline(file,index,row)
Xint file;
Xint index;
Xint row;
X{
X	static char tmp[Z_LINELEN];
X	m_move(0,row);
X	stripnl(tmp,L_getcline(file,index));
X	m_printstr(tmp);
X}
X
Xstripnl(to,from)
Xchar *to,*from;
X{
X	while ((*from != '\n') && (*from != '\0'))
X	{
X		*to++ = *from++;
X	}
X	*to = '\0';
X}
X
Xstatic int didscr = 0;
X
Xmessup()
X{
X	int col, row;
X	int dum1,dum2,dum3,border;
X
X	m_setup(W_FLUSH|W_DEBUG);
X	m_push(P_EVENT|P_FLAGS|P_POSITION);
X	get_param(&dum1,&dum2,&dum3,&border);
X	didscr = 1;
X	comwin =  m_makewindow(192,50,732,116);
X	wina = m_makewindow(0,218,570,670);
X	m_selectwin(wina);
X	m_font(2);
X	get_font(&fontx,&fonty);
X	m_shapewindow(0,218,NCOL*fontx+(2*border),NROW*fonty+(2*border));
X
X	get_colrow(&col,&row);
X	if ((col != NCOL) || (row != NROW))
X	{
X		Z_fatal("bad window size");
X	}
X	m_func(B_INVERT);
X	m_setmode(W_ABS);
X
X	winb = m_makewindow(580,218,570,670);
X	m_selectwin(winb);
X	m_font(2);
X	get_font(&fontx,&fonty);
X	m_shapewindow(580,218,NCOL*fontx+(2*border),NROW*fonty+(2*border));
X
X	get_colrow(&col,&row);
X	if ((col != NCOL) || (row != NROW))
X	{
X		Z_fatal("bad window size");
X	}
X	m_func(B_INVERT);
X	m_setmode(W_ABS);
X
X	m_selectwin(comwin);
X	m_clear();
X	m_setmode(W_ABS);
X	m_setmode(W_ACTIVATE);
X}
X
XV_cleanup()
X{
X	if (didscr)
X	{
X		m_destroywin(wina);
X		m_destroywin(winb);
X		m_destroywin(comwin);
X		m_popall();
X		m_setecho();
X		(void) fclose(m_termin);
X		(void) fclose(m_termout);
X	}
X}
X
X#else
X
X#include "misc.h"
X/*
X**	dummy code for systems that don't have
X**	the mgr window manager installed
X*/
XV_visual(d)
Xint d;
X{
X	Z_fatal("visual mode is not available on this machine\n");
X	return(-d);	/* boiler plate */
X}
X
Xvoid
XV_cleanup()
X{
X}
X
X#endif
END_OF_FILE
if test 7697 -ne `wc -c <'visual.c'`; then
    echo shar: \"'visual.c'\" unpacked with wrong size!
fi
# end of 'visual.c'
fi
echo shar: End of archive 2 \(of 4\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 4 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 4 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.