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.