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

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

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

[  This is the program Dan presented at his \fIexcellent\fP talk at
   SF Usenix.  For those who weren't there, yes, Spiff is named after
   the comic strip character in Calvin and Hobbes.  The "MGR" window
   system mentioned in the README will be appearing here shortly.  I
   repacked this submission.  --r$  ]

The well known program diff is inappropriate for some common tasks such as
comparing the output of floating point calculations where roundoff errors
lead diff astray and comparing program source code where some differences
in the text (such as white space and comments) have no effect on the
operation of the compiled code. A new program, named spiff, addresses
these and other similar cases by lexical parsing of the input files and
then applying a differencing algorithm to the token sequences. Spiff
ignores differences between floating point numbers that are below a user
settable tolerance.  Other features include user settable commenting and
literal string conventions and a choice of differencing algorithm. There
is also an interactive mode wherein the input texts are displayed with
differences highlighted. The user can change numeric tolerances "on the
fly" and spiff will adjust the highlighting accordingly.

#! /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 1 (of 4)."
# Contents:  MANIFEST README Sample.1 Sample.2 Sample.3 Sample.4
#   command.c command.h comment.h compare.h edit.h exact.c exact.h
#   flagdefs.h float.h floatrep.c floatrep.h miller.c miller.h misc.c
#   misc.h output.h parse.h strings.c strings.h token.c token.h tol.h
#   visual.h
# Wrapped by rsalz@papaya.bbn.com on Fri Nov 11 13:12:22 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'MANIFEST'\"
else
echo shar: Extracting \"'MANIFEST'\" \(127 characters\)
sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
X   File Name		Archive #	Description
X-----------------------------------------------------------
X MANIFEST                   1	
END_OF_FILE
if test 127 -ne `wc -c <'MANIFEST'`; then
    echo shar: \"'MANIFEST'\" unpacked with wrong size!
fi
# end of 'MANIFEST'
fi
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(9702 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XINSTALLATION
X	1) Change makefile settings to reflect
X		ATT vs. BSD software
X		termio vs. termcap
X		MGR vs. no MGR		(MGR is a BELLCORE produced
X					 window manager that is also available
X					 free to the public.)
X	2) Then, just say "make".
X		If you want to "make install", you should first
X		change definition of INSDIR in the makefile
X
X	3) to test the software say
X
X			spiff Sample.1 Sample.2
X
X		spiff should find 4 differences and
X		you should see the words "added", "deleted", "changed",
X		and "altered" as well as four number in stand-out mode.
X
X			spiff Sample.1 Sample.2 | cat
X
X		should produce the same output, only the differences
X		should be underlined However, on many terminals the underlining
X		does not appear. So try the command
X
X			spiff Sample.1 Sample.2 | cat -v
X
X		or whatever the equivalent to cat -v is on your system.
X
X		A more complicated test set is found in Sample.3 and Sample.4
X		These files show how to use embedded commands to do things
X		like change the commenting convention and tolerances on the
X		fly.  Be sure to run the command with the -s option to spiff:
X
X			spiff -s 'command spiffword' Sample.3 Sample.4
X
X		These files by no means provide an exhaustive test of
X		spiff's features. But they should give you some idea if things
X		are working right.
X
X	This code (or it's closely related cousins) has been run on
X	Vaxen running 4.3BSD, a CCI Power 6, some XENIX machines, and some
X	other machines running System V derivatives as well as
X	(thanks to eugene@ames.arpa) Cray, Amdahl and Convex machines.
X
X	4) Share and enjoy.
X
XAUTHOR'S ADDRESS
X	Please send complaints, comments, praise, bug reports, etc to
X		Dan Nachbar
X		Bell Communications Research  (also known as BELLCORE)
X		445 South St. Room 2B-389
X		Morristown, NJ 07960
X
X			nachbar@bellcore.com
X		or
X			bellcore!nachbar
X		or
X			(201) 829-4392  (praise only, please)
X
XOVERVIEW OF OPERATION
X
XEach of two input files is read and stored in core.
XThen it is parsed into a series of tokens (literal strings and
Xfloating point numbers, white space is ignored).
XThe token sequences are stored in core as well.
XAfter both files have been parsed, a differencing algorithm is applied to
Xthe token sequences.  The differencing algorithm
Xproduces an edit script, which is then passed to an output routine.
X
XSIZE LIMITS AND OTHER DEFAULTS
X		file implementing limit		name		default value
Xmaximum number of lines		lines.h		_L_MAXLINES	10000
X	per file
Xmaximum number of tokens	token.h		K_MAXTOKENS	50000
X	per file
Xmaximum line length		misc.h		Z_LINELEN	 1024
Xmaximum word length		misc.h		Z_WORDLEN	   20
X (length of misc buffers for
X things like literal
X delimiters.
X NOT length of tokens which
X can be virtually any length)
Xdefault absolute tolerance	tol.h		_T_ADEF		   "1e-10"   
Xdefault relative tolerance	tol.h		_T_RDEF		   "1e-10"  
Xmaximum number of commands	command.h	_C_CMDMAX	  100
X in effect at one time
Xmaximum number of commenting	comment.h	W_COMMAX	   20
X conventions that can be
X in effect at one time
X (not including commenting
X  conventions that are
X  restricted to beginning
X  of line)
Xmaximum number of commenting	comment.h	W_BOLMAX	   20
X conventions that are
X restricted to beginning of
X line that are in effect at
X one time
Xmaximum number of literal	comment.h	W_LITMAX	   20
X string conventions that
X can be in effect at one time
Xmaximum number of tolerances	tol.h		_T_TOLMAX	   10
X that can be in effect at one
X time
X
X
XDIFFERENCES BETWEEN THE CURRENT VERSION AND THE ENCLOSED PAPER
X
XThe files paper.ms and paper.out contain the nroff -ms input and
Xoutput respectively of a paper on spiff that was given the Summer '88
XUSENIX conference in San Francisco.  Since that time many changes
Xhave been made to the code.  Many flags have changed and some have
Xhad their meanings reversed, see the enclosed man page for the current
Xusage.  Also, there is no longer control over the
Xgranularity of object used when applying the differencing algorithm.
XThe current version of spiff always applies the differencing
Xin terms of individual tokens.  The -t flag controls how the edit script
Xis printed.  This arrangement more closely reflects the original intent
Xof having multiple differencing granularities. 
X
XPERFORMANCE
X
XSpiff is big and slow.  It is big because all the storage is
Xin core.  It is a straightforward but boring task to move the temporary
Xstorage into a file.  Someone who cares is invited to take on the job.
XSpiff is slow because whenever a choice had to be made between
Xspeed of operation and ease of coding, speed of operation almost always lost.
XAs the program matures it will almost certainly get smaller and faster.
XObvious performance enhancements have been avoided in order to make the
Xprogram available as soon as possible.
X
XCOPYRIGHT
X
XOur lawyers advise the following:
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
XGiven that all of the above seems to be very reasonable, there should be no
Xreason for anyone to not play by the rules.
X
X
XNAMING CONVENTIONS USED IN THE CODE
X
XAll symbols (functions, data declarations, macros) are named as follows:
X
X	L_foo	-- for names exported to other modules
X			and possibly used inside the module as well.
X	_L_foo	-- for names used by more than one routine
X			within a module
X	foo	-- for names used inside a single routine.
X
XEach module uses a different value for "L" -- 
X	module files	   letter used     implements
X	spiff.c			Y	top level routines
X	misc.[ch]		Z	various routines used throughout
X	strings.[ch]		S	routines for handling strings
X	edit.h			E	list of changes found and printed
X	tol.[ch]		T	tolerances for real numbers
X	token.[ch]		K	storage for objects
X	float.[ch]		F	manipulation of floats
X	floatrep.[ch]		R	representation of floats
X	line.[ch]		L	storage for input lines
X	parse.[ch]		P	parse for input files
X	command.[ch]		C	storage and recognition of commands
X	comment.[ch]		W	comment list maintenance
X	compare.[ch]		X	comparisons of a single token
X	exact.[ch]		Q	exact match differencing algorithm
X	miller.[ch]		G	miller/myers differencing algorithm
X	output.[ch]		O	print listing of differences
X	flagdefs.h		U	define flag bits that are used in
X					several of the other modules.
X					These #defines could have been
X					included in misc.c, but were separated
X					out because of their explicit
X					communication function.
X	visual.[ch]		V	screen oriented display for MGR
X					window manager, also contains
X					dummy routines for people who don't
X					have MGR 
X
XI haven't cleaned up visual.c yet.  It probably doesn't even compile
Xin this version anyway. But since most people don't have mgr, this
Xisn't urgent.
X
XNON-OBVIOUS DATA STRUCTURES
X
XThe Floating Point Representation
X
XFloating point numbers are stored in a struct R_flstr
XThe fractional part is often called the mantissa.
X
XThe structure consists of
X	a flag for the sign of the factional part
X	the exponent in binary 
X	a character string containing the fractional part
X
XThe structure could be converted to a float via
X	atof(strcat(".",mantissa)) * (10^exponent)
X
XTo be properly formed, the mantissa string must:
X	start with a digit between 1 and 9 (i.e. no leading zeros)
X		except for the zero, in which case the mantissa is exactly "0"
X	for the special case of zero, the exponent is always 0, and the
X		sign is always positive. (i.e. no negative 0)
X
XIn other words, (except for the value 0)
Xthe mantissa is a fractional number ranging
Xbetween 0.1 (inclusive) and 1.0 (exclusive).
XThe exponent is interpreted as a power of 10.
X
XLines 
Xthere are three sets of lines:
Ximplemented in line.c and line.h
X	real_lines --
X	  the lines as they come from the file
X	content_lines --
X	  a subset of reallines that excluding embedded commands
Ximplemented in token.c and token.h 
X	token_lines --
X	  a subset of content_lines consisting of those lines that
X		have tokens that begin on them (literals can go on for
X		more than one line)
X		i.e. content_lines excluding comments and blank lines.
X
X
XTHE STATE OF THE CODE
XThings that should be added
X	visual mode should handle tabs and wrapped lines
X	handling huge files in chunks when in using the ordinal match
X	algorithm. right now you have to parse and then diff the
X	whole thing before you get any output.  often, you run out of memory.
X
XThings that would be nice to add
X	output should optionally be expressed in real line numbers
X		(i.e. including command lines)
X	at present, all storage is in core. there should
X		be a compile time decision to allow temporary storage
X		in files rather than core. 
X		that way the user could decide how to handle the
X			speed/space tradeoff
X	a front end that looked like diff should be added so that
X		one could drop spiff into existing shell scripts
X	the parser converts floats into their internal form even when
X		it isn't necessary.
X	in the miller/myer code, the code should check for matching
X		end sequences.  it currently looks matching beginning
X		sequences.
X
XMinor programming improvements (programming botches)
X	some of the #defines should really be enumerated types
X	all the routines in strings.c that alter the data at the end of
X		a pointer but return void should just return the correct
X		data. the current arrangement is a historical artifact
X		of the days when these routines returned a status code.
X		but then the code was never examined,
X		so i made them void . . .
X	comments should be added to the miller/myer code
X	in visual mode, ask for font by name rather than number
END_OF_FILE
if test 9702 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'Sample.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Sample.1'\"
else
echo shar: Extracting \"'Sample.1'\" \(378 characters\)
sed "s/^X//" >'Sample.1' <<'END_OF_FILE'
Xtest file for spiff.
Xthere is a word       here.
Xthere is a deleted word in this line.
Xthere is a word that is changed here.
X
Xno difference on 	this line  due to      white space.
Xdefault absolute tolerance should be 1e-10   
Xno difference --> 0.0           different --> 0.0
Xdefault relative tolerance should be 1e-10   
Xno difference --> 10.           different --> 10.00000
X
END_OF_FILE
if test 378 -ne `wc -c <'Sample.1'`; then
    echo shar: \"'Sample.1'\" unpacked with wrong size!
