v16i068: Spiff, find approximate differences in files, Part02/04
Rich Salz
rsalz at uunet.uu.net
Sat Nov 12 04:18:38 AEST 1988
Submitted-by: Daniel W Nachbar <daniel at 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 at 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 at uunet.uu.net.
More information about the Comp.sources.unix
mailing list