home *** CD-ROM | disk | FTP | other *** search
-
- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- :
- : 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 *)
-
-