Subject: v16i067: Spiff, find approximate differences in files, Part01/04 Newsgroups: comp.sources.unix Sender: sources Approved: rsalz@uunet.UU.NET Submitted-by: Daniel W Nachbar 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 '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 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= max_d+1) X Z_exceed(max_d); X i++; X } X /* X ** build the list of deletions X */ X for(tmp=start;tmp'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 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 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