home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
DATABASE
/
DBLIST11.LBR
/
DBLIST.PZS
/
DBLIST.PAS
Wrap
Pascal/Delphi Source File
|
2000-06-30
|
18KB
|
658 lines
Program DBLIST11(input,output);
{This program produces a cross-reference listing for a
DBASEII program. Occurences only are listed. No distinction is
made between definitions and references. It will also give a
graphical representation of the block structure of the program.
Note: This program was originally written by N. Wirth. It was
adapted for UCSD Pascal (1.4) by Shawn Fanning in 1978 and
subsequently adopted for Pascal/MT+ by Mike Lehman in 1981.
It was modified by Warren A. Smith to try to get back to ISO
standard pascal and to add the additional features of mapping
out the compound statements. It was adapted for Turbo Pascal
by Ron Finger in July 1984. Further modified by William Mabes
and Larry Clive in October, 1986.
DBLIST11 developed by Ellis B. Levin -Chicago, IL
to analyze DBASE II programs in June, 1987}
{$I-}
{$V-}
Const
P = 749; {SIZE of HASHTABLE}
NK = 82; {NO. of KEYWORDS}
PAGESIZE = 65; { LINES PER PAGE}
ALFALEN = 16; { SIZE of IDENTIFIERS}
REFSPERLINE = 8;
REFSPERITEM = 8;
NESTMAX = 21 ;
Type
Str80 = string[80];
FNAME = STRING[14];
ALFA = Packed Array[1..ALFALEN] of Char;
INDEX = 0..P;
ITEMPTR = ^ITEM;
WORD = Record
KEY: ALFA;
FIRST, LAST: ITEMPTR;
FOL: INDEX
End ;
NUMREFS = 1..REFSPERITEM;
REFTYPE = (COUNT, PTR);
ITEM = Record
REF : ARRAY[NUMREFS] of Integer;
CASE REFTYPE of
COUNT: (REFNUM: NUMREFS);
PTR: (NEXT: ITEMPTR)
End ;
BUFFER = STRING[131]{Packed Array[0..131] of Char};
Var
TOP: INDEX; {TOP of CHAIN LINKING ALL ENTRIES IN T}
I,LINECOUNT,BUFCURSOR: Integer; {CURRENT LINE NUMBER}
FF,CH: Char; {CURRENT CHAR SCANNED }
WORKSTRING,BUF : BUFFER;
T : ARRAY [INDEX] of WORD; {HASH TABLE}
KEY: ARRAY [1..NK] of ALFA; {RESERVED KEYWORD TABLE }
ERROR, { ERROR FLAG }
BLOCK,LISTING: Boolean; { LISTING/BLOCK OPTION }
INFILE,LST: Text;
LSTFILENAME : String[14];
INPUT_LINE : BUFFER{ String[120]};
LAST_KEY,PAGE_NUM,NESTLVL:Integer;
ABORT,LITERAL,ACOMMENT,BCOMMENT,EOL,NESTUP,NESTDN,
NODOT,Nextime,nex2time,nex3time:Boolean;
BAR : Char ;
FILENAME,FILETITLE:FNAME {String[14]};
DATE:String[20];
LDATE,LTITLE:Byte;
search1,search2, search3, search4: string[5];
PROCEDURE PROCESSLINE; FORWARD;
procedure WHITESPACE; {rsr * added 1/13/87 to eliminate whitespace}
BEGIN
WHILE LENGTH(INPUT_LINE) > 0 DO
BEGIN
IF INPUT_LINE[1] IN[^I,' '] THEN DELETE(INPUT_LINE,1,1) ELSE EXIT;
END;
END; { Whitespace }
Function Open(var fp:text; name: Fname): boolean;
begin
Assign(fp,Name);
{$I-}
reset(fp);
{$I+}
If IOresult <> 0 then
begin
Open := False;
close(fp);
end
else
Open := True;
end { Open };
Function IncludeIn(VAR CurStr: buffer): Boolean;
Var ChkChar: char;
column: integer;
begin
ChkChar := '-';
column := pos(search1,CurStr);
if column <> 0 then
chkchar := CurStr[column+3]
else
begin
column := Pos(search3,CurStr);
if column <> 0 then
chkchar := CurStr[column+4]
else
begin
column := Pos(search2,CurStr);
if column <> 0 then
chkchar := CurStr[column+3]
else
begin
column := Pos(search4,CurStr);
if column <> 0 then
chkchar := CurStr[column+4]
end;
end;
end;
if ChkChar in ['+','-'] then IncludeIn := False
Else IncludeIn := True;
end { IncludeIn };
Procedure ProcessIncludeFile(VAR IncStr: buffer);
var NameStart, NameEnd: integer;
IncludeFile: text;
IncludeFileName: Fname;
Function Parse(IncStr: buffer): buffer;
begin
NameStart := pos('$I',IncStr)+2;
while IncStr[NameStart] = ' ' do
NameStart := Succ(NameStart);
NameEnd := NameStart;
while (not (IncStr[NameEnd] in [' ','}','*']))
AND ((NameEnd - NameStart) <= 14{PathLength})
do NameEnd := Succ(NameEnd);
NameEnd := Pred(NameEnd);
Parse := copy(IncStr,NameStart,(NameEnd-NameStart+1));
end {Parse};
begin {Process include file}
IncludeFileName := Parse(IncStr);
If not Open(IncludeFile,IncludeFileName) then
begin
INPUT_LINE := 'ERROR -- Include file not found: ' + IncludeFileName;
end
Else
begin
IF LISTING OR BLOCK THEN
WRITELN(LST,^M^J'(***** Start of ',INCLUDEFILENAME,' *****)'^M^J);
while not eof(IncludeFile) do
begin
BUFCURSOR:=0;
NESTUP:= FALSE;
NESTDN:=FALSE;
Readln(IncludeFile,INPUT_LINE);
WHITESPACE;
PROCESSLINE;
end;
IF LISTING OR BLOCK THEN
WRITELN(LST,^M^J'(***** End of ',INCLUDEFILENAME,' *****)'^M^J);
close(IncludeFile);
end;
end {Process include file};
function ConstStr(C : Char; N : Integer) : Str80;
var
S : string[80];
begin
if N < 0 then
N := 0;
S[0] := Chr(N);
FillChar(S[1],N,C);
ConstStr := S;
end;
procedure BigDash;
var
I : integer;
begin
For I := 1 to 79 do
begin
Write('-');
end;
writeln;
end;
Function Centered(TheString:Str80):Str80;
begin
Centered := ConstStr(' ',((80 - Length(TheString)) Div 2)) +
TheString;
end;
Function Space(Spaces : Integer) : Str80;
Var
Column : Integer;
Temp : Str80;
begin
Temp :='';
For Column := 1 to Spaces do
begin
Temp := Temp + ' ';
Space := Temp;
end;
end;
Procedure LPWRITELN;
Var
I : Integer;
Begin
{BUF[BUFCURSOR]:=CHR(13);
BUFCURSOR:=BUFCURSOR+1;}
For I := 0 to BUFCURSOR-1 do
Write(LST,BUF[I]);
Writeln(LST);
BUFCURSOR:=0;
LINECOUNT:=LINECOUNT+1;
{If (LINECOUNT MOD PAGESIZE) = 0 then
TITLELINE;}
End;
Procedure INITIALIZE;
Var
I : Integer;
Begin { INITIALIZE }
FF:=CHR(12);
ERROR := FALSE;
For I := 0 to P do
T[I].KEY := ' ';
KEY[ 1] := 'ACCE ';
KEY[ 2] := 'ACCCEPT ';
KEY[ 3] := 'ADD ';
KEY[ 4] := 'ALL ';
KEY[ 5] := 'AND ';
KEY[ 6] := 'APPEND ';
KEY[ 7] := 'ASCENDING ';
KEY[ 8] := 'BLANK ';
KEY[ 9] := 'BROWSE ';
KEY[10] := 'CANCEL ';
KEY[11] := 'CHANGE ';
KEY[12] := 'CLEAR ';
KEY[13] := 'CONTINUE ';
KEY[14] := 'COPY ';
KEY[15] := 'COUNT ';
KEY[16] := 'CREATE ';
KEY[17] := 'DELETE ';
KEY[18] := 'DELIMITED ';
KEY[19] := 'DESCENDING ';
KEY[20] := 'DISPLAY ';
KEY[21] := 'DO ';
KEY[22] := 'EDIT ';
KEY[23] := 'EOF ';
KEY[24] := 'EJECT ';
KEY[25] := 'ELSE ';
KEY[26] := 'ENDCASE ';
KEY[27] := 'ENDDO ';
KEY[28] := 'ENDIF ';
KEY[29] := 'ERASE ';
KEY[30] := 'FIELD ';
KEY[31] := 'FILE ';
KEY[32] := 'FILES ';
KEY[33] := 'FIND ';
KEY[34] := 'FOR ';
KEY[35] := 'GET ';
KEY[36] := 'GO ';
KEY[37] := 'IF ';
KEY[38] := 'INDEX ';
KEY[39] := 'INPUT ';
KEY[40] := 'INSERT ';
KEY[41] := 'JOIN ';
KEY[42] := 'LEN ';
KEY[43] := 'LIST ';
KEY[44] := 'LOCATE ';
KEY[45] := 'LOOP ';
KEY[46] := 'NOT ';
KEY[47] := 'NOTE ';
KEY[48] := 'MODIFY ';
KEY[49] := 'OFF ';
KEY[50] := 'ON ';
KEY[51] := 'OR ';
KEY[52] := 'PACK ';
KEY[53] := 'PICTURE ';
KEY[54] := 'POKE ';
KEY[55] := 'QUIT ';
KEY[56] := 'READ ';
KEY[57] := 'RECALL ';
KEY[58] := 'RELEASE ';
KEY[59] := 'REMARK ';
KEY[60] := 'RENAME ';
KEY[61] := 'REPLACE ';
KEY[62] := 'REPORT ';
KEY[63] := 'RESET ';
KEY[64] := 'RESTORE ';
KEY[65] := 'RETURN ';
KEY[66] := 'SAVE ';
KEY[67] := 'SAY ';
KEY[68] := 'SELECT ';
KEY[69] := 'SET ';
KEY[70] := 'SDF ';
KEY[71] := 'SKIP ';
KEY[72] := 'SORT ';
KEY[73] := 'STORE ';
KEY[74] := 'STRUCTURE ';
KEY[75] := 'SUM ';
KEY[76] := 'TO ';
KEY[77] := 'TOTAL ';
KEY[78] := 'UPDATE ';
KEY[79] := 'USE ';
KEY[80] := 'USING ';
KEY[81] := 'WAIT ';
KEY[82] := 'WITH ';
LINECOUNT:= 1;
TOP := P;
PAGE_NUM := 1 ;
LITERAL := FALSE ;
ACOMMENT := FALSE ;
BCOMMENT := FALSE ;
NESTLVL := 0 ;
LAST_KEY := 0 ;
BAR := '|' ;
CH := ' ';
search1 := '{$'+'I'; { So LISTER can list itself! }
search2 := '{$'+'i';
search3 := '(*$'+'I';
search4 := '(*$'+'i';
End; { INITIALIZE }
{$I DLSTOVER.INC}
Procedure PRINTWORD(W: WORD);
Var
L,NEXTREF: Integer;
X: ITEMPTR;
THISREF: NUMREFS;
Begin
PUTALFA(W.KEY);
X := W.FIRST;
L := 0;
Repeat
If L = REFSPERLINE
then
Begin
L := 0;
LPWRITELN;
PUTALFA(' ');
End ;
L := L+1;
THISREF := (L-1) MOD REFSPERITEM + 1;
NEXTREF := X^.REF[ THISREF ];
If THISREF = X^.REFNUM
then
X := NIL
Else
If THISREF = REFSPERITEM
then
X := X^.NEXT;
PUTNUMBER(NEXTREF);
Until X = NIL;
LPWRITELN;
End {PRINTWORD} ;
Procedure PRINTTABLE;
Var
I,J,M: INDEX;
Begin
I := TOP;
While I <> P do
Begin {FIND MINIMAL WORD}
M := I;
J := T[I].FOL;
While J <> P do
Begin
If T[J].KEY < T[M].KEY
then
M := J;
J := T[J].FOL
End ;
PRINTWORD(T[M]);
If M <> I then
Begin
T[M].KEY:=T[I].KEY;
T[M].FIRST:=T[I].FIRST;
T[M].LAST:=T[I].LAST;
End;
I := T[I].FOL
End
End {PRINTTABLE} ;
Procedure OUTPUT_LINE (BUF : BUFFER) ;
Var
I : Integer ;
Procedure PRTNEST (Var LINE : BUFFER) ;
Var COL : Integer ;
Begin { PRTNEST }
For COL := 1 to NESTLVL - 1 do
Write (LST, BAR, ' ') ;
If NESTLVL > 0 then
If NESTUP OR NESTDN then
Begin
If NESTDN then
Begin
Write (LST, BAR, ' ') ;
Write (LST, 'E--') ;
For COL := NESTLVL+2 to NESTMAX do
Write (LST, '-')
End
Else
Begin
Write (LST, 'B--') ;
For COL := NESTLVL+1 to NESTMAX do
Write (LST, '-')
End ;
End
Else
Begin
Write (LST, BAR, ' ') ;
For COL := NESTLVL+1 to NESTMAX do
Write (LST,'')
End
Else
If NESTDN then
Begin
Write (LST, 'E--') ;
For COL := 2 to NESTMAX do
Write (LST, '-') ;
End
Else
For COL := 1 to NESTMAX do
Write (LST,'')
End ; { PRTNEST }
Begin { OUTPUT_LINE }
If ((LINECOUNT MOD PAGESIZE) = 0) OR (PAGE_NUM = 1)
then
Begin
If LISTING OR BLOCK then
If (LSTFILENAME <> 'CON:') AND (((LINECOUNT MOD PAGESIZE) = 0) OR
(EOF(INFILE)))
then
BEGIN
Writeln (OUTPUT, '< ', LINECOUNT:4, ',', MEMAVAIL:5, ' >');
IF EOF(INFILE) THEN
IF NOT BLOCK THEN
WRITELN(OUTPUT,^M^J'Working on Cross Reference Listing');
END;
End ;
Write (LST, LINECOUNT:4, ' ') ;
PRTNEST (BUF) ;
For I := 1 to BUFCURSOR do
Write (LST, BUF[I]) ;
Writeln (LST) ;
If LSTFILENAME <> 'CON:' then
Write (OUTPUT, '.')
End ; { OUTPUT_LINE }
Procedure GETNEXTCHAR;
Var I : Integer;
Begin { GETNEXTCHAR }
If BUFCURSOR >= LENGTH (INPUT_LINE) then
Begin
EOL := TRUE ;
CH := ' ' ;
ERROR := EOF(INFILE)
End
Else
Begin
BUFCURSOR := BUFCURSOR + 1 ;
CH := INPUT_LINE [BUFCURSOR] ;
BUF [BUFCURSOR] := CH ;
CH := UPcase(CH)
End
End; { GETNEXTCHAR }
Procedure GETIDENTIFIER;
Var
J,K,I: Integer;
ID: ALFA;
Begin { GETIDENTIFIER }
I := 0;
ID := ' ';
Repeat
If I < ALFALEN
then
Begin
I := I+1;
ID[I] := CH
End;
GETNEXTCHAR
Until ( NOT(((CH>='A') AND (CH<='Z')) OR (CH='_')
OR ((CH>='0') AND (CH<='9')))) OR (ERROR);
I := 1;
J := NK;
Repeat
K := (I+J) DIV 2; {BINARY SEARCH}
If KEY[K] <= ID
then
I := K+1;
If KEY[K] >= ID
then
J := K-1;
Until I > J;
If KEY[K] <> ID then
SEARCH(ID)
Else
Begin
If (K=21) OR (K=37) then { DO or IF}
Begin
LAST_KEY := K ;
If NESTLVL = NESTMAX then
Write (LST, '----Too many levels')
Else
Begin
NESTLVL := NESTLVL + 1 ;
NESTUP := TRUE
End
End ;
If (K=26) OR (K=27) OR (K= 28) then { ENDDO or ENDIF or ENDCASE}
If (NESTLVL = 0) AND LISTING then
Write (LST, '----Nesting error ')
Else
Begin
NESTLVL := NESTLVL - 1 ;
NESTDN := TRUE
End
End
End; { GETIDENTIFIER }
PROCEDURE PROCESSLINE;
BEGIN
If LENGTH (INPUT_LINE) > 0 then
Begin
EOL := FALSE ;
BUFCURSOR := BUFCURSOR + 1 ;
CH := INPUT_LINE[BUFCURSOR] ;
BUF[BUFCURSOR] := CH ;
CH := UPcase (CH)
End
Else
Begin
EOL := TRUE ;
CH := ' '
End ;
While NOT EOL do
Begin
If ((CH >= 'A') AND (CH <= 'Z')) AND (NOT LITERAL) AND
(NOT ACOMMENT) AND (NOT BCOMMENT) then
GETIDENTIFIER
Else
If (CH = '''') OR LITERAL then
Begin
Repeat
GETNEXTCHAR;
Until (CH = '''') OR (ERROR) OR EOL;
LITERAL := EOL ;
GETNEXTCHAR
End
Else
If (CH = '{') OR ACOMMENT then
Begin
While (CH <> '}') AND (NOT ERROR) AND (NOT EOL) do
GETNEXTCHAR ;
ACOMMENT := EOL ;
GETNEXTCHAR
End
Else
If (CH = '(') OR BCOMMENT then
Begin
If NOT BCOMMENT then
GETNEXTCHAR;
If (CH = '*') OR BCOMMENT then
Begin
If NOT BCOMMENT then
GETNEXTCHAR;
Repeat
While (CH <> '*') AND (NOT ERROR) AND (NOT EOL) do
GETNEXTCHAR ;
BCOMMENT := EOL ;
If NOT EOL then
GETNEXTCHAR
Until (CH = ')') OR ERROR OR EOL ;
If NOT EOL then
GETNEXTCHAR
End
End
Else
GETNEXTCHAR;
END;{WHILE}
EOL := FALSE ;
If LISTING OR BLOCK then
OUTPUT_LINE(BUF) ;
LINECOUNT := LINECOUNT + 1;
END; {PROCESSLINE}
Begin { CROSSREF } {AND ELIM. LEFT WHITESPACE}
nextime := true;
nex2time := true;
nex3time := true;
INITIALIZE;
OPENFILES;
While NOT EOF(INFILE) AND (NOT ABORT) do
Begin
BUFCURSOR:= 0;
NESTUP := FALSE ;
NESTDN := FALSE ;
READLN (INFILE, INPUT_LINE) ;
WHITESPACE; {rsr * added 1/13/87 to eliminate whitespace}
IF INCLUDEIN(INPUT_LINE) THEN
PROCESSINCLUDEFILE(INPUT_LINE)
ELSE
PROCESSLINE;
END;
If NOT ABORT then
Begin
{TITLELINE;}
IF ((NOT BLOCK) OR LISTING) THEN
BEGIN
LINECOUNT := 0;
BUFCURSOR := 0;
WRITELN(LST,^M^J'CROSS REFERENCE TABLE for ',FILENAME,^M^J);
PRINTTABLE;
Writeln(LST,^M^J'END of CROSS REFERENCE TABLE for ',FILENAME,^M^J);
END;
CLOSE(LST);
If IOresult <> 0 then
Writeln('ERROR CLOSING OUTPUT FILE')
End;
WRITELN(^M^J'PROGRAM COMPLETE: Written to ',LSTFILENAME,' - EXITING ');
{CLRSCR}
END.