fi
# end of 'Sample.1'
fi
if test -f 'Sample.2' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Sample.2'\"
else
echo shar: Extracting \"'Sample.2'\" \(394 characters\)
sed "s/^X//" >'Sample.2' <<'END_OF_FILE'
Xtest file for spiff.
Xthere is a word added here.
Xthere is a         word in this line.
Xthere is a word that is altered here.
Xno difference on this line due to white space.
X
Xdefault absolute tolerance should be .0000000001   
Xno difference --> 0.0000000001  different --> 0.00000000011
Xdefault relative tolerance should be 1.0e-10   
Xno difference --> 10.000000001  different --> 10.0000000011
X
END_OF_FILE
if test 394 -ne `wc -c <'Sample.2'`; then
    echo shar: \"'Sample.2'\" unpacked with wrong size!
fi
# end of 'Sample.2'
fi
if test -f 'Sample.3' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Sample.3'\"
else
echo shar: Extracting \"'Sample.3'\" \(2072 characters\)
sed "s/^X//" >'Sample.3' <<'END_OF_FILE'
Xspiffword rem this file should be named Sample.3
Xspiffword rem it is a test input file for spiff
Xspiffword rem it should be compared with a file named Sample.4, to use it
Xspiffword rem execute: spiff -s 'command spiffword' Sample.3 Sample.4
Xspiffword rem the -s argument is  essential, otherwise spiff will
Xspiffword rem will not recognized these comments for what they are.
Xspiffword rem first we'll check the default tolerances.  this is the
Xspiffword rem same test as is found in Sample.1/Sample.2
Xdefault absolute tolerance should be 1e-10   
Xno difference --> 0.0           different --> 0.0
Xdefault relative tolerance should be 1e-10   
Xno difference --> 10.           different --> 10.00000
Xspiffword rem Note that spiff said that the differences were on lines 2 and 4
Xspiffword rem of the input files even though they were really on lines 10 and
Xspiffword rem of this file.
Xspiffword rem That's because spiff does not count lines with commands.
Xspiffword rem As part of spiff's design, it is assumed that "embedded commands"
Xspiffword rem such as these are not of direct interest and have been added
Xspiffword rem soley for the purpose of controlling the spiffing process.
Xspiffword rem OK. Now we'll try changing some things. first, we'll add 
Xspiffword rem a commenting convention, everything from # to end of line
Xspiffword rem will be ignored.
Xspiffword comment # $
Xthere should be NO differences on this line !!!! # Nah, Nah, can't see me !!
Xspiffword rem Well, that was fun. Now we'll ignore all differences
Xspiffword tol i
Xspiffword rem and there should be no differences the following lines
Xno difference --> 0.0           NO difference --> 0.0
Xno difference --> 10.           NO difference --> 10.00000
Xspiffword rem now we'll set the tolerance for the second number
Xspiffword rem on each line, to be lower than the others.
Xspiffword tol a0.02 ; a0.01 ; a0.02
Xspiffword rem and only the middle number should appear different
Xnot different --> 0.0    different --> 0.0    not different --> 0.0
Xspiffword rem You get the idea. Enough fun for now.
XBye, Bye.
END_OF_FILE
if test 2072 -ne `wc -c <'Sample.3'`; then
    echo shar: \"'Sample.3'\" unpacked with wrong size!
