home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
pascal
/
utility
/
crossref
/
xref
/
blist.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1979-12-31
|
8KB
|
219 lines
PROGRAM BList;
{ TURBO PASCAL SOURCE CODE LISTER AND BEGIN-END COUNTER PROGRAM }
{ Prints a listing to console or printer of a TURBO PASCAL source code with
optional display of comment counter and begin/end counter, and also optional
display skip of paper perforations. Accepts file name passed by CP/M or
from operator input of file to list. }
{ This version of the code is specific to CP/M-80 because the GET_IN_FILE
procedure looks for a parameter passed by CP/M at absolute location $80. The
procedure could be modified for other operating systems, or not to accept
passed parameters at all. }
{ I declare that this code is released to the PUBLIC DOMAIN as of July 1, 1984
Phillip M. Nickell }
{ Modified Sept. 1, 1984 by Marvin Landis
Record/end combination is now handled correctly. }
VAR Buff1: STRING[135]; { Input line buffer }
ListFil: TEXT; { Fib for LST: or CON: output }
InFile: TEXT; { Fib for input file }
BCount,KCount,LineCt: INTEGER; { Counters }
Count_Be,PerfSkip: BOOLEAN; { Count begin/end and skip }
ch: char;
CONST First: BOOLEAN = TRUE; { True when program is run }
{ To customize code for your printer and desires - adjust the next two items }
MaxLine = 60; { max # of lines on page when in PERFSKIP mode }
SkipLine = 2; { # of lines to skip at top of form }
CR = #13;
LF = #10;
FF = #12;
Procedure Clean; { Clears screen and positions cursor }
BEGIN
ClrScr;
GoToXY(1,10);
END;
Procedure Lines(X: Integer); { Puts X amount of blank lines to output file }
Var N: Integer;
BEGIN
For N:= 1 To X Do
Writeln(ListFil);
END;
{ GET_IN_FILE PROCEDURE : When program is first run, it will check for a file
name passed by CP/M and will try to open that file. If no name is passed,
it will ask operator for a file name to open. Proc will tell operator if
file doesn't exist and will allow multiple retrys. On second and later
executions, proc will not check for CP/M passed file name. In all cases
proc will assume a file type of .PAS if file type is not specified. Exit
from the program occurs when a null string is entered in response to a file
name request. }
Procedure Get_In_File; { Gets input file name }
Var FNam: String[14];
Parm: String[14] Absolute CSeg:$0081;
ParmLth: Byte Absolute CSeg:$0080;
Existing: Boolean;
BEGIN
Repeat { Until file exists }
If (ParmLth In [1..14]) And First Then
FNam:= Copy(Parm,1,ParmLth - 1)
Else Begin
Clean;
Write('Enter file name to list or <CR> to exit: ');
Readln(FNam);
End;
If FNam = '' Then Halt;
If Pos('.',FNam) = 0 Then
FNam:= Concat(FNam,'.PAS'); { File default to .PAS type }
First:= False;
Assign(InFile,FNam);
{$I-}
Reset(InFile);
{$I+}
Existing:= (IOResult = 0);
If Not Existing Then Begin
Clean;
Writeln('File does not exist.');
Delay(700);
End;
Until Existing;
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' are the only correct responses, and
multiple retrys are allowed. }
Procedure Get_Out_File;
Var C: Char;
BEGIN
Repeat { Until good selection }
Clean;
Write('Output listing to (C)onsole or (P)rinter? ');
read(kbd,C);
c:=upcase(c);
Until C In ['C','P'];
Writeln;
If C = 'C' Then
Assign(ListFil,'CON:')
Else
Assign(ListFil,'LST:');
Reset(ListFil);
END; { Get_Out_File }
{ GET_OPTIONS procedure : Asks operator if count of begin/end pairs is desired,
and also if skip over paper perforations is desired. Proc will set or clear
the Count_Be flag and the PerfSkip flag. }
Procedure Get_Options;
Var C: Char;
BEGIN
Repeat
Clean;
Write('Count of BEGIN/END pairs (Y/N)? ');
read(kbd,C);
c:=upcase(c);
Until C In ['Y','N'];
If C = 'Y' Then Count_Be:= True
Else Count_Be:= False;
Repeat
Clean;
Write('Skip printer perforations (Y/N)? ');
read(kbd,C);
c:=upcase(c);
Until C In ['Y','N'];
If C = 'Y' Then PerfSkip:= True
Else PerfSkip:= False;
END; { Get_Options }
{ 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 this
procedure appears at first glance to be repetitive and/or redundant, but
was added to speed up the process of scanning each line of source code.
The program now spits out listings much faster than a 160 cps printer. }
Procedure Scan_Line;
Var Literal: Boolean; { True if in literal field }
Tmp: String[8]; { Temp work area }
Buff2: String[135]; { Working line buffer }
I: Integer;
BEGIN
Literal:= False;
Buff2[0]:= Buff1[0]; { Copy input buffer into working buffer }
For I:= 1 to Length(Buff1) Do
Buff2[I]:= UpCase(Buff1[I]);
Buff2:= Concat(' ',Buff2,' '); { Add on some working space }
For I:= 1 to Length(Buff2) - 7 Do Begin
Tmp:= Copy(Buff2,I,8);
If Not Literal Then Begin
If Tmp[1] In ['{','}','(','*'] Then Begin
If (Tmp[1] = '{') Or (Copy(Tmp,1,2) = '(*') Then
KCount:= Succ(KCount);
If (Tmp[1] = '}') Or (Copy(Tmp,1,2) = '*)') then
KCount:= Pred(KCount);
End;
End;
If KCount = 0 Then Begin
If Tmp[1] = Chr(39) Then Literal:= Not Literal;
If Not Literal And (Tmp[2] In ['B','C','E','R']) Then Begin
If (Copy(Tmp,1,7) = ' BEGIN ') Or (Copy(Tmp,1,6) = ' CASE ') Or
(Tmp = ' RECORD ') Then Begin
BCount:= Succ(BCount);
I:= I + 5;
End;
If (Copy(Tmp,1,4) = ' END') And (Tmp[5] In ['.',' ',';']) Then Begin
BCount:= Pred(BCount);
I:= I + 4;
End;
End;
End;
End;
END; { Scan_Line }
BEGIN
Repeat { Forever }
Get_In_File;
Get_Out_File;
Get_Options;
Lines(1);
Linect:= 1;
If Count_Be Then Begin
KCount:= 0;
BCount:= 0;
Writeln(ListFil,' C B');
End;
While Not EOF(InFile) Do Begin
Readln(InFile,Buff1);
If Count_Be Then Begin
Scan_Line;
Writeln(ListFil,KCount:2,BCount:3,' ',Buff1);
End Else
Writeln(ListFil,Buff1);
If PerfSkip Then Begin
LineCt:= Succ(LineCt);
If LineCt > MaxLine Then Begin
Write(ListFil,FF);
Lines(SkipLine);
LineCt:= 1;
If Count_Be Then Writeln(ListFil,' C B');
End;
End;
End;
Write(CR,LF,'Hit any key to continue...');
read(kbd,ch);
Until False; { Exit is in Get_In_File procedure }
END.