home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
mbug
/
mbug117.arc
/
PASLIST.LBR
/
PASLIST.PQS
/
PASLIST.PAS
Wrap
Pascal/Delphi Source File
|
1979-12-31
|
8KB
|
225 lines
program PascalLister (Input, Output, Infile, Lst);
{
Program by Marco Colli
16 Tudor Avenue,
Cherrybrook NSW 2120,
Australia.
To use this program type
PASLIST <progname>
If <progname> has no extension a default of '.PAS' is added.
Version 1.1, 1 January 1986.
Corrected handling of reserved words in comments and within quotes.
Program could not list itself otherwise!!
Version 1.0, 31 December 1985.
The purpose of this program is to produce a listing of a Pascal program,
in this case TURBO PASCAL, underlining the reserved words as occur. No
account is taken of page boundaries, i.e. listing is continuous.
Words longer than MaxWordLen are truncated.
NOTE: The program must be accepted by the compiler before it is listed
using PASLIST. No error checking is carried out.
}
const
Version = '1.1'; { version number }
MaxWordLen = 20; { longest allowable word }
Blank = ' ';
oQuote = '''';
cQuote = '''';
oBrace = '{';
cBrace = '}';
type
CharIndex = 1 .. MaxWordLen; { counter subrange }
WordType = string[MaxWordLen]; { a word }
const
{ This list of RESERVED WORDS is taken from the TURBO PASCAL 3.0 manual.
It must be maintained in alphabetical order, and ResWordsNum must be
the count of reserved words }
ResWordsNum = 44;
ResWords : array [1..ResWordsNum] of WordType =
('ABSOLUTE','AND','ARRAY','BEGIN','CASE','CONST','DIV','DO',
'DOWNTO','ELSE','END','EXTERNAL','FILE','FOR','FORWARD',
'FUNCTION','GOTO','IF','IN','INLINE','LABEL','MOD','NIL',
'NOT','OF','OR','OVERLAY','PACKED','PROCEDURE','PROGRAM',
'RECORD','REPEAT','SET','SHL','SHR','STRING','THEN','TO',
'TYPE','UNTIL','VAR','WHILE','WITH','XOR');
var
NextWord : WordType; { temporary word buffer }
Chbuffer : char; { character buffer }
Infile : text; { input file }
Exceptions, { set of exception characters }
Letters : set of char; { set of valid characters }
procedure Initialise;
{ Initialise variables and open files required }
var
temp : integer; { temporary variable }
begin
Chbuffer := chr(0);
Letters := ['A'..'Z','a'..'z'];
Exceptions := [oQuote,oBrace];
if (ParamCount = 0) or (ParamCount > 1) then begin
Writeln('usage: PASLIST textfile');
Halt;
end; { if }
NextWord := ParamStr(1);
temp := Pos('.',NextWord); { see if there is an extension }
if (temp = 0) then
NextWord := Concat(NextWord,'.PAS');
Assign(Infile,NextWord);
{$I-}
Reset(Infile);
{$I+}
if (IOResult <> 0) then begin
Writeln('PASLIST: cannot open file ',NextWord);
Halt;
end; { if }
end; { Initialise }
procedure UnGetch (ch : char);
{ Gone too far - put last char back in char buffer }
begin
Chbuffer := ch;
end; { UnGetch }
function Getch : char;
{ Read a character from the input file. If the buffer contains a
character take it. }
var
ch : char; { temporary }
begin
if (Chbuffer <> chr(0)) then begin { character in the buffer }
ch := Chbuffer;
Chbuffer := chr(0); { no character left }
end else { read in from file }
if not Eof(Infile) then
Read(Infile,ch)
else
ch := Blank; { stop any loops }
Getch := ch;
end; { Getch }
procedure SkipQuote (var ch : char);
{ Read and echo the input until the close quote is reached }
begin
repeat
Write(Lst,ch);
ch := Getch;
until (ch = cQuote) or Eof(Infile);
end; { SkipQuote }
{$A- This is a recursive procedure}
procedure SkipComments (var ch : char);
{ Handle comments in a recursive way, thus allowing nesting.
NOTE: The only recognised comments indicators are } {, the compound
'(*' and '*)' characters are not. }
begin
Write(Lst,ch); { left over from calling procedure }
repeat
ch := Getch;
if (ch = oBrace) then
SkipComments(ch); { nested comments }
if (ch = oQuote) then
SkipQuote(ch); { zoom to close quote }
Write(Lst,ch);
until (ch = cBrace) or Eof(Infile);
ch := Getch; { set up for calling procedure }
end; { SkipComments }
{$A+ End of recursive procedure }
procedure ReadWord (var Word : WordType);
{ Read the next word from input file }
var
CharCount : CharIndex; { counter }
ch : char;
begin
Word := ''; { none there yet }
if not Eof(Infile) then
repeat { skip all leading rubbish }
ch := Getch;
if (ch in Exceptions) then
case ch of
oQuote : SkipQuote(ch); { zoom to close quote }
oBrace : SkipComments(ch); { finish off comment }
end; { case }
Write(Lst,ch); { echo it back }
until Eof(Infile) or (ch in Letters);
if not Eof(Infile) then begin
CharCount := 0; { no letters yet }
while (ch in Letters) do begin
if (CharCount < MaxWordLen) then begin { build up word }
CharCount := CharCount + 1;
Word := Concat(Word,ch);
end; { if }
ch := Getch;
if (ch in Letters) then { avoid writing last character }
Write(Lst,ch);
end; { while }
UnGetch(ch); { gone too far, save it }
end; { if }
end; { ReadWord }
procedure Underline (Len : integer);
{ Underline a reserved word. Printer must be able to backspace }
const
BS = ^H; { backspace }
UL = '_'; { underline }
var
i : integer; { temporary }
begin
for i := 1 to Len do
Write(Lst,BS); { move back to start of word }
for i := 1 to Len do
Write(Lst,UL); { underline the word }
end; { Underline }
function ReservedWord (Word : WordType) : boolean;
{ Check the next word with the list of reserved words and return
true if it is there }
var
i : integer; { loop counter }
t : boolean; { temporary }
begin
for i := 1 to Length(Word) do
Word[i] := UpCase(Word[i]); { table entries are in uc }
i := 1;
t := false;
while (i <= ResWordsNum) and (ResWords[i] <= Word) and (not t) do begin
t := (ResWords[i] = Word);
i := i + 1;
end; { for }
ReservedWord := t;
end; { ReservedWord }
begin { PascalLister }
Writeln('PASLIST Version ',Version,' by Marco Colli');
Initialise; { set up files & variables }
while not Eof(Infile) do begin { process file }
ReadWord(NextWord); { get a word }
if ReservedWord(NextWord) then { is it in reserved list? }
Underline(Length(NextWord)); { yes, underline the word }
end; { while }
end. { PascalLister }