fi
# end of 'Sample.3'
fi
if test -f 'Sample.4' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Sample.4'\"
else
echo shar: Extracting \"'Sample.4'\" \(2110 characters\)
sed "s/^X//" >'Sample.4' <<'END_OF_FILE'
Xspiffword rem this file should be named Sample.4
Xspiffword rem it is a test input file for spiff
Xspiffword rem it should be compared with a file named Sample.3, to use it
Xspiffword rem execute: spiff -s 'command spiffword' Sample.3 Sample.4
Xspiffword rem the -s argument is  essential, otherwise spiff will
Xspiffword rem will not recognized these comments for what they are.
Xspiffword rem first we'll check the default tolerances.  this is the
Xspiffword rem same test as is found in Sample.1/Sample.2
Xdefault absolute tolerance should be .0000000001   
Xno difference --> 0.0000000001  different --> 0.00000000011
Xdefault relative tolerance should be 1.0e-10   
Xno difference --> 10.000000001  different --> 10.0000000011
Xspiffword rem Note that spiff said that the differences were on lines 1 and 3
Xspiffword rem of the input files even though they were really on lines 10 and
Xspiffword rem of this file.
Xspiffword rem That's because spiff does not count lines with commands.
Xspiffword rem As part of spiff's design, it is assumed that "embedded commands"
Xspiffword rem such as these are not of direct interest and have been added
Xspiffword rem soley for the purpose of controlling the spiffing process.
Xspiffword rem OK. Now we'll try changing some things. first, we'll add 
Xspiffword rem a commenting convention, everything from # to end of line
Xspiffword rem will be ignored.
Xspiffword comment # $
Xthere should be NO differences on this line !!!! # No difference here !!
Xspiffword rem Well, that was fun. Now we'll ignore all differences
Xspiffword tol i
Xspiffword rem and there should be no differences the following lines
Xno difference --> 0.0000000001  NO difference --> 0.00000000011
Xno difference --> 10.000000001  NO difference --> 10.0000000011
Xspiffword rem now we'll set the tolerance for the second number
Xspiffword rem on each line, to be lower than the others.
Xspiffword tol a0.02 ; a0.01 ; a0.02
Xspiffword rem and only the middle number should appear different
Xnot different --> 0.011  different --> 0.011  not different --> 0.011  
Xspiffword rem You get the idea. Enough fun for now.
XAll done.
END_OF_FILE
if test 2110 -ne `wc -c <'Sample.4'`; then
    echo shar: \"'Sample.4'\" unpacked with wrong size!
fi
# end of 'Sample.4'
fi
if test -f 'command.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'command.c'\"
else
echo shar: Extracting \"'command.c'\" \(3236 characters\)
sed "s/^X//" >'command.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: command.c,v 1.1 88/09/15 11:33:58 daniel Rel $";
X#endif
X
X
X#include "misc.h"
X#include "tol.h"
X#include "comment.h"
X#include "command.h"
X#include "strings.h"
X#include "parse.h"
X
X/*
X**	storage for the string that signals an embedded command
X*/
Xstatic char _C_cmdword[Z_WORDLEN];
X
X/*
X**	storage for the command script
X*/
Xstatic int _C_nextcmd = 0;
Xstatic char *_C_cmds[_C_CMDMAX];
X
X
X/*
X**	add a string to the command buffer
X*/
Xvoid
XC_addcmd(str)
Xchar *str;
X{
X	S_savestr(&_C_cmds[_C_nextcmd++],str);
X	return;
X}
X
X/*
X**	execute a single command
X*/
Xstatic void
X_C_do_a_cmd(str)
Xchar *str;
X{
X	/*
X	**	place holder for the beginning of the string
X	*/
X	char *beginning = str;
X
X	S_skipspace(&str);
X
X	/*
X	**	set the command string to allow embedded commands
X	*/
X	if 	(!S_wordcmp(str,"command"))
X	{
X		S_nextword(&str);
X		if (strlen(str) >= Z_WORDLEN)
X		{
X			Z_fatal("command word is too long");
X		}
X		S_wordcpy(_C_cmdword,str);
X	}
X	/*
X	**	set the tolerances
X	*/
X	else if (!S_wordcmp(str,"tol"))
X	{
X		S_nextword(&str);
X		T_tolline(str);
X	}
X	/*
X	**	add a comment specification
X	*/
X	else if (!S_wordcmp(str,"comment"))
X	{
X		S_nextword(&str);
X		if (strlen(str) >= Z_WORDLEN)
X		{
X			Z_fatal("command word is too long");
X		}
X		W_addcom(str,0);
X	}
X	else if (!S_wordcmp(str,"nestcom"))
X	{
X		S_nextword(&str);
X		if (strlen(str) >= Z_WORDLEN)
X		{
X			Z_fatal("command word is too long");
X		}
X		W_addcom(str,1);
X	}
X	/*
X	**	add a literal string specification
X	*/
X	else if (!S_wordcmp(str,"literal"))
X	{
X		S_nextword(&str);
X		if (strlen(str) >= Z_WORDLEN)
X		{
X			Z_fatal("command word is too long");
X		}
X		W_addlit(str);
X	}
X	else if (!S_wordcmp(str,"resetcomments"))
X	{
X		W_clearcoms();
X	}
X	else if (!S_wordcmp(str,"resetliterals"))
X	{
X		W_clearlits();
X	}
X	else if (!S_wordcmp(str,"beginchar"))
X	{
X		S_nextword(&str);
X		W_setbolchar(*str);
X	}
X	else if (!S_wordcmp(str,"endchar"))
X	{
X		S_nextword(&str);
X		W_seteolchar(*str);
X	}
X	else if (!S_wordcmp(str,"addalpha"))
X	{
X		S_nextword(&str);
X		P_addalpha(str);
X	}
X	else if ((0 == strlen(str)) || !S_wordcmp(str,"rem") 
X				    || ('#' == *str))
X	{
X		/* do nothing */
X	}
X	else
X	{
X		(void) sprintf(Z_err_buf,
X			       "don't understand command %s\n",
X			       beginning);
X		Z_fatal(Z_err_buf);
X	}
X	return;
X}
X
X/*
X**	execute the commands in the command buffer
X*/
Xvoid
XC_docmds()
X{
X	int i;
X	for (i=0;i<_C_nextcmd;i++)
X	{
X		_C_do_a_cmd(_C_cmds[i]);
X	}
X	return;
X}
X
X/*
X**	disable embedded command key word recognition
X*/
Xvoid
XC_clear_cmd()
X{
X	_C_cmdword[0] = '\0';
X	return;
X}
X
Xint
XC_is_cmd(inline)
Xchar *inline;
X{
X	char *ptr;
X	/*
X	**	see if this is a command line
X	**	and if so, do the command right away
X	*/
X	if (('\0' != _C_cmdword[0]) && (!S_wordcmp(inline,_C_cmdword)))
X	{
X		ptr = inline;
X		S_nextword(&ptr);
X		_C_do_a_cmd(ptr);
X		return(1);
X	}
X	return(0);
X}
X
END_OF_FILE
if test 3236 -ne `wc -c <'command.c'`; then
    echo shar: \"'command.c'\" unpacked with wrong size!
