home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols000
/
vol019
/
compare.bbb
< prev
next >
Wrap
Text File
|
1984-04-29
|
11KB
|
376 lines
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:
: I got this program from a UCSD PASCAL USERS GROUP and as
: such it will not run immediately. Why is it here? I included
: it to give you folks out there practice in converting from UCSD
: to Pascal/Z. Once you have done it (and it runs) it would be
: nice to give it to our users group. We help you, you help us.
: I'll be including a UCSD on each volume so we can get the group
: to help updating various programs that are around and are public
: domain.
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
{Program to compare two sourcecode files and output the differences,
if any. Useful to compare two similar textfiles to find out whether and
where they have been changed. Part of original UCSD I.4 release--author
is unknown.}
PROGRAM SRCCOM; (* SOURCE COMPARE *)
CONST
VERSION = 'v202 27-Oct-77';
MINLINESFORMATCH = 6;
MAXTRY = 150; (*<<<10/27/77 GLH. LIMIT ON SEARCH AHEAD FOR MATCH*)
LINELENGTH = 90;
TYPE
LINEPOINTER = ^LINE;
LINE =
RECORD (*<<<10/26/77 GLH*)
NEXTLINE : LINEPOINTER;
IMAGE : STRING[LINELENGTH]
END;
STREAM =
RECORD
CURSOR, HEAD, TAIL : LINEPOINTER;
CURSORLINENO, HEADLINENO, TAILLINENO : INTEGER;
ENDFILE : BOOLEAN
END;
VAR
TITLEA, TITLEB : STRING; (*<<<10/27/77 GLH*)
FILEA, FILEB : TEXT;
A, B : STREAM;
MATCH : BOOLEAN;
ENDFILE : BOOLEAN;
TEMPLINE : STRING[LINELENGTH]; (*<<<10/26/77 GLH*)
FREELINES : LINEPOINTER;
SAME : BOOLEAN;
PROCEDURE COMPARE;
FUNCTION ENDSTREAM(VAR X : STREAM) : BOOLEAN;
BEGIN (* ENDSTREAM *)
ENDSTREAM := (X.CURSOR = NIL) AND X.ENDFILE
END; (* ENDSTREAM *)
PROCEDURE MARK(VAR X : STREAM);
(* CAUSES BEGINNING OF STREAM TO BE POSITIONED BEFORE *)
(* CURRENT STREAM CURSOR. BUFFERS GET RECLAIMED, LINE *)
(* COUNTERS RESET, ETC. *)
PROCEDURE COLLECT(FWA, LWAPLUS1 : LINEPOINTER);
VAR P : LINEPOINTER;
BEGIN (* COLLECT *)
WHILE FWA <> LWAPLUS1 DO
BEGIN P := FWA^.NEXTLINE;
FWA^.NEXTLINE := FREELINES; FREELINES := FWA;
FWA := P
END
END; (* COLLECT *)
BEGIN (* MARK *)
IF X.HEAD <> NIL THEN
BEGIN
COLLECT(X.HEAD, X.CURSOR);
X.HEAD := X.CURSOR; X.HEADLINENO := X.CURSORLINENO;
IF X.CURSOR = NIL THEN
BEGIN X.TAIL := NIL; X.TAILLINENO := X.CURSORLINENO END
END
END; (* MARK *)
PROCEDURE MOVECURSOR(VAR X : STREAM; VAR FILEX : TEXT);
(* FILEX IS THE INPUT FILE ASSOCIATED WITH STREAM X. THE *)
(* CURSOR FOR X IS MOVED FORWARD ONE LINE, READING FROM X *)
(* IF NECESSARY, AND INCREMENTING THE LINE COUNT. ENDFILE *)
(* IS SET IF EOF ENCOUNTERED ON EITHER STREAM. *)
PROCEDURE READLINE;
VAR
I : INTEGER;
CH : CHAR;
NEWLINE : LINEPOINTER;
C, C2 : 0..LINELENGTH;
BEGIN (* READLINE *)
IF NOT X.ENDFILE THEN
BEGIN
C := 0;
(*<<<10/26/77 GLH. CHANGED WAY CHARS GET INTO TEMPLINE*)
READ(FILEX, TEMPLINE);
NEWLINE := FREELINES;
IF NEWLINE = NIL THEN NEW(NEWLINE)
ELSE FREELINES := FREELINES^.NEXTLINE;
NEWLINE^.IMAGE := TEMPLINE; (*<<<10/26/77 GLH*)
NEWLINE^.NEXTLINE := NIL;
IF X.TAIL = NIL THEN
BEGIN X.HEAD := NEWLINE;
X.TAILLINENO := 1; X.HEADLINENO := 1
END
ELSE
BEGIN X.TAIL^.NEXTLINE := NEWLINE;
X.TAILLINENO := X.TAILLINENO + 1
END;
X.TAIL := NEWLINE;
X.ENDFILE := EOF(FILEX);
END
END; (* READLINE *)
BEGIN (* MOVECURSOR *)
IF X.CURSOR <> NIL THEN
BEGIN
IF X.CURSOR = X.TAIL THEN READLINE;
X.CURSOR := X.CURSOR^.NEXTLINE;
IF X.CURSOR = NIL THEN ENDFILE := TRUE;
X.CURSORLINENO := X.CURSORLINENO + 1
END
ELSE
IF NOT X.ENDFILE THEN (* BEGINNING OF STREAM *)
BEGIN
READLINE; X.CURSOR := X.HEAD;
X.CURSORLINENO := X.HEADLINENO
END
ELSE (* END OF STREAM *)
ENDFILE := TRUE;
END; (* MOVECURSOR *)
PROCEDURE BACKTRACK(VAR X : STREAM; VAR XLINES : INTEGER);
(* CAUSES THE CURRENT POSITION OF STREAM THE NEW CURRENT *)
(* THE LINE COUNTER IS RETURNED IN XLINES. IT IS THE NUMBER *)
(* OF THE CURRENT LINE (BEFORE BACKTRACK) RELATIVE TO BEGINNING *)
(* OF STREAM. *)
BEGIN (* BACKTRACK *)
XLINES := X.CURSORLINENO + 1 - X.HEADLINENO;
X.CURSOR := X.HEAD; X.CURSORLINENO := X.HEADLINENO;
ENDFILE := ENDSTREAM(A) OR ENDSTREAM(B)
END; (* BACKTRACK *)
PROCEDURE COMPARELINES(VAR MATCH : BOOLEAN);
(* COMPARE THE CURRENT LINES OF STREAMS A AND B, RETURNING *)
(* MATCH TO SIGNAL THEIR (NON-) EQUIVALENCE. EOF ON BOTH STREAMS *)
(* IS CONSIDERED A MATCH, BUT EOF ON ONLY ONE STREAM IS A MISMATCH *)
BEGIN (* COMPARELINES *)
IF (A.CURSOR = NIL) OR (B.CURSOR = NIL) THEN
MATCH := ENDSTREAM(A) AND ENDSTREAM(B)
ELSE
MATCH := (A.CURSOR^.IMAGE = B.CURSOR^.IMAGE)
END; (* COMPARELINES *)
PROCEDURE FINDMISMATCH;
BEGIN (* FINDMISMATCH *)
(* NOT ENDFILE AND MATCH *)
REPEAT (* COMPARENEXTLINES *)
MOVECURSOR(A, FILEA); MOVECURSOR(B,FILEB);
MARK(A); MARK(B);
COMPARELINES(MATCH)
UNTIL ENDFILE OR NOT MATCH;
END; (* FINDMISMATCH *)
PROCEDURE FINDMATCH;
VAR
TRYCOUNT : INTEGER;
PROCEDURE SEARCH(VAR X : STREAM; (* STREAM TO SEARCH *)
VAR FILEX : TEXT;
VAR Y : STREAM; (* STREAM TO LOOKAHEAD *)
VAR FILEY : TEXT);
(* LOOK AHEAD ONE LINE ON STREAM Y, AND SEARCH FOR THAT LINE *)
(* BACKTRACKING ON STREAM X. *)
VAR
COUNT : INTEGER; (* NUMBER OF LINES BACKTRACKED ON X *)
PROCEDURE CHECKFULLMATCH;
(* FROM THE CURRENT POSITIONS IN X AND Y, WHICH MATCH, *)
(* MAKE SURE THAT THE NEXT MINLINESFORMATCH-1 LINES ALSO *)
(* MATCH, OR ELSE SET MATCH := FALSE. *)
VAR
N : INTEGER;
SAVEXCUR, SAVEYCUR : LINEPOINTER;
SAVEXLINE, SAVEYLINE : INTEGER;
BEGIN (* CHECKFULLMATCH *)
SAVEXCUR := X.CURSOR; SAVEYCUR := Y.CURSOR;
SAVEXLINE := X.CURSORLINENO; SAVEYLINE := Y.CURSORLINENO;
COMPARELINES(MATCH);
N := MINLINESFORMATCH - 1;
WHILE MATCH AND (N <> 0) DO
BEGIN MOVECURSOR(X, FILEX); MOVECURSOR(Y, FILEY);
COMPARELINES(MATCH); N := N - 1
END;
X.CURSOR := SAVEXCUR; X.CURSORLINENO := SAVEXLINE;
Y.CURSOR := SAVEYCUR; Y.CURSORLINENO := SAVEYLINE;
END; (* CHECKFULLMATCH *)
BEGIN (* SEARCH *)
MOVECURSOR(Y, FILEY); BACKTRACK(X, COUNT);
CHECKFULLMATCH; COUNT := COUNT - 1;
WHILE (COUNT <> 0) AND NOT MATCH DO
BEGIN
MOVECURSOR(X, FILEX); COUNT := COUNT - 1;
CHECKFULLMATCH
END
END; (* SEARCH *)
PROCEDURE PRINTMISMATCH;
VAR
EMPTYA, EMPTYB : BOOLEAN;
PROCEDURE WRITETEXT(P, Q : LINEPOINTER);
BEGIN (* WRITETEXT *)
WRITELN;
WHILE (P <> NIL) AND (P <> Q) DO
BEGIN WRITE(' * ');
WRITELN (P^.IMAGE);
P := P^.NEXTLINE
END;
IF P = NIL THEN WRITELN(' *** EOF ***');
WRITELN
END; (* WRITETEXT *)
PROCEDURE WRITELINENO(VAR X : STREAM);
VAR
F, L : INTEGER;
BEGIN (* WRITELINENO *)
F := X.HEADLINENO; L := X.CURSORLINENO - 1;
WRITE('LINE');
IF F = L THEN WRITE(' ', F)
ELSE WRITE('S ', F, ' TO ', L);
IF X.CURSOR = NIL THEN WRITE(' (BEFORE EOF)');
END; (* WRITELINENO *)
PROCEDURE PRINTEXTRATEXT(VAR X : STREAM; XNAME : STRING;
VAR Y : STREAM; YNAME : STRING);
BEGIN (* PRINTEXTRATEXT *)
WRITE(' EXTRA TEXT ON ', XNAME, ', ');
WRITELINENO(X); WRITELN;
IF Y.HEAD = NIL THEN
WRITELN(' BEFORE EOF ON ', YNAME)
ELSE
WRITELN(' BETWEEN LINES ', Y.HEADLINENO-1, ' AND ',
Y.HEADLINENO, ' OF ', YNAME);
WRITETEXT(X.HEAD, X.CURSOR)
END; (* PRINTEXTRATEXT *)
BEGIN (* PRINTMISMATCH *)
WRITELN(' ***********************************');
EMPTYA := (A.HEAD = A.CURSOR);
EMPTYB := (B.HEAD = B.CURSOR);
IF EMPTYA OR EMPTYB THEN
IF EMPTYA THEN PRINTEXTRATEXT(B, TITLEB, A, TITLEA)
ELSE PRINTEXTRATEXT(A, TITLEA, B, TITLEB)
ELSE
BEGIN
WRITELN(' MISMATCH:'); WRITELN;
WRITE(' ', TITLEA, ', '); WRITELINENO(A); WRITELN(':');
WRITETEXT(A.HEAD, A.CURSOR);
WRITE(' ', TITLEB, ', '); WRITELINENO(B); WRITELN(':');
WRITETEXT(B.HEAD, B.CURSOR)
END
END; (* PRINTMISMATCH *)
BEGIN (* FINDMATCH *)
TRYCOUNT := 0;
WHILE (NOT MATCH) AND (TRYCOUNT <= MAXTRY) DO
BEGIN
SEARCH(A, FILEA, B, FILEB);
TRYCOUNT := TRYCOUNT+1;
END;
IF NOT MATCH THEN
BEGIN
TRYCOUNT:=0;
WHILE (NOT MATCH) AND (TRYCOUNT<=MAXTRY) DO
BEGIN
SEARCH(B, FILEB, A, FILEA);
TRYCOUNT:=TRYCOUNT+1;
END;
END;
PRINTMISMATCH;
IF (NOT MATCH) AND (TRYCOUNT>MAXTRY) THEN
BEGIN MARK(A); MARK(B) END;
END; (* FINDMATCH *)
BEGIN (* COMPARE *)
ENDFILE := FALSE; MATCH := TRUE; (* I.E., BOI MATCHES BOI *)
REPEAT
IF MATCH THEN FINDMISMATCH ELSE BEGIN SAME := FALSE; FINDMATCH END
UNTIL ENDFILE AND MATCH;
MARK(A); MARK(B); (* MARK END OF FILES, THEREBY DISPOSING BUFFERS *)
END; (* COMPARE *)
PROCEDURE INITSTREAM(VAR X : STREAM; VAR FILEX : TEXT);
BEGIN (* INITSTREAM *)
X.CURSOR := NIL; X.HEAD := NIL; X.TAIL := NIL;
X.CURSORLINENO := 0; X.HEADLINENO := 0; X.TAILLINENO := 0;
X.ENDFILE := EOF(FILEX);
END; (* INITSTREAM *)
BEGIN (* SRCCOM *)
WRITELN('INPUT FILE NAME:'); READLN(TITLEA);
OPENOLD(FILEA, TITLEA);
WRITELN('SECOND INPUT FILE NAME:'); READLN(TITLEB);
OPENOLD(FILEB, TITLEB);
RESET(FILEA); RESET(FILEB);
INITSTREAM(A, FILEA); INITSTREAM(B, FILEB);
FREELINES := NIL;
WRITELN('Source Compare [', VERSION, ']' );
WRITELN;
IF EOF(FILEA) THEN
BEGIN WRITELN(TITLEA, ' IS EMPTY.');
IF EOF(FILEB) THEN WRITELN(TITLEB, ' IS EMPTY.')
END
ELSE
IF EOF(FILEB) THEN WRITELN(TITLEB, ' IS EMPTY.')
ELSE
BEGIN SAME := TRUE;
COMPARE;
IF SAME THEN WRITELN('No differences encountered.');
END
END. (* SRCCOM *)