home *** CD-ROM | disk | FTP | other *** search
- program PLIST;
- (* Written by: Rick Schaeffer
- E. 13611 26th Av.
- Spokane, Wa. 99216
-
- modifications (7/8/84 by Len Whitten, CIS: [73545,1006])
- 1) added error handling if file not found
- 2) added default extension of .PAS to main & include files
- 3) added "WhenCreated" procedure to extract file
- creation date & time from TURBO FIB
- 4) added demarcation of where include file ends
- 5) added upper char. conversion to include file
- 6) increased left margin to 5 spaces (80 char. line just fits @ 10cpi)
- 7) added listing control: {.L-} turns it off, {.L+} turns it back on,
- must be in column 1
-
- further modifications (7/12/84 by Rick Schaeffer)
- 1) cleaned up the command line parsing routines and put them in
- separate procedures. Now permits any number of command line
- arguments, each argument separated with at least one space.
- 2) added support for an optional second command line parameter
- which specifies whether include files will be listed or not.
- The command is invoked by placing "/i" on the command line
- at least one space after the file name to be listed. For
- instance, to list MYPROG.PAS as well as any "included" files,
- the command line would be: PLIST MYPROG /I
-
- further modification (8/28/84) by Jay Kadashaw)
- 1) Restored filedate and filetime after listing an included
- file.
- 2) Added comment counter and begin/end counter.
- 3) Output can be routed to either the printer or console.
- 4) After listing first file the user is prompted for next
- file if any.
-
- Still more modifications! (10/30/84) by Michael Roberts
- 1) Cleaned Up various problems I encountered
- 2) Removed Comment counter in order to add line numbers
- 3) Added Cross-Referencing facility
- a) IMPORTANT!! Make sure when you create COM file you assign
- The minimum segment sizes given in a MEM compile
- (Particularly allow a minimum Stack Size Of 1300)
- b) The file 'TURBOPAS.RES' contains the reserved words for
- the TURBO Pascal compiler release 2.0. If new reserved
- words are implemented in future releases, add the new
- words to this file.
-
- Please let me know if you run into any problems!
- Michael Roberts [CIS 74226,3045]
- 3103 Glenview
- Royal Oak, MI 48073
-
-
-
-
-
- Further Updates and modifications -- 03/04/85, Gene Czarcinski ..
- 1) Eliminate requirement for the TURBOPAS.RES file.
- 2) Do FormFeed at end of output, not the beginning.
- 3) Add code to check for and eliminate xref of reserved words
- 4) Redo/correct build of xref table .. rewrite BuildXref
- (fixes bug causing incorrect line numbers in xref)
- 5) If command line parms specified, do not prompt and
- process only that file.
- 6) Add code to support command line parms --
- /X - supports compressed print on Gemini 10X printer
- /R - XREF reserved words also
- /C - output to console (default is printer)
-
- ** NOTE **
- The routine BuildXref now contains a copmplex if-then-else-elseif
- structure. If the if-elseif structure is too long, it appears that
- TURBO will barf (hang in compile).
-
-
- Supported pseudo operations:
- 1) Listing control: {.L-} turns it off, {.L+} turns it back on,
- must be in column 1
- 2. Page ejection: {.PAGE} or {.PA}, must be in column 1.
- *)
-
- { When program is first run will check for a file
- name passed by DOS, and will try to open that file. If no name is
- passed, will ask operator for a file name to open. Proc will tell
- operator if file doesn't exist and will allow multiple retrys.
-
- Included files will be expanded only if the program is invoked as
- follows:
- pretty filename /i
- The default is not to expand included files.
-
- On 2nd and later executions, proc will not check for DOS passed file
- name. In all cases, proc will assume a file type of .PAS if file
- type is not specified.
- PROGRAM EXIT from this proc when a null string is encountered in
- response to a file name request. }
-
-
-
- const monthmask = $000F;
- daymask = $001F;
- minutemask = $003F;
- secondmask = $001F;
-
- { to customize code for your printer - adjust the next item }
-
- maxline = 58;
-
- ff = #12;
- PreFix = #27#66#03#27#77#14;
- PostFix = #27#77#0#18;
-
-
- type
- XrefWordptr = ^XrefwordRec;
- XrefNumPtr = ^XrefNumRec;
- XrefWordRec = RECORD
- XrefWord : string[20];
- FirstNum : XrefNumPtr;
- LastNum : XrefNumPtr;
- NextWord : XrefwordPtr;
- END;
- XrefNumRec = RECORD
- XrefNum : Integer;
- NextNum : XrefNumPtr;
- END;
- alfa = string[15];
- two_letters = string[2];
- dtstr = string[8];
- fnmtype = string[14];
- instring = string[135];
- regpack = record
- ax,bx,cx,dx,bp,si,di,ds,es,flags : integer;
- end;
-
- Var
- ParmX,
- ParmR,
- ParmC,
- CmdParm,
- DoneFlag,
- First,
- initprt : boolean;
- answer : char;
- Buff1 : instring; {input line buffer}
- FirstWord : ARRAY[0..26] of XrefWordPtr;
- PrevWord,
- NewWord,
- CurrWord : XRefWordPtr;
- CurrNum : XRefNumPtr;
- XrefWord : string[20];
- XrefNum : Integer;
- wordchk : alfa;
- heaptop : ^Integer;
- listfil : text; {FIB for LST: or CON: output}
- infile : text; {FIB for input file}
- fnam : fnmtype; {in file name}
- FirstNdx,
- bcount, {begin/end counter}
- kcount, {comment counter}
- linect, {output file line counter}
- linecnt,
- pageno,
- offset : integer;
- print : boolean; (* {.L-} don't print *)
- (* {.L+} print *)
- print_head : boolean;
- Print_Xref : boolean;
- Word_switch: Boolean;
- c : char;
- month, day, year,
- hour, minute, second : two_letters;
- sysdate, systime,
- filedate, filetime : dtstr;
- expand_includes : boolean;
- holdarg : instring;
- allregs : regpack;
-
- {.page}
- Procedure ListIt(filename : fnmtype); forward;
-
- Function Find_in_Reserve(var kword: alfa) : boolean;
- var flg : boolean;
- cnt : integer;
- Begin
- cnt := length(kword);
- if cnt=2 then begin
- if kword='IF' then flg:=TRUE
- else if kword='DO' then flg:=TRUE
- else if kword='TO' then flg:=TRUE
- else if kword='IN' then flg:=TRUE
- else if kword='OF' then flg:=TRUE
- else if kword='OR' then flg:=TRUE
- else if kword='LN' then flg:=TRUE
- else if kword='HI' then flg:=TRUE
- else if kword='LO' then flg:=TRUE
- else flg:=FALSE;
- end
- else if cnt=3 then begin
- if kword='END' then flg:=TRUE
- else if kword='FOR' then flg:=TRUE
- else if kword='VAR' then flg:=TRUE
- else if kword='SET' then flg:=TRUE
- else if kword='CHR' then flg:=TRUE
- else if kword='ORD' then flg:=TRUE
- else if kword='VAL' then flg:=TRUE
- else if kword='STR' then flg:=TRUE
- else if kword='MOD' then flg:=TRUE
- else if kword='DIV' then flg:=TRUE
- else if kword='AND' then flg:=TRUE
- else if kword='NOT' then flg:=TRUE
- else if kword='XOR' then flg:=TRUE
- else if kword='SHL' then flg:=TRUE
- else if kword='SHR' then flg:=TRUE
- else if kword='SIN' then flg:=TRUE
- else if kword='COS' then flg:=TRUE
- else if kword='INT' then flg:=TRUE
- else if kword='POS' then flg:=TRUE
- else if kword='EXP' then flg:=TRUE
- else if kword='NIL' then flg:=TRUE
- else if kword='ABS' then flg:=TRUE
- else if kword='SQR' then flg:=TRUE
- else if kword='ODD' then flg:=TRUE
- else if kword='EOF' then flg:=TRUE
- else if kword='PTR' then flg:=TRUE
- else if kword='NEW' then flg:=TRUE
- else flg:= FALSE;
- end
- else if cnt=4 then begin
- if kword='ELSE' then flg:=TRUE
- else if kword='THEN' then flg:=TRUE
- else if kword='TYPE' then flg:=TRUE
- else if kword='TRUE' then flg:=TRUE
- else if kword='CHAR' then flg:=TRUE
- else if kword='BYTE' then flg:=TRUE
- else if kword='REAL' then flg:=TRUE
- else if kword='FRAC' then flg:=TRUE
- else if kword='SQRT' then flg:=TRUE
- else if kword='PRED' then flg:=TRUE
- else if kword='SUCC' then flg:=TRUE
- else if kword='WITH' then flg:=TRUE
- else if kword='COPY' then flg:=TRUE
- else if kword='MOVE' then flg:=TRUE
- else if kword='FILE' then flg:=TRUE
- else if kword='TEXT' then flg:=TRUE
- else if kword='READ' then flg:=TRUE
- else if kword='SEEK' then flg:=TRUE
- else if kword='EOLN' then flg:=TRUE
- else if kword='MARK' then flg:=TRUE
- else if kword='ADDR' then flg:=TRUE
- else if kword='SWAP' then flg:=TRUE
- else if kword='GOTO' then flg:=TRUE
- else if kword='EXIT' then flg:=TRUE
- else if kword='HALT' then flg:=TRUE
- else if kword='DRAW' then flg:=TRUE
- else if kword='PLOT' then flg:=TRUE
- else flg:=FALSE;
- end
- else if cnt=5 then begin
- if kword='WHILE' then flg:=TRUE
- else if kword='SOUND' then flg:=TRUE
- else if kword='UNTIL' then flg:=TRUE
- else if kword='CONST' then flg:=TRUE
- else if kword='FALSE' then flg:=TRUE
- else if kword='ARRAY' then flg:=TRUE
- else if kword='LABEL' then flg:=TRUE
- else if kword='ROUND' then flg:=TRUE
- else if kword='TRUNC' then flg:=TRUE
- else if kword='CLOSE' then flg:=TRUE
- else if kword='WRITE' then flg:=TRUE
- else if kword='RESET' then flg:=TRUE
- else if kword='ERASE' then flg:=TRUE
- else if kword='FLUSH' then flg:=TRUE
- else if kword='CHAIN' then flg:=TRUE
- else if kword='DELAY' then flg:=TRUE
- else if kword='HIRES' then flg:=TRUE
- else if kword='MSDOS' then flg:=TRUE
- else flg:=FALSE;
- end
- else if cnt=6 then begin
- if kword='SIZEOF' then flg:=TRUE
- else if kword='DOWNTO' then flg:=TRUE
- else if kword='REPEAT' then flg:=TRUE
- else if kword='RECORD' then flg:=TRUE
- else if kword='STRING' then flg:=TRUE
- else if kword='ARCTAN' then flg:=TRUE
- else if kword='UPCASE' then flg:=TRUE
- else if kword='CONCAT' then flg:=TRUE
- else if kword='LENGTH' then flg:=TRUE
- else if kword='INSERT' then flg:=TRUE
- else if kword='DELETE' then flg:=TRUE
- else if kword='ASSIGN' then flg:=TRUE
- else if kword='READLN' then flg:=TRUE
- else if kword='RENAME' then flg:=TRUE
- else if kword='GETMEM' then flg:=TRUE
- else if kword='WINDOW' then flg:=TRUE
- else if kword='WHEREX' then flg:=TRUE
- else if kword='WHEREY' then flg:=TRUE
- else if kword='CLREOL' then flg:=TRUE
- else if kword='CLRSCR' then flg:=TRUE
- else if kword='GOTOXY' then flg:=TRUE
- else if kword='RANDOM' then flg:=TRUE
- else flg:=FALSE;
- end
- else if cnt=7 then begin
- if kword='OVERLAY' then flg:=TRUE
- else if kword='FORWARD' then flg:=TRUE
- else if kword='BOOLEAN' then flg:=TRUE
- else if kword='INTEGER' then flg:=TRUE
- else if kword='WRITELN' then flg:=TRUE
- else if kword='REWRITE' then flg:=TRUE
- else if kword='FILEPOS' then flg:=TRUE
- else if kword='EXECUTE' then flg:=TRUE
- else if kword='DISPOSE' then flg:=TRUE
- else if kword='FREEMEM' then flg:=TRUE
- else if kword='NOSOUND' then flg:=TRUE
- else if kword='DISPOSE' then flg:=TRUE
- else if kword='CRTEXIT' then flg:=TRUE
- else if kword='PALETTE' then flg:=TRUE
- else if kword='CRTINIT' then flg:=TRUE
- else if kword='INSLINE' then flg:=TRUE
- else if kword='DELLINE' then flg:=TRUE
- else if kword='PROGRAM' then flg:=TRUE
- else flg:=FALSE;
- end
- else begin
- if kword='PROCEDURE' then flg:=TRUE
- else if kword='FUNCTION' then flg:=TRUE
- else if kword='EXTERNAL' then flg:=TRUE
- else if kword='FILLCHAR' then flg:=TRUE
- else if kword='FILESIZE' then flg:=TRUE
- else if kword='MEMAVAIL' then flg:=TRUE
- else if kword='MAXAVAIL' then flg:=TRUE
- else if kword='TEXTMODE' then flg:=TRUE
- else if kword='TEXTCOLOR' then flg:=TRUE
- else if kword='IORESULT' then flg:=TRUE
- else if kword='LOWVIDEO' then flg:=TRUE
- else if kword='NORMVIDEO' then flg:=TRUE
- else if kword='KEYPRESSED' then flg:=TRUE
- else if kword='BLOCKREAD' then flg:=TRUE
- else if kword='BLOCKWRITE' then flg:=TRUE
- else if kword='TEXTBACKROUND' then flg:=TRUE
- else if kword='HIRESCOLOR' then flg:=TRUE
- else if kword='GRAPHWINDOW' then flg:=TRUE
- else if kword='GRAPHMODE' then flg:=TRUE
- else if kword='GRAPHCOLORMODE' then flg:=TRUE
- else if kword='GRAPHBACKGROUND' then flg:=TRUE
- else flg:=FALSE;
- end;
- Find_in_Reserve := flg;
- End;
-
-
- procedure getchar(var char_value : char);
- begin
- allregs.ax := $0000;
- intr($16, allregs);
- char_value := chr(ord(lo(allregs.ax)));
- end;
-
- procedure fill_blanks (var line: dtstr);
- var i : integer;
- begin
- for i:= 1 to 8 do if line[i] = ' ' then line[i]:= '0';
- end;
-
- procedure getdate(var date : dtstr);
- begin
- allregs.ax := $2A * 256;
- MsDos(allregs);
- str((allregs.dx div 256):2,month);
- str((allregs.dx mod 256):2,day);
- str((allregs.cx - 1900):2,year);
- date := month + '/' + day + '/' + year;
- fill_blanks (date);
- end;
-
- procedure gettime(var time : dtstr);
- begin
- allregs.ax := $2C * 256;
- MsDos(allregs);
- str((allregs.cx div 256):2,hour);
- str((allregs.cx mod 256):2,minute);
- str((allregs.dx div 256):2,second);
- time := hour + ':' + minute + ':' + second;
- fill_blanks (time);
- end;
-
- procedure WhenCreated (var date, time: dtstr; var infile: text);
- var fulltime,fulldate: integer;
- begin
-
- { fulldate gets the area of the FIB which corresponds to bytes 20-21
- of the FCB. Format is: bits 0 - 4: day of month
- 5 - 8: month of year
- 9 -15: year - 1980
- }
- fulldate:= memw [seg(infile):ofs(infile)+31];
- str(((fulldate shr 9) + 80):2,year);
- str(((fulldate shr 5) and monthmask):2,month);
- str((fulldate and daymask):2,day);
- date:= month + '/' + day + '/' + year;
- fill_blanks(date);
-
- { fulltime gets the area of the FIB which corresponds to bytes 22-23
- of the FCB. Format is: bits 0 - 4: seconds/2
- 5 -10: minutes
- 11-15: hours
- }
- fulltime:= memw [seg(infile):ofs(infile)+33];
- str((fulltime shr 11):2,hour);
- str(((fulltime shr 5) and minutemask):2,minute);
- str(((fulltime and secondmask) * 2):2,second);
- time:= hour + ':' + minute + ':' + second;
- fill_blanks (time);
- end; {WhenCreated}
-
- Procedure BuildXref;
- var done:boolean;
- Begin
- FirstNdx := ord(wordchk[1]) - ord('A');
- if (FirstNdx<1) or (FirstNdx>26) or (length(wordchk)=0) then
- FirstNdx := 0;
- done := FALSE;
- CurrWord := FirstWord[FIrstNdx];
- PrevWord := nil;
- REPEAT
- if CurrWord=nil then begin
- new(CurrWord);
- CurrWord^.XrefWord := wordchk;
- CurrWord^.FirstNum := nil;
- CurrWord^.LastNum := nil;
- CurrWord^.NextWord := nil;
- done := TRUE;
- end
- else if CurrWord^.XrefWord = wordchk then begin
- done := TRUE;
- end
- else if CurrWord^.XrefWord > wordchk then Begin
- new(NewWord);
- NewWord^.XrefWord := wordchk;
- NewWord^.FirstNum := nil;
- NewWord^.LastNum := nil;
- NewWord^.NextWord := CurrWord;
- if FirstWord[FirstNdx]=CurrWord then
- FirstWord[FirstNdx] := NewWord;
- CurrWord := NewWord;
- done := TRUE;
- end
- else begin
- PrevWord := CurrWord;
- CurrWord := CurrWord^.NextWord;
- end;
- UNTIL done;
- if FirstWord[FirstNdx]=nil then begin
- FirstWord[FirstNdx] := CurrWord;
- end;
- if PrevWord <> Nil then begin
- PrevWord^.NextWord := CurrWord;
- end;
- new(CurrNum);
- CurrNum^.NextNum := nil;
- CurrNum^.XrefNum := linecnt;
- if CurrWord^.FirstNum=nil then
- CurrWord^.FirstNum := CurrNum;
- if CurrWord^.LastNum=nil then
- CurrWord^.LastNum := CurrNum
- else begin
- CurrWord^.LastNum^.NextNum := CurrNum;
- CurrWord^.LastNum := CurrNum;
- end;
- end;
-
- procedure print_heading(filename : fnmtype);
- var offset_inc: integer;
- begin
- if print then begin
- pageno := pageno + 1;
- {top of form}
- if initprt then begin
- if not ParmC then
- write(listfil,ff);
- end
- else begin
- initprt := TRUE;
- if not ParmC then begin
- if ParmX then
- write(listfil,PreFix);
- end;
- end;
- writeln(listfil);
- writeln(listfil,'TURBO Pascal Program Lister - 03/04/85 ',
- 'Printed: ',sysdate,' ',systime,
- ' Page ',pageno:4);
- if filename <> fnam then begin
- offset_inc:= 14 - length (filename);
- write(listfil,' Include File:',filename,' ':offset_inc,
- 'Created: ',filedate,' ',filetime);
- end
- else write(listfil,' Main File: ',fnam,' ':offset,
- 'Created: ',filedate,' ',filetime);
- writeln(listfil); writeln(listfil);
- If Print_Xref then
- Writeln(Listfil,' ':32,'CROSS-REFERENCE')
- else
- writeln(listfil, ' ');
- writeln(listfil);
- linect := 6;
- end; {check for print}
- end; {print_heading}
-
- procedure printline(iptline : instring; filename : fnmtype);
- begin
- if print then begin
- if linect < 56 then begin
- writeln(listfil,' ',iptline);
- linect := linect + 1
- end
- else begin
- print_heading(filename);
- end;
- end; {check for print}
- end; {printline}
-
- function chkinc(var iptline : instring; var incflname : fnmtype) : boolean;
- var
- done : boolean;
- i, j : integer;
- begin
- i := 4; j := 1; incflname := '';
- if copy(iptline,1,3)='{$I' then begin
- i := 4; j := 1; incflname := '';
- while (iptline[i]=' ') and (i<=length(iptline)) do
- i := i + 1;
- done := false;
- while not done do begin
- if i<=length(iptline) then begin
- if not (iptline[i] in [' ','}','+','-']) then begin
- incflname := incflname + iptline[i];
- i := i+1; j := j+1;
- end
- else
- done := true;
- end
- else
- done := true;
- if j>14 then
- done := true;
- end;
- end;
- if incflname <> '' then begin
- chkinc := true;
- for i := 1 to length(Incflname) do
- incflname[i] := upcase(incflname[i]);
- end
- else
- chkinc := false;
- end; {chkinc}
-
- function parse_cmd(argno : integer) : instring;
- var
- i,j : integer;
- wkstr : instring;
- done : boolean;
- cmdline : ^instring;
- begin
- cmdline := ptr(CSEG,$0080);
- wkstr := '';
- done := false; i := 1; j := 0;
- if length(cmdline^) < i then done := true;
- repeat
- while ((cmdline^[i] = ' ') and (not done)) do begin
- i := i + 1;
- if i > length(cmdline^) then done := true;
- end;
- if not done then j := j + 1;
- while ((cmdline^[i] <> ' ') and (not done)) do begin
- wkstr := wkstr + cmdline^[i];
- i := i + 1;
- if i > length(cmdline^) then done := true;
- end;
- if (j <> argno) then wkstr := '';
- until (done or (j = argno));
- for i := 1 to length(wkstr) do
- wkstr[i] := upcase(wkstr[i]); {all arguments forced to upper case}
- parse_cmd := wkstr;
- end;
-
- PROCEDURE GET_IN_FILE; {GETS INPUT FILE NAME }
- var
- existing : boolean;
- i : integer;
- begin
- REPEAT {until file exists}
- holdarg := parse_cmd(1); {get command line argument # 1}
- if (length(holdarg) in [1..14]) and first then begin
- fnam := holdarg; {move possible file name to fnam}
- CmdParm := TRUE;
- end
- else begin
- writeln;
- write(' ENTER FILE NAME TO LIST or <cr> to EXIT ');
- readln(fnam);
- if length(fnam)=0 then
- HALT
- else begin
- writeln;write(' EXPAND INCLUDES? (Y/N) ');
- readln(answer);
- if upcase(answer) = 'Y' then
- expand_includes := true
- else
- expand_includes := false;
- end;
- end;
-
- for i := 1 to length(fnam) do
- fnam[i] := upcase(fnam[i]);
- if pos('.',fnam) = 0 then {file type given?}
- fnam := concat(fnam,'.PAS'); {file default to .PAS type}
-
- {get optional command line argument # 2}
- if CmdParm and first then begin
- holdarg := parse_cmd(2);
- if (length(holdarg)>1) and (holdarg[1]='/') then begin
- for i := 1 to length(holdarg) do
- holdarg[i] := upcase(holdarg[i]);
- while length(holdarg)>0 do begin
- if holdarg[1]='R' then ParmR := TRUE
- else if holdarg[1]='I' then expand_includes := TRUE
- else if holdarg[1]='C' then ParmC := TRUE
- else if holdarg[1]='X' then ParmX := TRUE;
- Delete(holdarg,1,1);
- end;
- end;
- end;
-
- first := false; {get passed file name only once}
- assign(infile,fnam);
- {$I-}
- reset(infile); {check for existence of file}
- {$I+}
- existing := (ioresult = 0); {true if file found}
- if not existing then begin
- writeln;
- writeln(' FILE DOESN''T EXIST'); {tell operator the sad news}
- end;
- UNTIL existing; {until file exists}
- end; {GET_IN_FILE}
-
- { GET_OUT_FILE procedure asks operator to select output to console
- device or list device, and then assigns and resets a file control
- block to the appropriate device. 'C' or 'P' is only correct
- response, and multiple retrys are allowed. }
-
- Procedure Get_Out_File;
- var c : char;
- begin
- if CmdParm then begin
- if ParmC then c := 'C'
- else c := 'P';
- end
- else begin
- REPEAT {until good selection}
- writeln; write(' OUTPUT LISTING TO (C)ONSOLE OR (P)RINTER ? ');
- getchar(c);
- c := upcase(c); write(c);
- UNTIL c in ['C', 'P'];
- writeln;
- end;
- if c = 'C' then
- assign (listfil, 'CON:')
- else
- assign (listfil, 'LST:');
- reset(listfil);
- end; {GET_OUT_FILE}
-
-
- {.page}
- { SCAN_LINE procedure scans one line of Turbo Pascal source code
- looking for BEGIN/END pairs, CASE/END pairs, LITERAL fields
- and COMMENT fields. BCOUNT is begin/end and case/end counter.
- KCOUNT is comment counter. Begin/case/ends are only valid
- outside of comment fields and literal constant fields (KCOUNT = 0
- and NOT LITERAL).
- Some of the code in the SCAN_LINE procedure appears at first glance
- to be repitive and/or redundant, but was added to speed up the
- process of scanning each line of source code.}
-
- Procedure SCAN_LINE;
- var
- literal : boolean; { true if in literal field}
- tmp : string[7]; { tmp work area }
- i : integer; {loop variable index}
- buff2 : instring; {working line buffer}
- incflname : fnmtype; {in file name}
- filedate_save : dtstr;
- filetime_save : dtstr;
- begin
- literal := false;
-
- buff2[0] := buff1[0]; {copy input buffer to working buffer}
- for i := 1 to length(buff1) do
- buff2[i] := upcase(buff1[i]); {and translate to upper case}
-
- if chkinc(buff2, incflname) and expand_includes then begin
- if pos('.',incflname) = 0 then
- incflname := incflname + '.PAS';
- printline('+++++++++++++++++++++++++++++++++++++',incflname);
- printline(' Including "'+incflname+'"', incflname);
- printline('+++++++++++++++++++++++++++++++++++++',incflname);
- filedate_save := filedate; {save filedate & filetime for}
- filetime_save := filetime; {main file }
- listit(incflname);
- filedate := filedate_save; {restore}
- filetime := filetime_save;
- printline('-------------------------------------',incflname);
- printline(' End of "'+incflname+'"', incflname);
- printline('-------------------------------------',incflname);
- linecnt := linecnt - 1;
- end; {include file check}
-
- if copy(buff2,1,5) = '{.L-}' then begin
- print := false;
- if length(buff2) = 5 then
- linecnt := linecnt - 1;
- end;
-
- if copy(buff2,1,5) = '{.L+}' then begin
- print := true;
- if length(buff2) = 5 then
- linecnt := linecnt - 1;
- end;
-
- if (copy(buff2,1,7)='{.PAGE}') or (Copy(buff2,1,5)='{.PA}') then begin
- print_head := true;
- if length(buff2) = 7 then
- linecnt := linecnt - 1;
- end;
-
- if length(buff2) > 0 then
- linecnt := linecnt + 1;
-
- buff2 := concat(' ', buff2, ' '); {add on some working space}
- for i := 1 to length(buff2) - 6 do begin
- tmp := copy(buff2, i, 7);
- if not literal then begin {possible to find comment delim}
- {determine if comment area delim}
- if tmp[1] in ['{', '}', '(', '*'] then begin
- if (tmp[1] = '{') or (copy(tmp,1,2)='(*') then
- kcount := succ(kcount); {count comment opens}
- if (tmp[1] = '}') or (copy(tmp,1,2)='*)') then
- kcount := pred(kcount); {un-count comment closes}
- end;
- end;
-
- if kcount = 0 then begin {we aren't in a comment area}
- if tmp[1] = chr(39) then
- literal := not literal; {toggle literal flag}
- if not literal then begin
- if ((not Word_switch) and
- (buff2[i] in ['A'..'Z','a'..'z'])) then begin
- Word_switch := true;
- wordchk := '';
- end;
- if word_switch then
- if (buff2[i] in ['A'..'Z','a'..'z','0'..'9','_']) then
- wordchk := concat(wordchk,upcase(Buff2[i]))
- else begin
- word_switch := false;
- if ParmR then
- BuildXref
- else begin
- if not find_in_reserve(wordchk) then BuildXref;
- end;
- end;
- end;
- if not literal and (tmp[2] in ['B','C','E']) then begin
- if (tmp=' BEGIN ') or (copy(tmp,1,6)=' CASE ') then begin
- bcount := succ(bcount); {count BEGIN}
- i := i + 5; {skip rest of begin}
- end;
- if (copy(tmp,1,4) = ' END') and
- (tmp[5] in ['.', ' ', ';']) and
- (bcount > 0) then begin
- bcount := pred(bcount); {un-count for END}
- i := i + 4;
- end;
- end; {if not literal}
- end; { if kcount = 0 }
- end; { for i := }
- end; {SCAN_LINE}
-
- {.page}
- Procedure ListIt;
- var infile : text;
- begin
- assign(infile, filename);
- {$I-} reset(infile) {$I+} ;
- if IOresult <> 0 then begin
- writeln ('File ',filename,' not found.');
- halt;
- end;
- WhenCreated(filedate,filetime,infile);
- print_heading(filename);
- while not eof(infile) do begin
- readln(infile, buff1);
- scan_line;
- if print_head then
- print_heading(filename);
- if print and (not print_head) then begin
- if length(buff1) > 0 then
- writeln(listfil,linecnt : 4, bcount : 3, ' ', buff1)
- else
- writeln(listfil,' ',buff1);
- linect := succ(linect);
- if linect > maxline then begin
- print_heading(filename);
- end;
- end;
- print_head := false;
- end; {while not eof}
- end; {ListIt}
-
- {.page}
- Procedure ListXref;
- Var x, y: Integer;
- Begin
- Print_Xref := True;
- Print_heading(fnam);
- FOR FirstNdx := 0 to 26 do begin
- CurrWord := FirstWord[FirstNdx];
- while CurrWord <> Nil Do Begin
- Write(listfil,CurrWord^.XrefWord:20);
- x := 0;
- CurrNum := CurrWord^.FirstNum;
- while CurrNum <> Nil do begin
- if X < 10 then begin
- Write(listfil,CurrNum^.XrefNum:5);
- x := x + 1;
- end
- else begin
- Writeln(listfil);
- Linect := linect + 1;
- if linect>maxline then Print_heading(fnam);
- Write(listfil,' ':20,CurrNum^.XrefNum:5);
- x := 0;
- end;
- CurrNum := CurrNum^.NextNum;
- end;
- writeln(listfil);
- Linect := linect+1;
- if linect > Maxline then Print_heading(fnam);
- CurrWord := CurrWord^.NextWord;
- end;
- end;
- end;
- {.page}
-
- begin {main procedure}
- Mark(heaptop);
- DoneFlag := FALSE;
- getdate(sysdate);
- gettime(systime);
- First := TRUE;
- expand_includes := false; {default settings}
- print := true; initprt := FALSE;
- ParmC := FALSE; ParmR := FALSE; ParmX := FALSE; CmdParm := FALSE;
- expand_includes := FALSE;
- pageno := 0;
-
- repeat {forever}
- Release(heaptop);
- for FirstNdx := 0 to 26 do
- FirstWord[FirstNdx] := nil;
- ClrScr;
- GotoXY(2, 2);
- writeln('TURBO Pascal Formatted Listing');
- GotoXY(2, 4);
- get_in_file; {file to list}
- offset := 23 - length(fnam);
- get_out_file; {where to list it}
- pageno := 0;
- linect := 1; {output line counter}
- kcount := 0;
- linecnt := 0;
- bcount := 0;
- print_head := false;
- Print_xref := False;
- word_switch:= False;
- listit(fnam);
- Listxref;
- if CmdParm then
- DoneFlag := TRUE
- else begin
- writeln;
- write('HIT ANY KEY TO CONTINUE '); {allow op to see end
- of listing}
- getchar(c);
- end;
- until DoneFlag;
- if not ParmC then begin
- write(listfil,ff);
- if ParmX then write(listfil,PostFix);
- end;
- Close(listfil);
- HALT;
- end. {main procedure}