home *** CD-ROM | disk | FTP | other *** search
- {ED'S PASCAL BEAUTIFIER v2.33}
- {Copyright 1992 by Edward Lee}
- {edlee@chinet.chi.il.us}
- {Turbo Pascal v4.0}
-
- {31Jan1990 20:00 Program begun}
- {1 Feb1990 16:41}
- {2 Feb1990 16:47 v1.0 complete Capitalizes keywords}
- {4 Feb1990 22:34 v1.1 complete -Lower case option added}
- {7 Feb1990 00:29 v1.2 complete Non-alphabetic token padding added}
- { Identifier parsing debugged}
- {25Mar1990 21:15 v1.3 maintenance ) append rule modified;}
- { (***) parsing debugged; REGISTERS and TEXT keywords added}
- {26May1990 16:56 v1.4 complete optimized loop in identifier parsing}
- { Added identifier substitution option}
- {7 Sep1991 13:03 v1.5 maintenance}
- { The inputfile and outputfile may have the same name.}
- { If only the inputfile is specified, the outputfile is assumed to have}
- { the same name unless -o to STDOUT is specified.}
- { An extension of .PAS is assumed for filenames if the extension is not}
- { specified.}
- {24Nov1991 21:30 v1.51 maintenance corrected minor typos}
- {25Nov1991 06:45 v1.52 maintenance corrected -i and -o options}
- {v1.6x were experimental hashing versions}
- {26Jan1992 23:15 v1.7}
- { Added -m option for Mixed-case keywords.}
- { The first instance of a user-defined identifier sets the precedent in}
- { capitalization for all further instances of that identifier.}
- {24Feb1992 4:46 v1.71 Removed -Lowercase normalization for user identifiers}
- {19Mar1992 v2.0 Many rules have been added or modified. This version}
- { variably nests compound IF THEN ELSE, WHILE, FOR, REPEAT operations + more}
- {02May1992 v2.1 Bugfix. Added pops for nested, non-compound FOR DOs}
- { and WHILE DOs. Restored '(' padding.}
- {14Jun1992 v2.2 Bugfix. Corrected indentation of nested IF THEN ELSE}
- { constructs, indentation of nested WHILE DO constructs}
- {16Jun1992 Added an ElseIndent that is independent from IfIndent
- { to allow: ElseIndent=0 }
- {03Jul1992 v2.3 Replaced binary searches and insertion sorting with hybrid}
- { radix/child-sibling trees for faster average performance.}
- {04Jul1992 v2.31 Bugfix. Corrected an underflow associated with the}
- { conditional line break after a RECORD identifier}
- { v2.32 Modified indentation behavior after line breaks, Added}
- { a conditional line break after the OF keyword}
- {23July1992 v2.33 Bugfix. Exponential real and hexadecimal constants}
- { are now mostly invisible to the indentation and identifier}
- { replacement routines. I extend my apologies to anyone}
- { who was inconvenienced by the previous lack of this context}
- { sensitivity.}
- {24July1992 Added another error message for a full directory}
-
- CONST
- (* Hanging indents after various keywords, in spaces *)
- BeginIndent = 0; (* See LeftmostBeginIndent, below *)
- CaseIndent = 5;
- ConstIndent = 2;
- ElseIndent = 3;
- ForIndent = 4;
- IfIndent = 3;
- LabelIndent = 2;
- LeftmostBeginIndent = 2;
- ProcedureIndent = 2;
- RecordIndent = 2;
- RepeatIndent = 2;
- TypeIndent = 2;
- UntilIndent = 6;
- VarIndent = 2;
- WhileIndent = 6;
- WithIndent = 5;
-
-
- nkeys = 258; (* The number of keywords in keylist[] *)
- maxkeylen = 17; (* The maximum length of any keyword in keylist[] *)
-
- (* If you want to insert or delete keywords in the following list, you
- * must make sure that the constant NKEYS is updated so that it indicates
- * the number of keywords in the list and maintain the value of MAXKEYLEN
- * to be always 1 greater than the maximum length of any keyword in the
- * list. The order no longer matters, except that placing the most
- * frequent keys at the start of the list will speed up the processing of
- * your source programs.
- *)
-
- keylist : ARRAY [1..nkeys] OF
- STRING [maxkeylen] =
- (
- 'Abs', 'Absolute', 'Addr', 'And', 'Append', 'Arc', 'Arctan', 'Array',
- 'Assign', 'AssignCRT', 'Begin', 'Bar', 'Bar3D', 'BlockRead', 'BlockWrite',
- 'Boolean', 'Byte', 'Case', 'Char', 'Chdir', 'Chr', 'Circle', 'ClearDevice',
- 'ClearViewport', 'Close', 'CloseGraph', 'ClrEOL', 'ClrScr', 'Comp',
- 'Concat', 'Const', 'Copy', 'Cos', 'CSeg', 'Dec', 'Delay', 'Delete',
- 'DelLine', 'DetectGraph', 'DiskFree', 'DiskSize', 'Dispose', 'Div', 'Do',
- 'DOSExitCode', 'Double', 'DownTo', 'DrawPoly', 'DSeg', 'Ellipse', 'Else',
- 'End', 'Eof', 'Eoln', 'Erase', 'Exec', 'Exit', 'Exp', 'Extended',
- 'External', 'False', 'File', 'FilePos', 'FileSize', 'FillChar', 'FillPoly',
- 'FindFirst', 'FindNext', 'FloodFill', 'Flush', 'For', 'Forward', 'Frac',
- 'FreeMem', 'Function', 'GetArcCoords', 'GetAspectRatio', 'GetBkColor',
- 'GetColor', 'GetDate', 'GetDir', 'GetFattr', 'GetFillPattern',
- 'GetFillSettings', 'GetFTime', 'GetGraphMode', 'GetImage', 'GetIntVec',
- 'GetLineSettings', 'GetMaxColor', 'GetMaxX', 'GetMaxY', 'GetMem',
- 'GetModeRange', 'GetPallette', 'GetPixel', 'GetTextSettings', 'GetTime',
- 'GetViewSettings', 'GetX', 'GetY', 'Goto', 'GotoXY', 'GraphDefaults',
- 'GraphErrorMesg', 'GraphResult', 'Halt', 'Hi', 'HighVideo', 'If',
- 'ImageSize', 'Implementation', 'In', 'Inc', 'InitGraph', 'InLine',
- 'Insert', 'InsLine', 'Int', 'Integer', 'Interface', 'Interrupt', 'Intr',
- 'IOResult', 'Keep', 'KeyPressed', 'Label', 'Length', 'Line', 'LineRel',
- 'LineTo', 'Ln', 'Lo', 'LongInt', 'LowVideo', 'Mark', 'MaxAvail',
- 'MemAvail', 'MkDir', 'Mod', 'Move', 'MoveRel', 'MoveTo', 'MSDOS', 'New',
- 'Nil', 'NormVideo', 'NoSound', 'Not', 'Odd', 'Of', 'Ofs', 'Or', 'Ord',
- 'OutText', 'OutTextXY', 'Packed', 'PackTime', 'ParamCount', 'ParamStr',
- 'Pi', 'PieSlice', 'Pointer', 'Pos', 'Pred', 'Procedure', 'Program', 'Ptr',
- 'PutImage', 'PutPixel', 'Random', 'Randomize', 'Read', 'ReadKey', 'ReadLn',
- 'Real', 'Record', 'Rectangle', 'RegisterBGIFont', 'RegisterBGIDriver',
- 'Registers', 'Release', 'Rename', 'Repeat', 'Reset', 'RestoreCRTMode',
- 'Rewrite', 'RmDir', 'Round', 'Seek', 'SeekEOF', 'SeekEOLn', 'Seg', 'Set',
- 'SetActivePage', 'SetAllPalette', 'SetBkColor', 'SetColor', 'SetDate',
- 'SetFAttr', 'SetFillPattern', 'SetFillStyle', 'SetFTime',
- 'SetGraphBufSize', 'SetGraphMode', 'SetIntVec', 'SetLineStyle',
- 'SetPalette', 'SetTextBuf', 'SetTextJustify', 'SetTextStyle', 'SetTime',
- 'SetUserCharSize', 'SetViewPort', 'SetVisualPage', 'ShL', 'ShortInt',
- 'ShR', 'Sin', 'Single', 'SizeOf', 'Sound', 'SPtr', 'Sqr', 'Sqrt', 'SSeg',
- 'Str', 'String', 'Succ', 'Swap', 'Text', 'TextBackground', 'TextColor',
- 'TextHeight', 'TextMode', 'TextWidth', 'Then', 'To', 'True', 'Trunc',
- 'Truncate', 'Type', 'Unit', 'UnpackTime', 'Until', 'UpCase', 'Uses', 'Val',
- 'Var', 'WhereX', 'WhereY', 'While', 'Window', 'With', 'Word', 'Write',
- 'WriteLn', 'Xor'
- );
-
- sizebuf = 65520;
- (* If you want to conserve memory at the price of speed, you can reduce
- * sizebuf to any amount down to 1 (not recommended), change the maximum
- * index of mybuf to the value sizebuf-1, and recompile the program.
- *)
-
- TYPE
- mybuf = ARRAY [0..65519] OF
- CHAR;
-
- KeyNode = RECORD
- character : CHAR;
- index : WORD;
- sibling : POINTER;
- child : POINTER;
- END;
-
- KeyNodePtr = ^KeyNode;
-
- StringPtr = ^STRING;
-
- UserNode = RECORD
- character : CHAR;
- instance : StringPtr;
- sibling : POINTER;
- child : POINTER;
- END;
-
- UserNodePtr = ^UserNode;
-
- VAR
- a, b (* Input and Output buffer pointers *)
- : ^mybuf;
-
- FirstKeyTreeLevel (* Using more space than absolutely necessary, for speed *)
- : ARRAY [#0..#255] OF
- KeyNode;
-
- FirstUserTreeLevel (* Using more space than absolutely necessary, for speed *)
- : ARRAY [#0..#255] OF
- UserNode;
-
- IndentationStack
- : ARRAY [0..255] OF
- WORD;
-
- KeyStack
- : ARRAY [0..255] OF
- WORD;
-
- istream, NormalizeKeysToUpperCase, ostream, showbrackcom, showparencom
- : BOOLEAN;
-
- ch, lastch
- : CHAR;
-
- infile, outfile
- : FILE;
-
- i, j, len
- : INTEGER;
-
- HeapPtr
- : POINTER;
-
- ext, filename, iname, CurrentIdentifier, oname, SearchIdent, path,
- ReplacementIdent, ReplacementUpCaseIdent, s, UpCaseIdent
- : STRING;
-
- UPtr
- : UserNodePtr;
-
- col, ibegin, icase, iconst, ido, ielse, iend, ifunction, iif, ifor,
- ilabel, iprocedure, iprogram, irecord, irepeat, ithen, itype, iuntil,
- ivar, iwhile, iwith, ia, ib, iks, is, nread, nwrit, index, index1, iof,
- lastindex
- : WORD;
-
- LABEL
- findasterisk, out, start;
-
- FUNCTION NewKeyNode (c : CHAR) : KeyNodePtr;
- (* Returns a pointer to a newly constructed child-sibling node *)
- VAR
- p : KeyNodePtr;
- BEGIN
- NEW (p);
- IF (p = NIL) THEN
- BEGIN
- WRITELN ('epb: out of memory');
- RELEASE (HeapPtr);
- HALT;
- END;
-
- p^.character := c;
- p^.index := 0;
- p^.sibling := NIL;
- p^.child := NIL;
- NewKeyNode := p;
- END;
-
- FUNCTION NewUserNode (c : CHAR) : UserNodePtr;
- (* Returns a pointer to a newly constructed child-sibling node *)
- VAR
- p : UserNodePtr;
- BEGIN
- NEW (p);
- IF (p = NIL) THEN
- BEGIN
- WRITELN ('epb: out of memory');
- RELEASE (HeapPtr);
- HALT;
- END;
-
- p^.character := c;
- p^.instance := NIL;
- p^.sibling := NIL;
- p^.child := NIL;
- NewUserNode := p;
- END;
-
- (* Initialize the first level for the child-sibling trees *)
- PROCEDURE InitFirstTreeLevels;
- VAR
- i : WORD;
- c : CHAR;
- BEGIN
- FOR i := 0 TO 255 DO
- BEGIN
- c := CHR (i);
-
- IF ( (c >= 'A') AND (c <= 'Z') ) OR
- (c = '_') THEN
- FirstKeyTreeLevel [c] .character := c
- ELSE
- FirstKeyTreeLevel [c] .character := ' ';
-
- FirstKeyTreeLevel [c] .index := 0;
- FirstKeyTreeLevel [c] .sibling := NIL;
- FirstKeyTreeLevel [c] .child := NIL;
-
- IF ( (c >= 'A') AND (c <= 'Z') ) OR
- (c = '_') THEN
- FirstUserTreeLevel [c] .character := c
- ELSE
- FirstUserTreeLevel [c] .character := ' ';
-
- FirstUserTreeLevel [c] .instance := NIL;
- FirstUserTreeLevel [c] .sibling := NIL;
- FirstUserTreeLevel [c] .child := NIL;
- END;
- END; (* InitFirstLevels *)
-
- PROCEDURE InsertKeyTree (s : STRING;
- slot : INTEGER);
- (* Inserts a string in the Pascal Keyword Tree *)
- VAR
- uc : CHAR;
- i, len : WORD;
- p : KeyNodePtr;
- LABEL
- loop;
- BEGIN
- len := LENGTH (s);
-
- IF (len = 0) THEN (* There is nothing to insert *)
- EXIT;
-
- uc := UPCASE (s [1]);
-
- IF (uc <> FirstKeyTreeLevel [uc] .character) THEN
- FirstKeyTreeLevel [uc] .character := uc;
-
- IF (len = 1) THEN
- BEGIN
- FirstKeyTreeLevel [uc] .index := slot;
- EXIT;
- END;
-
- i := 2;
- p := FirstKeyTreeLevel [uc] .child;
-
- IF (p = NIL) THEN (* If the first child does not exist, create it *)
- BEGIN
- p := NewKeyNode (UPCASE (s [2]) );
- FirstKeyTreeLevel [uc] .child := p;
- END;
-
- loop :
- IF (UPCASE (s [i]) = p^.character) THEN
- BEGIN
- IF (i = len) THEN (* Indicate the termination of the string *)
- BEGIN
- IF (p^.index = 0) THEN
- p^.index := slot;
- EXIT;
- END;
-
- (* Assert: i < len *)
- INC (i);
- IF (p^.child = NIL) THEN
- p^.child := NewKeyNode (UPCASE (s [i]) );
- p := p^.child;
- GOTO loop;
- END
- ELSE
- BEGIN
- IF (p^.sibling = NIL) THEN
- p^.sibling := NewKeyNode (UPCASE (s [i]) );
- p := p^.sibling;
- GOTO loop;
- END;
-
- END; (* InsertKeyTree *)
-
-
- FUNCTION SearchKeyTree (s : STRING) : INTEGER;
- (* Determines whether or not a string is in the Pascal Keyword Tree *)
- (* Returns an index to the keylist[] element on success, a 0 on failure *)
- VAR
- i, len : INTEGER;
- p : KeyNodePtr;
- LABEL
- loop;
-
- BEGIN
- len := LENGTH (s);
-
- IF (len = 0) THEN (* Should a null string be considered to be present? *)
- BEGIN
- SearchKeyTree := 0; (* In this program, no *)
- EXIT;
- END;
-
- IF (s [1] <> FirstKeyTreeLevel [s [1] ] .character) THEN
- BEGIN
- SearchKeyTree := 0; (* Because the length of the string is >= 1 *)
- EXIT;
- END;
-
- IF (len = 1) THEN
- BEGIN
- IF (FirstKeyTreeLevel [s [1] ] .index = 0) THEN
- SearchKeyTree := 0
- ELSE
- SearchKeyTree := FirstKeyTreeLevel [s [1] ] .index;
- EXIT;
- END;
-
- i := 2;
- p := FirstKeyTreeLevel [s [1] ] .child;
-
- IF (p = NIL) THEN
- BEGIN
- SearchKeyTree := 0; (* Because the tree terminated early *)
- EXIT;
- END;
-
- loop :
- IF (s [i] = p^.character) THEN
- BEGIN
- IF (i = len) THEN (* Stop searching *)
- BEGIN
- IF (p^.index = 0) THEN
- SearchKeyTree := 0
- ELSE
- SearchKeyTree := p^.index;
- EXIT;
- END;
-
- (* Assert: i < len *)
- p := p^.child;
- IF (p = NIL) THEN
- BEGIN
- SearchKeyTree := 0; (* Because the tree terminated early *)
- EXIT;
- END;
- INC (i);
- GOTO loop;
- END
- ELSE
- BEGIN
- p := p^.sibling;
- IF (p = NIL) THEN
- BEGIN
- SearchKeyTree := 0; (* Because the tree terminated early *)
- EXIT;
- END;
- GOTO loop;
- END;
-
- END; (* SearchKeyTree *)
-
-
- PROCEDURE InsertUserTree (s : STRING);
- (* Inserts a string in the User Identifier Tree *)
- VAR
- uc : CHAR;
- i, len : WORD;
- p : UserNodePtr;
- LABEL loop;
- BEGIN
- len := LENGTH (s);
-
- IF (len = 0) THEN (* There is nothing to insert *)
- EXIT;
-
- uc := UPCASE (s [1]);
-
- IF (uc <> FirstUserTreeLevel [uc] .character) THEN
- FirstUserTreeLevel [uc] .character := uc;
-
- IF (len = 1) THEN
- BEGIN
- GETMEM (FirstUserTreeLevel [uc] .instance, 2); (* 1 for the length indicator, 1 for the string *)
- FirstUserTreeLevel [uc] .instance^ := s;
- EXIT;
- END;
-
- i := 2;
- p := FirstUserTreeLevel [uc] .child;
-
- IF (p = NIL) THEN (* If the first child does not exist, create it *)
- BEGIN
- p := NewUserNode (UPCASE (s [2]) );
- FirstUserTreeLevel [uc] .child := p;
- END;
-
- loop :
- IF (UPCASE (s [i]) = p^.character) THEN
- BEGIN
- IF (i = len) THEN (* Indicate the termination of the string *)
- BEGIN
- IF (p^.instance = NIL) THEN
- BEGIN
- GETMEM (p^.instance, 1 + len);
- p^.instance^ := s;
- END;
- EXIT;
- END;
-
- (* Assert: i < len *)
- INC (i);
- IF (p^.child = NIL) THEN
- p^.child := NewUserNode (UPCASE (s [i]) );
- p := p^.child;
- GOTO loop;
- END
- ELSE
- BEGIN
- IF (p^.sibling = NIL) THEN
- p^.sibling := NewUserNode (UPCASE (s [i]) );
- p := p^.sibling;
- GOTO loop;
- END;
-
- END; (* InsertUserTree *)
-
-
- FUNCTION SearchUserTree (s : STRING) : UserNodePtr;
- (* Determines whether or not a string is in the User Identifier Tree *)
- (* Returns a pointer to the final node on success, a NIL pointer on failure *)
- VAR
- i, len : INTEGER;
- p : UserNodePtr;
- LABEL
- loop;
- BEGIN
- len := LENGTH (s);
-
- IF (len = 0) THEN (* Should a null string be considered to be present? *)
- BEGIN
- SearchUserTree := NIL; (* In this program, no *)
- EXIT;
- END;
-
- IF (s [1] <> FirstUserTreeLevel [s [1] ] .character) THEN
- BEGIN
- SearchUserTree := NIL; (* Because the length of the string is >= 1 *)
- EXIT;
- END;
-
- IF (len = 1) THEN
- BEGIN
- IF (FirstUserTreeLevel [s [1] ] .instance = NIL) THEN
- SearchUserTree := NIL
- ELSE
- SearchUserTree := @FirstUserTreeLevel [s [1] ];
- EXIT;
- END;
-
- i := 2;
- p := FirstUserTreeLevel [s [1] ] .child;
-
- IF (p = NIL) THEN
- BEGIN
- SearchUserTree := NIL; (* Because the tree terminated early *)
- EXIT;
- END;
-
- loop :
- IF (s [i] = p^.character) THEN
- BEGIN
- IF (i = len) THEN (* Stop searching *)
- BEGIN
- IF (p^.instance = NIL) THEN
- SearchUserTree := NIL
- ELSE
- SearchUserTree := p;
- EXIT;
- END;
-
- (* Assert: i < len *)
- p := p^.child;
- IF (p = NIL) THEN
- BEGIN
- SearchUserTree := NIL; (* Because the tree terminated early *)
- EXIT;
- END;
- INC (i);
- GOTO loop;
- END
- ELSE
- BEGIN
- p := p^.sibling;
- IF (p = NIL) THEN
- BEGIN
- SearchUserTree := NIL; (* Because the tree terminated early *)
- EXIT;
- END;
- GOTO loop;
- END;
-
- END; (* SearchUserTree *)
-
-
- {$F+}
- FUNCTION HeapFunc (size : WORD) : INTEGER; {$F-}
- BEGIN
- HeapFunc := 1; (* Make NEW return a NIL pointer when out of memory *)
- END;
-
- PROCEDURE PushIndent (indent : WORD);
- BEGIN
- IF (is < 256) THEN
- BEGIN
- INC (is);
- IndentationStack [is] := IndentationStack [is - 1] + indent;
- END;
- END;
-
- PROCEDURE PopIndent;
- BEGIN
- IF (is > 0) THEN
- DEC (is);
- END;
-
- PROCEDURE PushKey (key : WORD);
- BEGIN
- IF (iks < 256) THEN
- BEGIN
- INC (iks);
- KeyStack [iks] := key;
- END;
- END;
-
- PROCEDURE PopKey;
- BEGIN
- IF (iks > 0) THEN
- DEC (iks);
- END;
-
- PROCEDURE writeblock;
- BEGIN
- BLOCKWRITE (outfile, b^, ib, nwrit);
-
- IF (nwrit <> ib) AND (oname <> '') THEN (* Don't check output to STDOUT *)
- BEGIN
- WRITELN ('epb: Cannot finish outputting (out of disk space?)');
- CLOSE (outfile);
- RELEASE (HeapPtr);
- HALT;
- END;
-
- ib := 0;
- END; (* writeblock *)
-
- PROCEDURE getblock;
- BEGIN
- ia := 0;
- BLOCKREAD (infile, a^, sizebuf, nread);
-
- IF (nread = 0) THEN
- BEGIN
- writeblock;
- CLOSE (infile);
- RELEASE (HeapPtr);
- HALT;
- END;
- END; (* getblock *)
-
- PROCEDURE OutPaddedChar (c : CHAR); (* Output a character, possibly w/ padding *)
- BEGIN
- CASE c OF
- '[', '(', '<', '+', '/', '*', '-', ':' :
- IF (lastch <> #32) THEN
- BEGIN
- b^ [ib] := #32;
- INC (ib);
- IF (ib = sizebuf) THEN
- writeblock;
- INC (col);
- END;
-
- '=' :
- IF (lastch > #32) AND
- (lastch <> ':') AND (lastch <> '<') AND (lastch <> '>') THEN
- BEGIN
- b^ [ib] := #32;
- INC (ib);
- IF (ib = sizebuf) THEN
- writeblock;
- INC (col);
- END;
-
- '>' :
- IF (lastch > #32) AND
- (lastch <> '<') THEN
- BEGIN
- b^ [ib] := #32;
- INC (ib);
- IF (ib = sizebuf) THEN
- writeblock;
- INC (col);
- END;
-
- ')' :
- IF (lastch = ')') THEN
- BEGIN
- b^ [ib] := #32;
- INC (ib);
- IF (ib = sizebuf) THEN
- writeblock;
- INC (col);
- END;
-
- ELSE (* case c *)
-
- IF (c > #32) THEN
- CASE lastch OF
- ':' :
- IF (c <> '=') THEN
- BEGIN
- b^ [ib] := #32;
- INC (ib);
- IF (ib = sizebuf) THEN
- writeblock;
- INC (col);
- END;
-
- '<' :
- IF (c <> '>') AND (c <> '=') THEN
- BEGIN
- b^ [ib] := #32;
- INC (ib);
- IF (ib = sizebuf) THEN
- writeblock;
- INC (col);
- END;
-
- '>' :
- IF (c <> '=') THEN
- BEGIN
- b^ [ib] := #32;
- INC (ib);
- IF (ib = sizebuf) THEN
- writeblock;
- INC (col);
- END;
-
- ')' :
- IF (c <> ';') AND (c <> ',') THEN
- BEGIN
- b^ [ib] := #32;
- INC (ib);
- IF (ib = sizebuf) THEN
- writeblock;
- INC (col);
- END;
-
- '=', '+', '/', '*', '-', ',' :
- BEGIN
- b^ [ib] := #32;
- INC (ib);
- IF (ib = sizebuf) THEN
- writeblock;
- INC (col);
- END;
-
- ']' :
- IF (c <> ')') AND (c <> ';') AND (c <> ',') AND (c <> '^') THEN
- BEGIN
- b^ [ib] := #32;
- INC (ib);
- IF (ib = sizebuf) THEN
- writeblock;
- INC (col);
- END;
-
- END; (* case lastch *)
- END; (* case c *)
-
- b^ [ib] := c;
- INC (ib);
- IF (ib = sizebuf) THEN
- writeblock;
- INC (col);
- lastch := c;
- END; (* OutPaddedChar *)
-
- PROCEDURE OutLiteralChar (c : CHAR); (* Output a character without padding *)
- BEGIN
- b^ [ib] := c;
- INC (ib);
- IF (ib = sizebuf) THEN
- writeblock;
- INC (col);
- lastch := c;
- END; (* OutLiteralChar *)
-
- PROCEDURE OutIdent (s : STRING); (* Output an identifier *)
- VAR
- i, len
- : INTEGER;
- BEGIN
- len := LENGTH (s);
- IF (len <> 0) THEN
- OutPaddedChar (s [1]);
-
- FOR i := 2 TO len DO
- BEGIN
- b^ [ib] := s [i];
- INC (ib);
- IF (ib = sizebuf) THEN
- writeblock;
- INC (col);
- END;
-
- lastch := s [len];
- END; (* OutIdent *)
-
- (* Split up a Path, Filename, Extension string *)
- PROCEDURE SplitPFE (pf : STRING;
- VAR p : STRING;
- VAR f : STRING;
- VAR e : STRING);
- VAR i : INTEGER;
- BEGIN
- p := '';
- f := '';
- e := '';
- i := LENGTH (pf);
-
- WHILE ( (POS (COPY (pf, i, 1), ':/\') = 0) AND (i > 0) ) DO
- DEC (i);
-
- p := COPY (pf, 1, i);
- f := COPY (pf, i + 1, 255);
-
- i := POS ('.', f);
-
- IF (i > 0) THEN
- BEGIN
- e := COPY (f, i + 1, 3);
- f := COPY (f, 1, i);
- END;
- END;
-
- PROCEDURE breakline;
- BEGIN
- b^ [ib] := #13;
- INC (ib);
- IF (ib = sizebuf) THEN
- writeblock;
- b^ [ib] := #10;
- INC (ib);
- IF (ib = sizebuf) THEN
- writeblock;
- lastch := #10;
- col := 0;
- END;
-
- PROCEDURE skipwhitespace;
- BEGIN
- WHILE (a^ [ia] < #33) DO
- BEGIN
- INC (ia);
- IF (ia >= nread) THEN
- getblock;
- END;
- END; (* skipwhitespace *)
-
- PROCEDURE skipspace;
- BEGIN
- WHILE (a^ [ia] < #33) AND (a^ [ia] <> #13) AND (a^ [ia] <> #10) DO
- BEGIN
- INC (ia);
- IF (ia >= nread) THEN
- getblock;
- END;
- END; (* skipspace *)
-
- PROCEDURE indent;
- VAR i : WORD;
- BEGIN
- FOR i := 1 TO IndentationStack [is] DO
- BEGIN
- b^ [ib] := #32;
- INC (ib);
- IF (ib = sizebuf) THEN
- writeblock;
- END;
-
- IF (IndentationStack [is] <> 0) THEN (* Keep track of the current column *)
- BEGIN
- col := col + IndentationStack [is];
- lastch := #32;
- END;
- END; (* indent *)
-
- PROCEDURE condbreakline;
- VAR
- ch : CHAR;
- s : STRING;
- i, len : WORD;
- BEGIN
- ch := a^ [ia];
- IF (ch <> #13) THEN
- BEGIN
- s := '';
- WHILE (a^ [ia] < #33) AND (a^ [ia] <> #13) AND (a^ [ia] <> #10) DO
- BEGIN
- s := s + a^ [ia]; (* Save spaces *)
- INC (ia);
- IF (ia >= nread) THEN
- getblock;
- END;
- len := LENGTH (s);
- ch := a^ [ia];
- IF (ch = '(') OR (ch = '{') THEN
- FOR i := 1 TO len DO (* Write saved spaces *)
- BEGIN
- b^ [ib] := s [i];
- INC (ib);
- IF (ib = sizebuf) THEN
- writeblock;
- INC (col);
- END
- ELSE
- breakline;
- END;
- END; (* condbreakline *)
-
- {---- MAIN PROGRAM ----}
- BEGIN
- IF (PARAMCOUNT = 0) THEN
- BEGIN
- WRITELN (#10'ED''S PASCAL BEAUTIFIER v2.33, Copyright 1992 by Edward Lee, -Ed L');
- WRITELN ('edlee@chinet.chi.il.us THIS PROGRAM MAY NOT BE DISTRIBUTED FOR PROFIT');
- WRITELN (#10'EPB normalizes the indentation of (Turbo) Pascal source code, including');
- WRITELN ('nested IF THEN ELSE constructs, and normalizes the capitalization of');
- WRITELN ('(Turbo) Pascal identifiers to either upper case or mixed case, defaulting');
- WRITELN ('to upper case. Each non-(Turbo) Pascal identifier has its capitalization');
- WRITELN ('normalized to the way it first appears in the input stream. EPB can');
- WRITELN ('do identifier substitutions by ignoring comments, sub-strings, and literal');
- WRITELN ('strings. An input file, if specified, is renamed to *.BAK before execution.');
- WRITELN ('This program, EPB, is provided without warranty. Use EPB at your own risk.');
- WRITELN (#10'INVOCATION (items in brackets are optional):');
- WRITELN (' epb [-bimop] [InputFile[.PAS]] [OutputFile[.PAS]] [-s Original Replacement]');
- WRITELN (#10'OPTIONS (flexible in case, grouping, and positioning on the command line):');
- WRITELN (' -b Shut off the output of Bracket comments: { ... }');
- WRITELN (' -p Shut off the output of Parentheses comments: (* ... *)');
- WRITELN (' -i Use the standard Input (STDIN) stream for input instead of InputFile');
- WRITELN (' -o Use the standard Output (STDOUT) stream for output instead of OutputFile');
- WRITELN (' -m Normalize all keywords to Mixed case rather than the default upper case');
- WRITELN (' -s Substitute all occurrences of an Original identifier with a Replacement');
- HALT;
- END;
-
- InitFirstTreeLevels;
-
- (* Copy keylist[] in a normalized form to the Key Tree *)
- FOR i := 1 TO nkeys DO
- InsertKeyTree (keylist [i], i);
-
- showparencom := TRUE;
- showbrackcom := TRUE;
- istream := FALSE;
- ostream := FALSE;
- NormalizeKeysToUpperCase := TRUE;
-
- SearchIdent := '';
- ReplacementIdent := '';
- ReplacementUpCaseIdent := '';
-
- i := 0;
- WHILE (i < PARAMCOUNT) DO (* Process options *)
- BEGIN
- INC (i);
- s := PARAMSTR (i);
- IF (s [1] = '-') THEN
- BEGIN
- IF (POS ('b', s) > 0) OR (POS ('B', s) > 0) THEN
- showbrackcom := FALSE;
- IF (POS ('p', s) > 0) OR (POS ('P', s) > 0) THEN
- showparencom := FALSE;
- IF (POS ('i', s) > 0) OR (POS ('I', s) > 0) THEN
- istream := TRUE;
- IF (POS ('o', s) > 0) OR (POS ('O', s) > 0) THEN
- ostream := TRUE;
- IF (POS ('m', s) > 0) OR (POS ('M', s) > 0) THEN
- NormalizeKeysToUpperCase := FALSE;
- IF (POS ('s', s) > 0) OR (POS ('S', s) > 0) THEN
- BEGIN
- INC (i);
- SearchIdent := PARAMSTR (i);
- INC (i);
- ReplacementIdent := PARAMSTR (i);
- IF (i > PARAMCOUNT) THEN
- BEGIN
- WRITELN ('epb: Error. The -s option has been used without enough parameters.');
- HALT;
- END;
- END; (* if (pos ('s' ... *)
- END; (* if (s [1] ... *)
- END; (* while *)
-
- (* Normalize Original and Replacement strings via upper case function *)
- FOR i := 1 TO LENGTH (SearchIdent) DO
- SearchIdent [i] := UPCASE (SearchIdent [i]);
-
- FOR i := 1 TO LENGTH (ReplacementIdent) DO
- ReplacementUpCaseIdent := ReplacementUpCaseIdent + UPCASE (ReplacementIdent [i]);
-
- iname := '';
- oname := '';
-
- IF NOT (istream AND ostream) THEN
- BEGIN
- i := 0;
- WHILE (i < PARAMCOUNT) DO (* Get filename(s) *)
- BEGIN
- INC (i);
- s := PARAMSTR (i);
-
- IF (s [1] <> '-') THEN (* Skip option flags *)
- BEGIN
- IF (istream) THEN (* Input is from STDIN *)
- BEGIN
- oname := s;
- GOTO out;
- END
- ELSE
- IF (ostream) THEN (* Output is to STDOUT *)
- BEGIN
- iname := s;
- GOTO out;
- END
- ELSE
- IF (iname = '') THEN (* Input is from infile *)
- iname := s
- ELSE
- BEGIN
- oname := s; (* Output is to outfile *)
- GOTO out;
- END;
- END (* if (s [1] ... *)
-
- ELSE
-
- IF (POS ('s', s) > 0) OR (POS ('S', s) > 0) THEN
- i := i + 2;
-
- END; (* while *)
- END; (* if not *)
-
- out :
- SplitPFE (iname, path, filename, ext);
-
- IF (filename <> '') THEN
- IF (COPY (filename, LENGTH (filename), 1) <> '.') THEN
- BEGIN
- filename := filename + '.';
- iname := path + filename + 'PAS';
- END;
-
- s := path + filename + 'BAK';
-
- SplitPFE (oname, path, filename, ext);
-
- IF (filename <> '') THEN
- IF (COPY (filename, LENGTH (filename), 1) <> '.') THEN
- oname := path + filename + '.PAS';
-
- IF (iname <> '') THEN
- IF (iname = oname) OR
- ( (oname = '') AND NOT ostream) THEN
- BEGIN
- ASSIGN (infile, s); (* If a backup file already exists, erase it *)
- {$I-}
- RESET (infile, 1); {$I+}
- IF (IORESULT = 0) THEN
- BEGIN
- CLOSE (infile);
- ERASE (infile);
- END;
-
- ASSIGN (infile, iname);
- {$I-}
- RESET (infile, 1); {$I+}
- IF (IORESULT = 0) THEN
- BEGIN
- CLOSE (infile);
- RENAME (infile, s);
- END
- ELSE
- BEGIN
- WRITELN ('epb: Cannot rename original file, ', iname, ', to ', s, '.');
- HALT;
- END;
-
- oname := iname;
- iname := s;
- END;
-
- ASSIGN (infile, iname);
- {$I-}
- RESET (infile, 1); {$I+}
- IF (IORESULT <> 0) THEN
- BEGIN
- WRITELN ('epb: Cannot open input file, ', iname);
- HALT;
- END;
-
- ASSIGN (outfile, oname);
- {$I-}
- REWRITE (outfile, 1); {$I+}
- IF (IORESULT <> 0) THEN
- BEGIN
- WRITELN ('epb: Error opening output file, ', oname, '. DOS file limit reached?');
- HALT;
- END;
-
- HeapError := @HeapFunc;
-
- MARK (HeapPtr);
-
- NEW (a);
- NEW (b);
- getblock;
-
- IF (a = NIL) OR (b = NIL) THEN
- BEGIN
- WRITELN ('epb: There is not enough free conventional memory for epb to run.');
- RELEASE (HeapPtr);
- HALT;
- END;
-
- col := 0;
- ib := 0;
- iks := 0;
- KeyStack [iks] := 0;
- is := 0;
- IndentationStack [is] := 0;
- index := 0;
- lastch := #0;
- CurrentIdentifier := '';
- UpCaseIdent := '';
-
- (* Soft-coded indexes to some keywords of interest *)
- ibegin := SearchKeyTree ('BEGIN');
- icase := SearchKeyTree ('CASE');
- iconst := SearchKeyTree ('CONST');
- ido := SearchKeyTree ('DO');
- iend := SearchKeyTree ('END');
- ifor := SearchKeyTree ('FOR');
- ifunction := SearchKeyTree ('FUNCTION');
- iif := SearchKeyTree ('IF');
- ithen := SearchKeyTree ('THEN');
- ielse := SearchKeyTree ('ELSE');
- ilabel := SearchKeyTree ('LABEL');
- iof := SearchKeyTree ('OF');
- iprocedure := SearchKeyTree ('PROCEDURE');
- iprogram := SearchKeyTree ('PROGRAM');
- irecord := SearchKeyTree ('RECORD');
- irepeat := SearchKeyTree ('REPEAT');
- itype := SearchKeyTree ('TYPE');
- iuntil := SearchKeyTree ('UNTIL');
- ivar := SearchKeyTree ('VAR');
- iwhile := SearchKeyTree ('WHILE');
- iwith := SearchKeyTree ('WITH');
-
- skipwhitespace;
- PushKey (iprogram);
-
- start :
- ch := a^ [ia];
-
- IF (lastch = #10) THEN
-
- BEGIN
- col := 0;
- skipspace;
- ch := a^ [ia];
- IF ( (ch < 'A') OR (ch > 'Z') ) AND
- ( (ch < 'a') OR (ch > 'z') ) AND
- (ch <> '_') THEN
- indent;
- END;
-
- CASE ch OF
- ';' :
- BEGIN
- OutLiteralChar (ch);
- INC (ia);
- IF (ia >= nread) THEN
- getblock;
- IF (KeyStack [iks] = iuntil) THEN
- BEGIN
- PopIndent;
- PopKey;
- END;
-
- condbreakline;
-
- WHILE (KeyStack [iks] = ido) DO
- BEGIN
- PopIndent;
- PopKey;
- END;
-
- WHILE (KeyStack [iks] = ithen) OR (KeyStack [iks] = ielse) DO
- BEGIN
- PopIndent;
- PopKey;
- END;
-
- GOTO start;
- END; (* ';' *)
-
-
- #39 : (* Do not process the contents of literal strings *)
- BEGIN
- OutPaddedChar (a^ [ia]);
- INC (ia);
- IF (ia >= nread) THEN
- getblock;
- WHILE (a^ [ia] <> #39) DO
- BEGIN
- OutLiteralChar (a^ [ia]);
- INC (ia);
- IF (ia >= nread) THEN
- getblock;
- END;
- OutLiteralChar (a^ [ia]);
- INC (ia);
- IF (ia >= nread) THEN
- getblock;
- GOTO start;
- END; (* ' *)
-
-
- '{' : (* Do not process the contents of { ... } comments *)
- BEGIN
- IF (showbrackcom) THEN
- BEGIN
- OutLiteralChar (a^ [ia]);
- INC (ia);
- IF (ia >= nread) THEN
- getblock;
- WHILE (a^ [ia] <> '}') DO
- BEGIN
- OutLiteralChar (a^ [ia]);
- INC (ia);
- IF (ia >= nread) THEN
- getblock;
- END;
- OutLiteralChar (a^ [ia]);
- INC (ia);
- IF (ia >= nread) THEN
- getblock;
- END
- ELSE
- BEGIN
- INC (ia);
- IF (ia >= nread) THEN
- getblock;
- WHILE (a^ [ia] <> '}') DO
- BEGIN
- INC (ia);
- IF (ia >= nread) THEN
- getblock;
- END;
- INC (ia);
- IF (ia >= nread) THEN
- getblock;
- END;
- IF (a^ [ia] <> #13) THEN
- BEGIN
- breakline;
- skipspace;
- END;
- GOTO start;
- END; (* {} *)
-
-
- '(' : { Do not process the contents of (* ... *) comments }
- BEGIN
- INC (ia);
- IF (ia >= nread) THEN
- getblock;
- IF (a^ [ia] <> '*') THEN
- BEGIN
- OutPaddedChar (ch);
- GOTO start;
- END
- ELSE (* A comment has begun *)
- BEGIN
- IF (showparencom) THEN
- BEGIN
- OutLiteralChar (ch);
- OutLiteralChar (a^ [ia]);
- END;
-
- INC (ia);
- IF (ia >= nread) THEN
- getblock;
- IF (showparencom) THEN
- OutLiteralChar (a^ [ia]);
-
- findasterisk :
- WHILE (a^ [ia] <> '*') DO
- BEGIN
- INC (ia);
- IF (ia >= nread) THEN
- getblock;
- IF (showparencom) THEN
- OutLiteralChar (a^ [ia]);
- END; (* a^[ia] = '*' *)
-
- INC (ia);
- IF (ia >= nread) THEN
- getblock;
- IF (showparencom) THEN
- OutLiteralChar (a^ [ia]);
-
- IF (a^ [ia] <> ')') THEN
- GOTO findasterisk;
- INC (ia);
- IF (ia >= nread) THEN
- getblock;
- IF (a^ [ia] <> #13) THEN
- BEGIN
- breakline;
- skipspace;
- END;
- GOTO start;
- END;
- END; { (* *) }
-
-
- 'A'..'Z', 'a'..'z', '_' : (* Collect and process identifiers *)
- BEGIN
- REPEAT
- UpCaseIdent := UpCaseIdent + UPCASE (ch);
- CurrentIdentifier := CurrentIdentifier + ch;
- INC (ia);
- IF (ia >= nread) THEN
- getblock;
- ch := a^ [ia];
- UNTIL ( (ch < 'A') OR (ch > 'Z') ) AND
- ( (ch < 'a') OR (ch > 'z') ) AND
- ( (ch < '0') OR (ch > '9') ) AND
- (ch <> '_'); {Turbo Pascal Sets are too slow}
-
- (*
- if (upcaseident = 'FOOZ') then
- begin
- writeln('{');
- writeln('iks = ', iks);
- writeln('keystack[iks] = ', keystack[iks]);
- if (keystack[iks] > 0) then
- writeln('keylist[keystack[iks]] = ', keylist[keystack[iks]]);
- writeln('is = ', is);
- writeln('indentationstack[is] = ', indentationstack[is]);
- writeln('col = ', col);
- writeln('}');
- end;
- *)
-
- IF (UpCaseIdent = SearchIdent) THEN
- BEGIN
- UpCaseIdent := ReplacementUpCaseIdent;
- CurrentIdentifier := ReplacementIdent;
- END;
-
- lastindex := index;
-
- index := SearchKeyTree (UpCaseIdent);
-
- IF (index = iend) THEN
- BEGIN
- PopIndent;
- IF (KeyStack [iks] = icase) THEN
- BEGIN
- PopKey;
- IF (KeyStack [iks] = irecord) THEN
- PopIndent;
- END;
- END
- ELSE
- IF (index = iuntil) THEN
- BEGIN
- PopIndent;
- PopKey;
- END
- ELSE
- IF (index = ielse) AND (KeyStack [iks] = icase) THEN
- PopIndent
- ELSE
- IF (KeyStack [iks] = iprogram) OR
- (KeyStack [iks] = iprocedure) OR
- (KeyStack [iks] = ifunction) THEN
- BEGIN
- IF (index = ivar) OR
- (index = iconst) OR
- (index = itype) OR
- (index = iprocedure) OR
- (index = ifunction) OR
- (index = ilabel) THEN
- PopIndent
- ELSE
- IF (index = ibegin) THEN
- BEGIN
- PopIndent;
- PopKey;
- END;
- END;
-
- IF (lastch = #10) THEN
- indent;
-
- (* Output Identifier *)
- IF (index <> 0) THEN
- IF (NormalizeKeysToUpperCase) THEN
- OutIdent (UpCaseIdent)
- ELSE
- OutIdent (keylist [index])
- ELSE
- BEGIN
- UPtr := SearchUserTree (UpCaseIdent);
-
- IF (UPtr <> NIL) THEN
- OutIdent (UPtr^.instance^)
- ELSE
- BEGIN
- InsertUserTree (CurrentIdentifier);
- OutIdent (CurrentIdentifier);
- END;
- END;
-
- IF (index = iend) THEN
- BEGIN
- IF (KeyStack [iks] = ibegin) THEN
- BEGIN
- PopKey;
-
- WHILE (KeyStack [iks] = ido) DO
- BEGIN
- PopIndent;
- PopKey;
- END;
-
- WHILE (KeyStack [iks] = ielse) DO
- BEGIN
- PopIndent;
- PopKey;
- END;
-
- IF (KeyStack [iks] = ithen) THEN
- BEGIN
- PopIndent;
- PopKey;
- END;
-
- IF (KeyStack [iks] = iprocedure) OR (KeyStack [iks] = ifunction) THEN
- PopKey;
- END
- ELSE
- IF (KeyStack [iks] = irecord) THEN
- BEGIN
- PopIndent;
- PopKey;
- END;
- END
- ELSE
- IF (lastindex = ido) AND
- (index <> ibegin) AND
- (index <> iif) AND
- (index <> ifor) AND
- (index <> irepeat) AND
- (index <> iwhile) AND
- (index <> icase) THEN
- BEGIN
- REPEAT
- PopIndent;
- PopKey;
- UNTIL (KeyStack [iks] <> ido);
-
- WHILE (KeyStack [iks] = ielse) DO
- BEGIN
- PopIndent;
- PopKey;
- END;
-
- IF (KeyStack [iks] = ithen) THEN
- BEGIN
- PopIndent;
- PopKey;
- END;
- END
- ELSE
- IF (lastindex = ielse) AND
- (index <> ibegin) AND
- (index <> iif) AND
- (index <> ifor) AND
- (index <> irepeat) AND
- (index <> iwhile) AND
- (index <> icase) AND
- (index <> iwith) THEN
- BEGIN
- REPEAT
- PopIndent;
- PopKey;
- UNTIL (KeyStack [iks] <> ielse);
- IF (KeyStack [iks] = ithen) THEN
- BEGIN
- PopIndent;
- PopKey;
- END;
- END
- ELSE
- IF (lastindex = ithen) AND
- (index <> ibegin) AND
- (index <> iif) AND
- (index <> ifor) AND
- (index <> irepeat) AND
- (index <> iwhile) AND
- (index <> icase) AND
- (index <> iwith) THEN
- BEGIN
- PopIndent;
- PopKey;
- END;
-
- IF (index = ibegin) OR
- (index = ithen) OR
- (index = ielse) OR
- (index = ido) OR
- (index = irepeat) THEN
- condbreakline;
-
- IF (index = ibegin) THEN
- BEGIN
- IF (is > 0) THEN
- PushIndent (BeginIndent)
- ELSE
- PushIndent (LeftmostBeginIndent);
- PushKey (ibegin);
- END
- ELSE
- IF (index = iif) THEN
- PushIndent (IfIndent)
- ELSE
- IF (index = ithen) THEN
- PushKey (ithen)
- ELSE
- IF (index = ielse) THEN
- BEGIN
- IF (KeyStack [iks] <> icase) THEN
- BEGIN
- PushIndent (ElseIndent);
- PushKey (ielse);
- END
- ELSE
- PushIndent (CaseIndent)
- END
- ELSE
- IF (index = iwhile) THEN
- PushIndent (WhileIndent)
- ELSE
- IF (index = ifor) THEN
- PushIndent (ForIndent)
- ELSE
- IF (index = ido) THEN
- PushKey (ido)
- ELSE
- IF (index = irepeat) THEN
- BEGIN
- PushIndent (RepeatIndent);
- PushKey (irepeat);
- END
- ELSE
- IF (index = iuntil) THEN
- BEGIN
- PushIndent (UntilIndent);
- PushKey (iuntil);
- END
- ELSE
- IF (index = iconst) THEN
- PushIndent (ConstIndent)
- ELSE
- IF (index = itype) THEN
- PushIndent (TypeIndent)
- ELSE
- IF (index = ivar) THEN
- PushIndent (VarIndent)
- ELSE
- IF (index = irecord) THEN
- BEGIN
- PushIndent (col - 6 - IndentationStack [is]);
- PushIndent (RecordIndent);
- PushKey (irecord);
- condbreakline;
- END
- ELSE
- IF (index = iprocedure) THEN
- BEGIN
- PushIndent (ProcedureIndent);
- PushKey (iprocedure);
- END
- ELSE
- IF (index = ifunction) THEN
- PushKey (ifunction)
- ELSE
- IF (index = ilabel) THEN
- PushIndent (LabelIndent)
- ELSE
- IF (index = icase) THEN
- BEGIN
- PushIndent (CaseIndent);
- PushKey (icase);
- END
- ELSE
- IF (index = iof) THEN
- condbreakline
- ELSE
- IF (index = iwith) THEN
- PushIndent (WithIndent);
-
- CurrentIdentifier := '';
- UpCaseIdent := '';
- GOTO start;
- END; (* 'A'..'Z', 'a'..'z', '_' *)
-
-
- '0'..'9' : (* Process decimal integer or real constants *)
- BEGIN
- OutPaddedChar (a^ [ia]);
- INC (ia);
- IF (ia >= nread) THEN
- getblock;
-
- WHILE ( (a^ [ia] >= '0') AND (a^ [ia] <= '9') ) OR
- (a^ [ia] = '.') DO
- BEGIN
- OutLiteralChar (a^ [ia]);
- INC (ia);
- IF (ia >= nread) THEN
- getblock;
- END;
-
- IF (a^ [ia] = 'e') OR (a^ [ia] = 'E') THEN
- BEGIN
- OutLiteralChar ('e');
-
- INC (ia); (* Go to the next character *)
- IF (ia >= nread) THEN
- getblock;
-
- OutLiteralChar (a^ [ia]); (* Output the sign or digit or (?) *)
-
- INC (ia); (* Go to the next character *)
- IF (ia >= nread) THEN
- getblock;
-
- IF ( (lastch >= '0') AND (lastch <= '9') ) OR
- (lastch = '-') OR
- (lastch = '+') THEN
- WHILE ( (a^ [ia] >= '0') AND (a^ [ia] <= '9') ) OR
- (a^ [ia] = '.') DO
- BEGIN
- OutLiteralChar (a^ [ia]);
- INC (ia);
- IF (ia >= nread) THEN
- getblock;
- END;
- END; (* if *)
- GOTO start;
- END; (* '0'..'9' *)
-
-
- '$' : (* Process hexadecimal constants, specific to Turbo Pascal *)
- BEGIN
- OutPaddedChar ('$');
- INC (ia);
- IF (ia >= nread) THEN
- getblock;
- WHILE ( (a^ [ia] >= 'a') AND (a^ [ia] <= 'f') ) OR
- ( (a^ [ia] >= 'A') AND (a^ [ia] <= 'F') ) OR
- ( (a^ [ia] >= '0') AND (a^ [ia] <= '9') ) DO
- BEGIN
- OutLiteralChar (a^ [ia]);
- INC (ia);
- IF (ia >= nread) THEN
- getblock;
- END;
- GOTO start;
- END; (* '$' *)
-
- ELSE
-
- BEGIN
- OutPaddedChar (ch);
- INC (ia);
- IF (ia >= nread) THEN
- getblock;
- GOTO start;
- END;
-
- END; (* CASE ch *)
-
- END.
-