fi
# end of 'command.c'
fi
if test -f 'command.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'command.h'\"
else
echo shar: Extracting \"'command.h'\" \(582 characters\)
sed "s/^X//" >'command.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#ifndef C_INCLUDED
Xextern int C_is_cmd();
Xextern void C_clear_cmd();
Xextern void C_addcmd();
Xextern void C_docmds();
X
X#define _C_CMDMAX	100
X
X#define C_INCLUDED
X#endif
END_OF_FILE
if test 582 -ne `wc -c <'command.h'`; then
    echo shar: \"'command.h'\" unpacked with wrong size!
fi
# end of 'command.h'
fi
if test -f 'comment.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'comment.h'\"
else
echo shar: Extracting \"'comment.h'\" \(2036 characters\)
sed "s/^X//" >'comment.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#ifndef W_INCLUDED
X
X#include <stdio.h>
X
X#define _W_COMWORD	16
X#define _W_COMMAX	20
X#define _W_BOLMAX	20
X#define _W_LITMAX	20
X
X/*
X**	these three data structures used to be much
X**		different.  eventually, the differences
X**		have disappeared as the code has evolved.
X**		obviously, they should now be collapsed.
X**		someday . . .
X*/
Xtypedef struct {
X	char begin[_W_COMWORD];
X	char end[_W_COMWORD];
X	char escape[_W_COMWORD];
X} _W_bolstruct, *W_bol;
X
Xtypedef struct {
X	char begin[_W_COMWORD];
X	char end[_W_COMWORD];
X	char escape[_W_COMWORD];
X	int nestbit;
X} _W_comstruct, *W_com;
X
Xtypedef struct {
X	char begin[_W_COMWORD];
X	char end[_W_COMWORD];
X	char escape[_W_COMWORD];
X} _W_litstruct, *W_lit;
X
X#define W_bolbegin(ptr)		(ptr->begin)
X#define W_bolend(ptr)		(ptr->end)
X#define W_bolescape(ptr)	(ptr->escape)
X
X#define W_litbegin(ptr)		(ptr->begin)
X#define W_litend(ptr)		(ptr->end)
X#define W_litescape(ptr)	(ptr->escape)
X
X#define W_combegin(ptr)		(ptr->begin)
X#define W_comend(ptr)		(ptr->end)
X#define W_comescape(ptr)	(ptr->escape)
X
Xextern char _W_bolchar;
Xextern char _W_eolchar;
X
X#define W_setbolchar(x)		(_W_bolchar = x)
X#define W_seteolchar(x)		(_W_eolchar = x)
X
Xextern W_bol W_isbol();
Xextern W_lit W_islit();
Xextern W_com W_iscom();
X
Xextern int W_is_bol();
Xextern int W_is_lit();
Xextern int W_is_com();
X
Xextern _W_bolstruct _W_bols[];
Xextern _W_litstruct _W_lits[];
Xextern _W_comstruct _W_coms[];
X
Xextern void W_clearcoms();
Xextern void W_clearlits();
Xextern void W_addcom();
Xextern void W_addlit();
X
X#define W_BOLNULL		((W_bol)0)
X#define W_COMNULL		((W_com)0)
X#define W_LITNULL		((W_lit)0)
X
X#define W_INCLUDED
X#endif
END_OF_FILE
if test 2036 -ne `wc -c <'comment.h'`; then
    echo shar: \"'comment.h'\" unpacked with wrong size!
fi
# end of 'comment.h'
fi
if test -f 'compare.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'compare.h'\"
else
echo shar: Extracting \"'compare.h'\" \(482 characters\)
sed "s/^X//" >'compare.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#ifndef X_INCLUDED
X
Xextern int X_com();
X
X#define X_INCLUDED
X#endif
END_OF_FILE
if test 482 -ne `wc -c <'compare.h'`; then
    echo shar: \"'compare.h'\" unpacked with wrong size!
fi
# end of 'compare.h'
fi
if test -f 'edit.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'edit.h'\"
else
echo shar: Extracting \"'edit.h'\" \(1196 characters\)
sed "s/^X//" >'edit.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**	the naming information hiding conventions are incompletely implemented
X**	 for the edit module. I tried to clean it up once, but kept introducing
X**	 nasty (ie. core dump) bugs in the miller code.  I give up for now.
X*/
X#ifndef E_INCLUDED
X
X#define E_INSERT	1
X#define E_DELETE	2
X
Xtypedef struct edt {
X	struct edt *link;
X	int op;
X	int line1;
X	int line2;
X} _E_struct, *E_edit;
X
X#define E_setop(x,y)		((x)->op = (y))
X#define E_setl1(x,y)		((x)->line1 = (y))
X#define E_setl2(x,y)		((x)->line2 = (y))
X#define E_setnext(x,y)		((x)->link = (y))
X
X#define E_getop(x)		((x)->op)
X#define E_getl1(x)		((x)->line1)
X#define E_getl2(x)		((x)->line2)
X#define E_getnext(x)		((x)->link)
X
X#define E_NULL 		((E_edit) 0)
X#define E_edit_alloc()	(Z_ALLOC(1,_E_struct))
X
X#define E_INCLUDED
X
X#endif
X
X
END_OF_FILE
if test 1196 -ne `wc -c <'edit.h'`; then
    echo shar: \"'edit.h'\" unpacked with wrong size!
