Contributor: SWAG SUPPORT TEAM 
(*>Does anyone know of a utility Program that will apply some sort of>reasonable structuring to a pascal source File?
I'm not sure if it's what you want, but the source For a Pascal
reFormatter, etc, was entered in the Fidonet PASCAL Programming
Competition, and came third (I came second!!).
As you can see by the File dates, this is a very recent thing and
since it is Nearly too late I toyed With the idea of just keeping it
to myself. It certainly is not an example of inspired Programming.
But then, I thought, if everyone felt that way you'd have nothing to
chose from and even if this is not a prize winner, mayby someone
else will find it useful.
So here it is... not extensively tested, but I couldn't find any
bugs. Used Pretty to reFormat itself and it still Compiled and
worked. Anyway, the only possible use is to another Turbo Pascal
Programmer who shouldn't have any difficult modifying to suit
himself. They'd probably do that anyway since the output represents
my own peculiar notion as to what a readable Format should be.
'Pretty Printers' date back to the earliest Computer days and
Variations existed For just about any language. However, I've been
unable to find a current one For Turbo Pascal.
Here's what this one does:
Pretty With no parameters generates a syntax message.
Input is scanned line-by-line, Word-by-Word and Byte-by-Byte. Any
identifiers recognized as part of TP's language are replaced by
mixed Case (in a style which _I_ like). Someone else can edit
Constants Borland1 through Borland5 and TP3. (Why TP3 later.) The
first one on a line is capitalized anyway.
A fallout of this is to use selected ones to determine indentation
in increments of 'IndentSpcs' which I arbitrarily set to 3. Change
if you like. Indentation is incremented whenever one of the
'IndentIDs' appears and decremented With 'UnindentIDs' (surprise!).
Single indents are also provided For 'SectionIDs' (Const, Type,
Uses, Var) and For 'NestIDs' (Procedure Function) to make these more
visible. White space is what does it, right?
On the other hand, no attempt is made to affect white space in the
vertical direction. Since that generally stays the way you
originate it.
Any '{', '(' or '''' (Single quote) detected during the line scan
trigger a 'skipit' mode which moves the enclosed stuff directly to
output, unmodified. With one exception. {Comments} which begin a
line are aligned to the left margin (where I like to see Compiler
directives and one line Procedure/Function explanations). Other
{Comments} which begin/end on the same line are shifted so the '}'
aligns at the (80th column) right margin. I think this makes them
more visible than when snuggled up to a semi-colon and getting them
away from the code makes it more legible, too.
and it did look better originally when it used some of my personal
Units. Hastily modified to stand alone. There are, no doubt, some
obvious ways the Programming can be improved (you would probably
have used some nice hash tables to look up key Words) but, as I say,
I thought I would be the only one using this and speed in this Case
is not all that important.
With one exception. Something I worked up For an earlier
application and may be worth looking at -- 'LowCase'.
It will Compile With TP4-TP5.5 and probably TP6 (if it still
supports Inline). I included TP3 stuff because some of the old
software I was looking at was written in it. and it recognizes
Units in a clumsy sort of way.
Switching to chat mode here. if you're Really busy, you can skip the
following.
This thing actually began as a 'Case-converter'. I was trying to
avoid re-inventing some wheels by re-working some old Pascal source
dating back to the late 70's and 80's. Upper Case Programs became a
'standard' back in the days when you talked to main frames through a
teleType machine, which has no lower Case. Sadly, this persisted
long after it was no longer necessary and I find those
all-upper-Case Programs almost unreadable. That is I can't find
what I'm looking For. They were making me crazy. (BTW I suspect
some of this has to do With why Pascal has UpCase but no LoCase.)
I stole the orginal LowCase included here from someone who had done
the intuitive thing -- first test For 'A', then For 'Z'. Changing
to an initial test For 'Z' does two things. A whopping 164 of the
255 possible Characters can be eliminated With just one test and,
since ordinary Text consists of mostly lower Case, these will be
passed over rapidly.
When you received this you thought, "Who the heck is Art Weller? I
don't remember him on the Pascal Echo." Right. I'm a 'lurker'!
Been reading the echo since beFore it had a moderator. (Now we have
an excellent one. Thank you.) I have a machine on a timer which
calls the BBS each morning to read and store several echos which I
read later. Rarely get inspired enough to call back and enter a
discussion. Things usually get resolved nicely without me. I
especially don't want to get involved in such as the 'Goto' wars.
But I monitor the better discussions to enhance my TP skills.
I'm not Really a Programmer (no Formal training, that is --
Computers hadn't been invented when I was in school!), but an
engineer. I'm retired from White Sands Missile Range where I was
Chief of Plans and Programs For (mumble, mumble) years. I
self-taught myself Computers when folks from our Analysis and
Computation Directorate started using jargon on me. I did that well
enough to later help Write a book For people who wanted to convert
from BASIC to Pascal then after "retiring" was an editor For a small
Computer magazine (68 Micro-Journal).
In summary, if you think this worth sharing With others I'll be
pleased enough even without a prize. not even sure it will get
there in time. Snail-Mail, you know.
*)
Program Pretty;
{A 'Pretty Printer' For Turbo Pascal Programs}
{ This Program converts Turbo Pascal identifiers in a source code File to
 mixed Case and indents the code.
 Released into Public Domain June, 1992 on an 'AS IS' basis. Enjoy at your
 own risk.
 Art Weller
 3217 Pagosa Court
 El Paso, Texas 79904
 U. S. A.
 Ph. (915) 755-2516}
{Uses
 Strings;}
Const
 IndentSpcs = 3;
 Borland1 =
 ' Absolute Addr and ArcTan Array Assign AuxInptr AuxOutptr BDos begin Bios '+
 ' BlockRead BlockWrite Boolean Buflen Byte Case Chain Char Chr Close ClrEol '+
 ' ClrScr Color Concat Const Copy Cos Delay Delete DelLine Dispose div do ';
 Borland2 =
 ' Downto Draw else end Eof Eoln Erase Execute Exp External False File '+
 ' FilePos FileSize FillChar Flush For Forward Frac Freemem Function Getmem '+
 ' Goto GotoXY Halt HeapPtr Hi HighVideo HiRes if Implementation in Inline ';
 Borland3 =
 ' Input Insert InsLine Int Integer Interface Intr IOResult KeyPressed '+
 ' Label Length Ln Lo LowVideo Lst Mark MaxAvail Maxint Mem MemAvail Memw Mod '+
 ' Move New Nil NormVideo not Odd of Ofs or Ord Output Overlay Packed ';
 Borland4 =
 ' Pallette Pi Plot Port Pos Pred Procedure Program Ptr Random Randomize Read '+
 ' ReadLn Real Record Release Rename Repeat Reset ReWrite Round Seek Seg Set '+
 ' Shl Shr Sin SizeOf Sound Sqr Sqrt Str String Succ Swap Text then to ';
 Borland5 =
 ' True Trunc Type Unit Until UpCase Uses UsrOutPtr Val Var While Window With '+
 ' Write WriteLn xor ';
 TP3 =
 ' AUX CONinPTR CON CONOUTPTR ConstPTR CrtEXIT CrtinIT ERRorPTR Kbd '+
 ' LStoUTPTR TRM USR USRinPTR ';
 IndentIDs = ' begin Case Const Record Repeat Type Uses Var ';
 UnIndentIDs = ' end Until ';
 SectionIDs = ' Const Type Uses Var ';
 endSection = ' begin Const Uses Var Function Implementation Interface '+
 ' Procedure Type Unit ';
 NestIDs = ' Function Procedure Unit ';
 IDAlphas = ['a'..'z', '1'..'0', '_'];
Var
 Indent,
 endPend,
 Pending,
 UnitFlag : Boolean;
 NestLevel,
 NestIndent,
 IndentNext,
 IndentNow,
 Pntr, LineNum : Integer;
 IDs,
 InFile,
 OutFile,
 ProgWrd,
 ProgLine : String;
 Idents,
 OutID : Array [1..5] of String;
 f1, f2 : Text;
Function LowCase(Ch: Char): Char;
begin
 Inline(
 8ドルA/86ドル/>Ch/ { mov al,>Ch[bp] ;Char to check}
 3ドルC/5ドルA/ { cmp al,'Z' }
 7ドルF/06ドル/ { jg Done }
 3ドルC/41ドル/ { cmp al,'A' }
 7ドルC/02ドル/ { jl Done }
 0ドルC/20ドル/ { or al,20ドル }
 88ドル/86ドル/>LowCase); {Done :mov>LowCase[bp],al }
end;
Function LowCaseStr(InStr : String): String;
Var
 i : Integer;
 len: Byte Absolute InStr;
begin
 LowCaseStr[0] := Chr(len);
 For i := 1 to len do
 LowCaseStr[i] := LowCase(InStr[i]);
end;
Function Blanks(Count: Byte): String; {return String of 'Count' spaces}
Var
 Result: String;
begin
 FillChar(Result[1], Count+1, ' ');
 Result[0] := Chr(Count);
 Blanks := Result;
end;
Procedure StripLeading(Var Str: String); {remove all leading spaces}
begin
 While (Str[1] = #32) and (length(Str)> 0) do
 Delete(Str,1,1);
end;
Procedure Initialize;
begin
 IDs := IndentIDs + UnIndentIDs + endSection;
 OutID[1] := Borland1;
 Idents[1] := LowCaseStr(OutID[1]);
 OutID[2] := Borland2;
 Idents[2] := LowCaseStr(OutID[2]);
 OutID[3] := Borland3;
 Idents[3] := LowCaseStr(OutID[3]);
 OutID[4] := Borland4;
 Idents[4] := LowCaseStr(OutID[4]);
 OutID[5] := Borland5 + TP3;
 Idents[5] := LowCaseStr(OutID[5]);
 Pending := False;
 UnitFlag := False;
 IndentNext := 0;
 IndentNow := 0;
 LineNum := 0;
 NestIndent := 0;
 NestLevel := 0;
end;
Procedure Greeting;
begin
 Writeln;
 Writeln('Pascal Program Indenter');
 Writeln; Writeln;
 Writeln('SYNTAX: INDENT InputFile OutPutFile');
 Writeln(' INDENT InputFile> OutPut');
 Writeln; Writeln;
 Halt(0);
end;
Procedure OpenFiles;
begin
 if paramcount  0 then
 begin
 InFile := ParamStr(1);
 if (pos('.', InFile) = 0) then
 InFile := InFile + '.pas';
 OutFile := Paramstr(2);
 end
 else
 Greeting;
 Assign(f1, InFile);
 Reset(f1);
 Assign(f2, OutFile);
 ReWrite(f2);
end;
Procedure GetWord;
Var
 i,
 index,
 TmpPtr,
 WrdPos : Integer;
 Procedure DecIndent;
 begin
 if (IndentNext> IndentNow) then {begin/end on same line}
 Dec(IndentNext)
 else
 if IndentNow> 0 then
 dec(IndentNow);
 IndentNext := IndentNow; {next line, too}
 end;
begin
 ProgWrd := ' ';
 TmpPtr := Pntr;
 While (LowCase(ProgLine[Pntr]) in IDAlphas) {Convert checked For LCase alpha}
 and (Pntr <= length(ProgLine)) do begin ProgWrd := ProgWrd + LowCase(ProgLine[Pntr]); Inc(Pntr); end; ProgWrd := ProgWrd+' '; {surrounded With blanks to make it unique!} index := 0; Repeat; {is it a Turbo Pascal Word?} inc(index); WrdPos := Pos(ProgWrd, Idents[index]); Until (WrdPos  0) or (index = 5);
 if WrdPos  0 then {found a Pascal Word}
 begin
 Move(OutID[index][WrdPos+1], ProgLine[TmpPtr], Length(ProgWrd)-2);
 if TmpPtr = 1 then
 ProgLine[1] := UpCase(ProgLine[1]);
 if Pos(ProgWrd, IDs)  0 then {only checked if a Pascal Word ^}
 begin
 if Pos(ProgWrd, endSection)  0 then {this includes "SectionIDs"}
 begin {and "NestIDs"}
 if (pos(ProgWrd, NestIDs)  0) then
 begin
 if ProgWrd = ' Unit ' then
 UnitFlag := True;
 if not UnitFlag then
 inc(NestLevel);
 end;
 if Pending then
 DecIndent;
 Pending := Pos(ProgWrd, SectionIDs)  0;
 if ProgWrd = ' Implementation ' then
 UnitFlag := False;
 end;
 if Pos(ProgWrd, IndentIDs)  0 then
 inc(IndentNext); {Indent 1 level}
 if Pos(ProgWrd, UnIndentIDs)  0 then
 begin
 DecIndent; {Unindent 1 level}
 if (IndentNow = 0) and (NestLevel> 0) then
 dec(NestLevel);
 end;
 if NestLevel> 1 then
 NestIndent := 1;
 end;
 end;
end;
Procedure Convert;
 Procedure OutLine;
 Var
 Tabs : String[40];
 begin
 Tabs := Blanks((IndentNow+NestIndent) * IndentSpcs);
 if ProgLine[1] = '{' then
 Writeln(f2, ProgLine)
 else
 Writeln(f2, Tabs, ProgLine);
 IndentNow := IndentNext; { get ready For next line }
 if NestLevel < 2 then NestIndent := 0; end; Procedure Skipto(SearchChar: Char); begin Repeat if pntr> Length(ProgLine) then
 begin
 OutLine;
 Readln(f1, ProgLine); {get another line}
 Pntr := 0;
 end;
 Inc(pntr);
 Until (ProgLine[pntr] = SearchChar) or Eof(f1);
 end;
 Procedure MoveComments;
 Var
 TmpIndent : Integer;
 begin
 if (ProgLine[1] = '{') or (ProgLine[Pntr+1] = '$') then
 begin
 Skipto('}');
 Exit;
 end;
 TmpIndent := (IndentNow+NestIndent) * IndentSpcs;
 While Length(ProgLine) < 80-TmpIndent do Insert(' ', ProgLine, Pntr); While (pos('}', ProgLine)> 80-TmpIndent) and (pos(' {', ProgLine)> 1) do
 begin
 Delete(ProgLine, Pos(' {', ProgLine), 1);
 Dec(Pntr);
 end;
 Skipto('}');
 end;
begin
 While not Eof(f1) do
 begin
 Readln(f1, ProgLine);
 StripLeading(ProgLine);
 if Length(ProgLine) = 0 then
 Writeln(f2)
 else
 begin
 Pntr := 1;
 Repeat
 Case LowCase(ProgLine[pntr]) of
 'a'..'z','_' : GetWord;
 '{' : MoveComments;
 '(' : Skipto(')');
 #39 : Skipto(#39) {Single quote}
 end;
 Inc(pntr)
 Until (pntr>= length(ProgLine));
 OutLine;
 end;
 end; { While }
 Close(f1); Close(f2);
end;
begin
 Initialize;
 OpenFiles;
 Convert;
end.
 

AltStyle によって変換されたページ (->オリジナル) /