fi
# end of 'edit.h'
fi
if test -f 'exact.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'exact.c'\"
else
echo shar: Extracting \"'exact.c'\" \(2043 characters\)
sed "s/^X//" >'exact.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: exact.c,v 1.1 88/09/15 11:33:55 daniel Rel $";
X#endif
X
X#include "misc.h"
X#include "edit.h"
X
X/*
X**	routine to compare each object with its ordinal twin
X*/
XE_edit
XQ_do_exact(size1,size2,max_d,comflags)
Xint size1;
Xint size2;
Xint max_d;
Xint comflags;
X{
X	int i = 0;
X	int diffcnt = 0;
X	int last = Z_MIN(size1,size2);
X	int next_edit = 0;
X	E_edit last_ptr = E_NULL;
X	int start,tmp;
X	E_edit *script;
X
X	script = Z_ALLOC(max_d+1,E_edit);
X
X	if (size1 != size2)
X	{
X		(void) sprintf(Z_err_buf,"unequal number of tokens, %d and %d respectively\n",size1,size2);
X		Z_complain(Z_err_buf);
X	}
X
X	do
X	{
X		/*
X		**	skip identical objects
X		*/
X		while (i<last && (!X_com(i,i,comflags)))
X		{
X			i++;
X		}
X		start = i;
X		/*
X		**	see how many difference we have in a row
X		*/
X		while (i<last && X_com(i,i,comflags))
X		{
X			if ((diffcnt += 2) >= max_d+1)
X				Z_exceed(max_d);
X			i++;
X		}
X		/*
X		**	build the list of deletions
X		*/
X		for(tmp=start;tmp<i;tmp++,next_edit++)
X		{
X			script[next_edit] = E_edit_alloc();
X			E_setnext(script[next_edit],last_ptr);
X			last_ptr = script[next_edit];
X
X			E_setop(script[next_edit],E_DELETE);
X			E_setl1(script[next_edit],tmp+1);
X			/* no need to set line2, it is never used */
X			E_setl2(script[next_edit],0);
X		}
X		/*
X		**	build the list of insertions
X		*/
X		for(tmp=start;tmp<i;tmp++,next_edit++)
X		{
X			script[next_edit] = E_edit_alloc();
X			E_setnext(script[next_edit],last_ptr);
X			last_ptr = script[next_edit];
X
X			E_setop(script[next_edit],E_INSERT);
X			E_setl1(script[next_edit],i);
X			E_setl2(script[next_edit],tmp+1);
X		}
X	} while (i<last);
X
X	return(last_ptr);
X}
END_OF_FILE
if test 2043 -ne `wc -c <'exact.c'`; then
    echo shar: \"'exact.c'\" unpacked with wrong size!
fi
# end of 'exact.c'
fi
if test -f 'exact.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'exact.h'\"
else
echo shar: Extracting \"'exact.h'\" \(510 characters\)
sed "s/^X//" >'exact.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#ifndef Q_INCLUDED
X
X#include "edit.h"
X
Xextern E_edit Q_do_exact();
X
X#define Q_INCLUDED
X
X#endif
END_OF_FILE
if test 510 -ne `wc -c <'exact.h'`; then
    echo shar: \"'exact.h'\" unpacked with wrong size!
fi
# end of 'exact.h'
fi
if test -f 'flagdefs.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'flagdefs.h'\"
else
echo shar: Extracting \"'flagdefs.h'\" \(757 characters\)
sed "s/^X//" >'flagdefs.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**	flags used by both parser and comparison routines
X*/
X#define U_INCLUDE_WS	001
X
X/*
X**	flags used only by the comparison routines
X*/
X#define U_BYTE_COMPARE		002
X#define U_NO_CASE		004
X
X/*
X**	flag used by the output routine
X*/
X#define U_TOKENS		010
X
X/*
X**	flags used only by the parser
X*/
X#define U_INC_SIGN	020
X#define U_NEED_DECIMAL	040
END_OF_FILE
if test 757 -ne `wc -c <'flagdefs.h'`; then
    echo shar: \"'flagdefs.h'\" unpacked with wrong size!
fi
# end of 'flagdefs.h'
fi
if test -f 'float.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'float.h'\"
else
echo shar: Extracting \"'float.h'\" \(838 characters\)
sed "s/^X//" >'float.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#include "floatrep.h"
X
X#ifndef F_INCLUDED
X
X/*
X**	flags for F_atof
X*/
X#define NO_USE_ALL	0
X#define USE_ALL		1
X
Xtypedef struct R_flstr *F_float;
X#define F_getexp(x)	R_getexp(x)
X#define F_getsign(x)	R_getsign(x)
X#define F_zerofloat(x)	R_zerofloat(x)
X
Xextern F_float F_atof();
X
Xextern F_float F_floatmul();
Xextern F_float F_floatmagadd();
Xextern F_float F_floatsub();
X
X#define F_null	((F_float) 0)
X
X#define F_INCLUDED
X
X#endif
END_OF_FILE
if test 838 -ne `wc -c <'float.h'`; then
    echo shar: \"'float.h'\" unpacked with wrong size!
fi
# end of 'float.h'
fi
if test -f 'floatrep.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'floatrep.c'\"
else
echo shar: Extracting \"'floatrep.c'\" \(758 characters\)
sed "s/^X//" >'floatrep.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: floatrep.c,v 1.1 88/09/15 11:34:00 daniel Rel $";
X#endif
X
X#include "misc.h"
X#include "floatrep.h"
X
XR_float
XR_makefloat()
X{
X	R_float retval;
X
X	retval = Z_ALLOC(1,struct R_flstr);
X	retval->mantissa = Z_ALLOC(R_MANMAX,char);
X	return(retval);
X}
X
XR_getexp(ptr)
XR_float ptr;
X{
X	return(ptr->exponent);
X}
X
END_OF_FILE
if test 758 -ne `wc -c <'floatrep.c'`; then
    echo shar: \"'floatrep.c'\" unpacked with wrong size!
fi
# end of 'floatrep.c'
fi
if test -f 'floatrep.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'floatrep.h'\"
else
echo shar: Extracting \"'floatrep.h'\" \(1372 characters\)
sed "s/^X//" >'floatrep.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** header file that defines canonical floating point structure
X**	and routines
X*/
X
X
X#ifndef  R_INCLUDED
X
X/*
X**	when evaluated to a string, the fractional part will
X**		not exceed this length
X*/
X#define R_MANMAX	200
X
X#define R_POSITIVE	0
X#define R_NEGATIVE	1
X
Xstruct  R_flstr {
X	int exponent;
X	int man_sign;
X	char *mantissa;
X};
X
Xtypedef struct R_flstr *R_float;
X
X#define R_getfrac(x)	(x->mantissa)
X
Xextern R_float R_makefloat();
X
Xextern int R_getexp();
X
X#define R_getsign(x)	(x->man_sign)
X
X/*
X**	takes a string
X*/
X#define R_setfrac(x,y)	((void)strcpy(x->mantissa,y))
X/*
X**	takes an int
X*/
X#define R_setexp(x,y)	(x->exponent = y)
X/*
X**	takes a sign
X*/
X#define R_setsign(x,y)	(x->man_sign = y)
X
X/*
X#define R_incexp(x)	((x->exponent)++)
X#define R_decexp(x)	((x->exponent)--)
X*/
X
X#define R_setzero(x)	R_setfrac(x,"0");R_setexp(x,0);R_setsign(x,R_POSITIVE)
X
X#define R_zerofloat(x)	((0 == x->exponent) && (!strcmp(x->mantissa,"0")))
X
X#define R_INCLUDED
X
X#endif
END_OF_FILE
if test 1372 -ne `wc -c <'floatrep.h'`; then
    echo shar: \"'floatrep.h'\" unpacked with wrong size!
fi
# end of 'floatrep.h'
fi
if test -f 'miller.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'miller.c'\"
else
echo shar: Extracting \"'miller.c'\" \(2663 characters\)
sed "s/^X//" >'miller.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: miller.c,v 1.1 88/09/15 11:33:56 daniel Rel $";
X#endif
X
X#include "misc.h"
X#include "token.h"
X#include "edit.h"
X
X#define MAXT	K_MAXTOKENS
X#define ORIGIN (max_obj/2)
X
X#define MILLER_CHATTER	100
X
X/*
X**	totally opaque miller/myers code
X**		hacked from a version provided by the author
X*/
X
X
XE_edit
XG_do_miller(m,n,max_d,comflags)
Xint m;
Xint n;
Xint max_d;
Xint comflags;
X{
X    int	max_obj = m + n;
X    int
X	lower,
X	upper,
X	d,
X	k,
X	row,
X	col;
X	E_edit new;
X
X#ifdef STATIC_MEM
X	static E_edit script[MAXT+1];
X	static int last_d[MAXT+1];
X#else
X	E_edit *script;
X	int *last_d;
X	/*
X	**	make space for the two big arrays
X	**		these could probably be smaller if I
X	**		understood this algorithm at all
X	**		as is, i just shoe horned it into my program.
X	**	be sure to allocate max_obj + 1 objects as was done
X	**		in original miller/myers code
X	*/
X	script = Z_ALLOC(max_obj+1,E_edit);
X	last_d = Z_ALLOC(max_obj+1,int);
X
X#endif
X	for (row=0;row < m && row < n && X_com(row,row,comflags) == 0; ++row)
X		;
X	last_d[ORIGIN] = row;
X	script[ORIGIN] = E_NULL;
X	lower = (row == m) ? ORIGIN+1 : ORIGIN - 1;
X	upper = (row == n) ? ORIGIN-1 : ORIGIN + 1;
X	if (lower > upper)
X	{
X		/*
X		**	the files are identical
X		*/
X		return(E_NULL);
X	}
X	for (d = 1; d <= max_d; ++d) {
X		for (k = lower; k<= upper; k+= 2) {
X			new = E_edit_alloc();
X
X			if (k == ORIGIN-d || k!= ORIGIN+d && last_d[k+1] >= last_d[k-1]) {
X				row = last_d[k+1]+1;
X				E_setnext(new,script[k+1]);
X				E_setop(new,E_DELETE);
X			} else {
X				row = last_d[k-1];
X				E_setnext(new,script[k-1]);
X				E_setop(new,E_INSERT);
X			}
X
X			E_setl1(new,row);
X			col = row + k - ORIGIN;
X			E_setl2(new,col);
X			script[k] = new;
X
X			while (row < m && col < n && X_com(row,col,comflags) == 0) {
X				++row;
X				++col;
X			}
X			last_d[k] = row;
X			if (row == m && col == n) {
X				return(script[k]);
X			}
X			if (row == m)
X				lower = k+2;
X			if (col == n)
X				upper = k-2;
X		}
X		--lower;
X		++upper;
X#ifndef NOCHATTER
X		if ((d > 0) && (0 == (d % MILLER_CHATTER)))
X		{
X			(void) sprintf(Z_err_buf,
X				"found %d differences\n",
X				d);
X			Z_chatter(Z_err_buf);
X		}
X#endif
X	}
X	Z_exceed(max_d);
X	/*
X	**	dummy lines to shut up lint
X	*/
X	Z_fatal("fell off end of do_miller\n");
X	return(E_NULL);
X}
END_OF_FILE
if test 2663 -ne `wc -c <'miller.c'`; then
    echo shar: \"'miller.c'\" unpacked with wrong size!
fi
# end of 'miller.c'
fi
if test -f 'miller.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'miller.h'\"
else
echo shar: Extracting \"'miller.h'\" \(511 characters\)
sed "s/^X//" >'miller.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#ifndef G_INCLUDED
X
X#include "edit.h"
X
Xextern E_edit G_do_miller();
X
X#define G_INCLUDED
X
X#endif
END_OF_FILE
if test 511 -ne `wc -c <'miller.h'`; then
    echo shar: \"'miller.h'\" unpacked with wrong size!
fi
# end of 'miller.h'
fi
if test -f 'misc.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'misc.c'\"
else
echo shar: Extracting \"'misc.c'\" \(1953 characters\)
sed "s/^X//" >'misc.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: misc.c,v 1.1 88/09/15 11:34:01 daniel Rel $";
X#endif
X
X#include <stdio.h>
X#include "misc.h"
X#include "visual.h"
X#include "output.h"
X
X/*
X**	various routines used throughout the program
X*/
X
Xstatic int _Z_qflag = 0;
X
Xvoid
XZ_setquiet()
X{
X	_Z_qflag = 1;
X}
X
Xchar Z_err_buf[Z_LINELEN];
X
X#ifndef NOCHATTER
X/*
X**	I/O coverup to reassure users with HUGE files
X**	that spiff is doing something
X*/
Xvoid
XZ_chatter(str)
Xchar *str;
X{
X	if (!_Z_qflag)
X	{
X		(void) fputs("spiff -- ",stderr);
X		(void) fputs(str,stderr);
X	}
X}
X#endif
X
X/*
X**	complain unless you've been told to be quiet
X*/
Xvoid
XZ_complain(str)
Xchar *str;
X{
X	if (!_Z_qflag)
X		(void) fputs(str,stderr);
X}
X
X/*
X**	quit with an error code
X*/
Xstatic void
X_Z_errexit()
X{
X	(void) exit(2);
X}
X
X/*
X**	complain and die
X*/
Xvoid
X_Z_qfatal(str)
Xchar *str;
X{
X	V_cleanup();	/* try reset the device to normal */
X	O_cleanup();	/*  "    "    "     "   "    "    */
X	Z_complain(str);
X	_Z_errexit();
X}
X
X/*
X**	scream and die
X*/
Xvoid
XZ_fatal(str)
Xchar *str;
X{
X	V_cleanup();	/* try reset the device to normal */
X	O_cleanup();	/*  "    "    "     "   "    "    */
X	(void) fputs(str,stderr);
X	_Z_errexit();
X}
X
X/*
X**	allocate memory with error checking
X*/
Xint*
X_Z_myalloc(k)
Xint k;
X{
X	int *tmp;
X	if (tmp = (int*) calloc((unsigned)k,(unsigned)1))
X	{
X		return(tmp);
X	}
X	Z_fatal("Out of Memory\n");
X	return(tmp);	/* boilerplate to shut up lint */
X}
X
Xvoid
XZ_exceed(d)
Xint d;
X{
X	(void) sprintf(Z_err_buf,
X		"The files differ in more than %d places\n", d);
X	_Z_qfatal(Z_err_buf);
X}
END_OF_FILE
if test 1953 -ne `wc -c <'misc.c'`; then
    echo shar: \"'misc.c'\" unpacked with wrong size!
fi
# end of 'misc.c'
fi
if test -f 'misc.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'misc.h'\"
else
echo shar: Extracting \"'misc.h'\" \(1269 characters\)
sed "s/^X//" >'misc.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#ifndef Z_INCLUDED
X
X/*
X**	make sure that if we have a XENIX system, that
X**	we also treat it as an AT and T derivative
X*/
X#ifdef XENIX
X#ifndef ATT
X#define ATT
X#endif
X#endif
X
X#define	Z_LINELEN	1024
X#define	Z_WORDLEN	  20
X
Xextern char Z_err_buf[];
X
X/*
X**	helpful macros
X*/
X#define Z_ABS(x)	(( (x) < (0) )? (-(x)):(x))
X#define Z_MIN(x,y)	(( (x) < (y) )? (x):(y))
X#define Z_MAX(x,y)	(( (x) > (y) )? (x):(y))
X
X#define Z_ALLOC(n,type)	((type*) _Z_myalloc((n) * sizeof (type)))
Xextern int *_Z_myalloc();
X
X/*
X**	lines needed to shut up lint
X*/
Xextern char *sprintf();
Xextern char *strcat();
Xextern char *strncat();
Xextern char *strcpy();
Xextern char *strncpy();
Xextern char *malloc();
X
Xextern void Z_complain();
Xextern void Z_fatal();
Xextern void Z_exceed();
Xextern void Z_setquiet();
X#ifndef NOCHATTER
Xextern void Z_chatter();
X#endif
X
X#define Z_INCLUDED
X#endif
END_OF_FILE
if test 1269 -ne `wc -c <'misc.h'`; then
    echo shar: \"'misc.h'\" unpacked with wrong size!
fi
# end of 'misc.h'
fi
if test -f 'output.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'output.h'\"
else
echo shar: Extracting \"'output.h'\" \(513 characters\)
sed "s/^X//" >'output.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 O_INCLUDED
X
Xextern void O_output();
Xextern void O_cleanup();
X
X#define O_INCLUDED
X
X#endif
END_OF_FILE
if test 513 -ne `wc -c <'output.h'`; then
    echo shar: \"'output.h'\" unpacked with wrong size!
fi
# end of 'output.h'
fi
if test -f 'parse.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'parse.h'\"
else
echo shar: Extracting \"'parse.h'\" \(469 characters\)
sed "s/^X//" >'parse.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
Xextern void P_file_parse();
Xextern void P_addalpha();
END_OF_FILE
if test 469 -ne `wc -c <'parse.h'`; then
    echo shar: \"'parse.h'\" unpacked with wrong size!
fi
# end of 'parse.h'
fi
if test -f 'strings.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'strings.c'\"
else
echo shar: Extracting \"'strings.c'\" \(2859 characters\)
sed "s/^X//" >'strings.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: strings.c,v 1.1 88/09/15 11:33:54 daniel Rel $";
X#endif
X
X#include <ctype.h>
X#include "misc.h"
X#include "strings.h"
X
X/*
X**	routines for handling strings.
X**		several routines manipulate  "words"
X**		a "word" is a string not containing whitespace
X*/
X
X/*
X**	copy a single word. similar to  strcpy
X*/
Xvoid
XS_wordcpy(to,from)
Xchar *to, *from;
X{
X	while ((*from != '\0') && isprint(*from) && (!isspace(*from)))
X	{
X		*to++ = *from++;
X	}
X	*to = '\0';
X	return;
X}
X
X/*
X**	find the next whitespace character.  The address of the pointer
X**		is passed and the pointer itself is changed.
X*/
Xvoid
XS_skipword(theptr)
Xchar **theptr;
X{
X	while((**theptr != '\0') && isprint(**theptr) && (!isspace(**theptr)))
X	{
X		(*theptr)++;	/* increment the pointer, NOT the pointer
X					to the pointer */
X	}
X	return;
X}
X
X/*
X**	find the next non-whitespace character.  The address of the pointer
X**		is passed and the pointer itself is changed.
X*/
Xvoid
XS_skipspace(theptr)
Xchar **theptr;
X{
X	while((**theptr != '\0') && isspace(**theptr))
X	{
X		(*theptr)++;	/* increment the pointer, NOT the pointer
X					to the pointer */
X	}
X	return;
X}
X
X/*
X**	move the pointer to the beginning of the next word
X*/
Xvoid
XS_nextword(theptr)
Xchar **theptr;
X{
X	S_skipword(theptr);
X	S_skipspace(theptr);
X	return;
X}
X
X/*
X**	see if the first string is a prefix of the second
X**		returns 0 if yes
X**		non zero if now
X**		sigh -- the way strcmp does
X*/
Xint
XS_wordcmp(s1,s2)
Xchar *s1,*s2;
X{
X	return(strncmp(s1,s2,strlen(s2)));
X}
X
X/*
X**	chop off any trailing zeros on a string
X**		but leave one zero if there are only zeros
X*/
Xvoid
XS_trimzeros(str)
Xchar *str;
X{
X	/*
X	**	end starts out pointing at the null terminator
X	*/
X	char *end = str + strlen(str);
X
X	/*
X	**	if there is more than one character left in the string
X	*/
X	while(end > (str+1))
X	{
X		--end;
X		if ('0' == *end)
X		{
X			*end = '\0';
X		}
X		else
X		{
X			return;
X		}
X	}
X	return;
X}
X
X/*
X**	save a copy of the string
X*/
Xvoid
XS_savestr(to,from)
Xchar **to,*from;
X{
X	S_allocstr(to,strlen(from));
X	(void) strcpy(*to,from);
X	return;
X}
X
X/*
X**	save cnt characters of the string
X*/
Xvoid
XS_savenstr(to,from,cnt)
Xchar **to,*from;
X{
X	S_allocstr(to,cnt);
X	(void) strncpy(*to,from,cnt);
X	*((*to)+cnt) = '\0';
X	return;
X}
X
X/*
X**	allocate space for a string,  add 1 to size to
X**		make sure that there is room for the terminating null character
X*/
Xvoid
XS_allocstr(to,size)
Xchar **to;
Xint size;
X{
X	*to = Z_ALLOC(size+1,char);
X}
END_OF_FILE
if test 2859 -ne `wc -c <'strings.c'`; then
    echo shar: \"'strings.c'\" unpacked with wrong size!
fi
# end of 'strings.c'
fi
if test -f 'strings.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'strings.h'\"
else
echo shar: Extracting \"'strings.h'\" \(693 characters\)
sed "s/^X//" >'strings.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#ifndef S_INCLUDED
Xextern void S_wordcpy();
Xextern void S_skipword();
Xextern void S_skipspace();
Xextern void S_nextword();
Xextern int  S_wordcmp();
Xextern void S_trimzeros();
Xextern void S_savestr();
Xextern void S_savenstr();
Xextern void S_allocstr();
X#define S_INCLUDED
X#endif
END_OF_FILE
if test 693 -ne `wc -c <'strings.h'`; then
    echo shar: \"'strings.h'\" unpacked with wrong size!
fi
# end of 'strings.h'
fi
if test -f 'token.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'token.c'\"
else
echo shar: Extracting \"'token.c'\" \(823 characters\)
sed "s/^X//" >'token.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: token.c,v 1.1 88/09/15 11:34:01 daniel Rel $";
X#endif
X
X#include "misc.h"
X#include "token.h"
X
XK_token _K_ato[K_MAXTOKENS]; /* storage for tokens */
XK_token _K_bto[K_MAXTOKENS];
X
Xint _K_atm;
Xint _K_btm;
X
Xvoid
XK_settoken(file,index,pointer)
Xint file;
Xint index;
XK_token pointer;
X{
X	if (file)
X	{
X		_K_bto[index] = pointer;
X	}
X	else
X	{
X		_K_ato[index] = pointer;
X	}
X}
END_OF_FILE
if test 823 -ne `wc -c <'token.c'`; then
    echo shar: \"'token.c'\" unpacked with wrong size!
fi
# end of 'token.c'
fi
if test -f 'token.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'token.h'\"
else
echo shar: Extracting \"'token.h'\" \(2203 characters\)
sed "s/^X//" >'token.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 K_INCLUDED
X#include "float.h"
X#include "tol.h"
X#include "strings.h"
X
X#define		K_MAXTOKENS	50000
X/*
X**	values for token type
X*/
X#define K_LIT		1
X#define	K_FLO_NUM	2
X
X
Xtypedef struct {
X	int linenum;		/* line that the token started on */
X	int pos;		/* position on the line where token started */
X	int type;		/* token type */
X	char *text;	 	/* literal token text */
X	/*
X	**	canonical floationg point representation
X	*/
X	F_float flo_num;
X	T_tol tolerance;
X} _K_str, *K_token;
X
X/*
X**	this should really be a two dimensional array
X**	but i'm too lazy to recode it
X*/
Xextern K_token _K_ato[];	/* storage for the tokens */
Xextern K_token _K_bto[];
X/*
X**	save token X from file
X*/
Xextern void K_settoken(/*file,X,ptr*/);
X#define K_gettoken(file, X)	(file?(_K_bto[X]):(_K_ato[X]))
X
Xextern int _K_atm;	/* count of tokens */
Xextern int _K_btm;
X
X/*
X**	get token number X from file
X*/
X#define K_get_token(file, X)	(file?(_K_bto[X]):(_K_ato[X]))
X
X#define K_gettmax(file)		(file?_K_btm:_K_atm)
X#define K_settmax(file,value)	(file?(_K_btm=(value)):(_K_atm=(value)))
X/*
X**	increment and return true on overflow
X*/
X#define	K_inctmax(file)		((file?(++_K_btm):(++_K_atm))>=K_MAXTOKENS)
X
X#define K_setline(x,y)		(x->linenum = y)
X#define K_setpos(x,y)		(x->pos = y)
X#define K_settext(x,y)		(x->text = y)
X#define K_savetext(x,y,z)	S_savestr(&(x->text),y)
X#define K_saventext(x,y,z)	S_savenstr(&(x->text),y,z)
X#define K_setfloat(x,y)		(x->flo_num = y)
X#define K_settol(x,y)		(x->tolerance = y)
X#define K_settype(x,y)		(x->type = y)
X
X#define K_getline(x)		(x->linenum)
X#define K_getpos(x)		(x->pos)
X#define K_gettext(x)		(x->text)
X#define K_getfloat(x)		(x->flo_num)
X#define K_gettol(x)		(x->tolerance)
X#define K_gettype(x)		(x->type)
X
X#define K_maketoken()		(Z_ALLOC(1,_K_str))
X
X#define K_INCLUDED
X#endif
END_OF_FILE
if test 2203 -ne `wc -c <'token.h'`; then
    echo shar: \"'token.h'\" unpacked with wrong size!
fi
# end of 'token.h'
fi
if test -f 'tol.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tol.h'\"
else
echo shar: Extracting \"'tol.h'\" \(1754 characters\)
sed "s/^X//" >'tol.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#include "float.h"
X
X#ifndef T_INCLUDED
X/*
X**	values for tol_type
X*/
X#define T_ABSOLUTE 		0
X#define T_RELATIVE 		1
X#define T_IGNORE		2
X
Xtypedef struct _T_tstr{
X	int tol_type;		/* one of the above */
X	F_float flo_tol;	/* tolerance is expressed in
X				    terms of a floating point value */
X	struct _T_tstr *next;
X} _T_struct, *T_tol;
X
X#define _T_TOLMAX	10	/* number of tolerances that can
X					be in effect at one time */
X
X#define _T_ADEF		"1e-10"	/* default absolute tolerance */
X#define _T_RDEF		"1e-10"	/* default relative tolerance */
X
Xextern T_tol T_gettol();
Xextern void T_clear_tols();
Xextern void T_initdefault();
Xextern void T_setdef();
Xextern void T_tolline();
Xextern T_tol T_picktol();
X
X#define T_gettype(x)	(x->tol_type)
X#define T_getfloat(x)	(x->flo_tol)
X#define T_getnext(x)	(x->next)
X
X#define T_settype(x,y)	(x->tol_type = y)
X#define T_setfloat(x,y)	(x->flo_tol = y)
X#define T_setnext(x,y)	(x->next = y)
X
X#define _T_null		((T_tol) 0)
X#define T_isnull(x)	((x) == _T_null)
X
Xextern T_tol _T_gtol;
Xextern void _T_addtol();
Xextern void _T_appendtols();
X
X/*
X**	routines for building the global tolerance list
X*/
X#define T_defatol(x)	_T_addtol(&_T_gtol,T_ABSOLUTE,x)
X#define T_defrtol(x)	_T_addtol(&_T_gtol,T_RELATIVE,x)
X#define T_defitol()	_T_addtol(&_T_gtol,T_IGNORE,(char*)NULL)
X
X#define _T_SEPCHAR	';'
X
X#define T_INCLUDED
X#endif
END_OF_FILE
if test 1754 -ne `wc -c <'tol.h'`; then
    echo shar: \"'tol.h'\" unpacked with wrong size!
fi
# end of 'tol.h'
fi
if test -f 'visual.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'visual.h'\"
else
echo shar: Extracting \"'visual.h'\" \(490 characters\)
sed "s/^X//" >'visual.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 V_INCLUDED
X
X
Xextern void V_cleanup();
X
X#define V_INCLUDED
X
X#endif
END_OF_FILE
if test 490 -ne `wc -c <'visual.h'`; then
    echo shar: \"'visual.h'\" unpacked with wrong size!
fi
# end of 'visual.h'
fi
echo shar: End of archive 1 \(of 4\).
cp /dev/null ark1isdone
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.