12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415 |
- {$mode objfpc}
- {$h+}
- Unit PtoPu;
- {
- This file is part of the Free Pascal run time library.
- Copyright (c) 1999-2000 by Michael Van Canneyt, member of
- the Free Pascal development team
- Pascal Pretty-Printer object implementation
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- {
- This unit is based heavily on the code by
- Author: Peter Grogono
- This program is based on a Pascal pretty-printer written by Ledgard,
- Hueras, and Singer. See SIGPLAN Notices, Vol. 12, No. 7, July 1977,
- pages 101-105, and PP.DOC/HLP.
- This version of PP developed under Pascal/Z V4.0 or later.
- Very minor modifications for Turbo Pascal made by Willett Kempton
- March 1984 and Oct 84. Runs under 8-bit Turbo or 16-bit Turbo.
- Toad Hall tweak, rewrite for TP 5, 28 Nov 89
- The following was changed :
- - Object oriented
- - Uses streams
- - Run-time customizable.
- }
- { $define debug}
- Interface
- uses Classes,Sysutils;
- Const
- MAXSYMBOLSIZE = 65500;
- MAXSHOWSIZE = 40;
- MAXSTACKSIZE = 100;
- MAXKEYLENGTH = 15; { The longest keywords are IMPLEMENTATION INITIALIZATION }
- DEFLINESIZE = 100;
- DEFINDENT = 2;
-
- TYPE
- Token = AnsiString;
- FileName = STRING;
- TTokenScope = (tsInterface,tsImplementation);
- { Keysymbols }
- { If you add keysyms, adjust the definition of lastkey }
- keysymbol = { keywords }
- (endsym,beginsym,ifsym,thensym,elsesym,procsym,varsym,ofsym,
- whilesym,dosym,casesym,withsym,forsym,repeatsym,untilsym,
- funcsym,labelsym,constsym,typesym,recordsym,stringsym,progsym,
- { TP and Delphi keywords}
- asmsym, trysym, finallysym,exceptsym,raisesym,classsym,objectsym,
- constructorsym,destructorsym,inheritedsym,propertysym,
- privatesym,publicsym,protectedsym,publishedsym,
- initializationsym,finalizationsym,
- inlinesym,librarysym,interfacesym,implementationsym,
- readsym,writesym,unitsym,
- { Not used for formatting }
- andsym,arrsym,divsym,downsym,filesym,gotosym,insym,modsym,
- notsym,nilsym,orsym,setsym,tosym,virtualsym,usessym,
- casevarsym,ofobjectsym,
- { other symbols }
- becomes,notequal,lessorequal,greaterorequal,delphicomment,dopencomment,dclosecomment,opencomment,closecomment,semicolon,colon,equals,
- openparen,closeparen,period,endoffile,othersym);
- { Formatting options }
- { If you add options, adjust the definition of lastopt }
- options = (crsupp,crbefore,blinbefore,
- dindonkey,dindent,spbef,
- spaft,gobsym,inbytab,inbyindent,crafter,upper,lower,capital);
- optionset = SET OF options;
- keysymset = SET OF keysymbol;
- tableentry = RECORD
- selected : optionset;
- dindsym : keysymset;
- terminators : keysymset
- END;
- { Character identification }
- charname = (letter,digit,space,quote,endofline,
- filemark,otherchar);
- charinfo = RECORD
- name : charname;
- Value : CHAR
- END;
- symbol = RECORD
- name : keysymbol;
- Value : Token;
- IsKeyWord : BOOLEAN;
- length, spacesbefore, crsbefore : INTEGER;
- END;
- symbolinfo = ^ symbol;
- stackentry = RECORD
- indentsymbol : keysymbol;
- prevmargin : INTEGER;
- END;
- symbolstack = ARRAY [1..MAXSTACKSIZE] OF stackentry;
- Const FirstOpt = crsupp;
- LastOpt = capital; { Adjust this if you add options }
- FirstKey = endsym;
- LastKey = othersym; { Adjust this if you add options }
- LastFormatsym = usessym;
- Type
- tableptr = ^tableentry;
- optiontable = ARRAY [Ttokenscope,keysymbol] OF tableptr;
- OEntriesTable = Array [keysymbol] OF String[15];
- ONamesTable = Array [Options] of String[15];
- KeywordTable = ARRAY [endsym..lastFormatsym] OF String[MAXKEYLENGTH];
- SpecialChar = ARRAY [1..2] OF CHAR;
- dblcharset = SET OF endsym..othersym;
- DblCharTable = ARRAY [becomes..dclosecomment] OF SpecialChar;
- SglCharTable = ARRAY [opencomment..period] OF CHAR;
-
- TVerboseEvent = Procedure (Sender : TObject; Const Msg : String) of Object;
- { TPrettyPrinter }
- TPrettyPrinter=Class(TObject)
- Private
- FTokenScope: TTokenScope;
- {$ifdef debug}
- GobbleLevel : Integer;
- {$endif debug}
- PreviousSymbol : keysymbol;
- RecordLevel : Integer;
- ClassSeen,ObjectSeen : Boolean;
- LastStruct : KeySymbol;
- CRPending : BOOLEAN;
- currchar,nextchar : charinfo;
- currsym,nextsym : symbolinfo;
- inlines,outlines : INTEGER;
- stack : symbolstack;
- top,startpos,currlinepos,currmargin : Integer;
- option : OptionTable;
- FOnVerbose : TVerboseEvent;
- FirstWordStackPos,
- FirstWordPos,
- FLineSize,
- FIndent : Integer;
- ins,outs,cfgs : TStream;
- Procedure Verbose (Const Msg : String);
- Procedure GetChar;
- Procedure StoreNextChar(Var lngth: INTEGER;
- var Value: Token);
- Procedure SkipBlanks(Out spacesbefore, crsbefore: INTEGER);
- Procedure GetComment(sym: symbolinfo);
- Procedure GetDoubleComment(sym: symbolinfo);
- Procedure GetDelphiComment(sym: symbolinfo);
- Procedure GetNumber(sym: symbolinfo);
- Procedure GetCharLiteral(sym: symbolinfo);
- Function char_Type: keysymbol;
- Procedure GetSpecialChar(sym: symbolinfo);
- Procedure GetNextSymbol(sym: symbolinfo);
- Procedure GetIdentifier(sym: symbolinfo);
- Procedure GetSymbol;
- Procedure PopStack(Out indentsymbol: keysymbol;
- Out prevmargin: INTEGER);
- Procedure PushStack(indentsymbol: keysymbol;
- prevmargin: INTEGER );
- Procedure WriteCRs(numberofcrs: INTEGER);
- Procedure InsertCR;
- Procedure InsertBlankLine;
- Procedure LShiftOn(dindsym: keysymset);
- Procedure LShift;
- Procedure InsertSpace(VAR symbol: symbolinfo);
- Procedure MoveLinePos(newlinepos: INTEGER);
- Procedure PrintSymbol;
- Procedure PPSymbol;
- Procedure Gobble(terminators: keysymset);
- Procedure RShift(currmsym: keysymbol);
- Procedure RShiftIndent(currmsym: keysymbol);
- Function ReadConfigFile: Boolean;
- Public
- Constructor Create;
- Function PrettyPrint : Boolean;
- Property OnVerbose : TVerboseEvent Read FOnVerbose Write FOnVerbose;
- Property LineSize : Integer Read FLineSize Write FLineSize;
- Property Indent : Integer Read FIndent Write FIndent; { How many characters to indent ? }
- Property Source : TStream Read Ins Write Ins;
- Property Dest : TStream Read OutS Write Outs;
- Property Config : Tstream Read cfgS Write cfgs;
- Property CurrentScope : TTokenScope Read FTokenScope Write FTokenScope;
- end;
- Procedure GenerateCfgFile(S: TStream);
- Implementation
- Const
- Blank = ' ';
- VAR
- sets : tableptr;
- dblch : dblcharset;
- CONST
- Keyword : KeywordTable =
- ('END', 'BEGIN', 'IF', 'THEN',
- 'ELSE', 'PROCEDURE', 'VAR', 'OF',
- 'WHILE', 'DO', 'CASE', 'WITH',
- 'FOR', 'REPEAT', 'UNTIL', 'FUNCTION',
- 'LABEL', 'CONST', 'TYPE', 'RECORD',
- 'STRING', 'PROGRAM',
- 'ASM','TRY','FINALLY','EXCEPT','RAISE','CLASS','OBJECT',
- 'CONSTRUCTOR','DESTRUCTOR','INHERITED','PROPERTY',
- 'PRIVATE','PUBLIC','PROTECTED','PUBLISHED',
- 'INITIALIZATION','FINALIZATION',
- 'INLINE','LIBRARY','INTERFACE','IMPLEMENTATION',
- 'READ','WRITE','UNIT',
- {keywords not used for formatting }
- 'AND', 'ARRAY', 'DIV', 'DOWNTO',
- 'FILE', 'GOTO', 'IN', 'MOD',
- 'NOT', 'NIL', 'OR', 'SET','TO','VIRTUAL','USES'
- );
- EntryNames : OEntriesTable =
- ('end','begin','if','then','else','proc','var',
- 'of','while','do','case','with','for','repeat','until',
- 'func','label','const','type','record','string',
- 'prog',
- 'asm','try','finally','except','raise','class','object',
- 'constructor','destructor','inherited','property',
- 'private','public','protected','published',
- 'initialization','finalization',
- 'inline','library','interface','implementation',
- 'read','write','unit',
- 'and','arr','div','down','file','goto',
- 'in','mod','not','nil','or','set','to','virtual','uses',
- 'casevar','ofobject',
- 'becomes','notequal','lessorequal','greaterorequal','delphicomment','dopencomment','dclosecomment',
- 'opencomment','closecomment','semicolon',
- 'colon','equals',
- 'openparen','closeparen','period','endoffile','other');
- OptionNames : ONamesTable =
- ('crsupp','crbefore','blinbefore',
- 'dindonkey','dindent','spbef','spaft',
- 'gobsym','inbytab','inbyindent','crafter','upper',
- 'lower','capital');
- DblChar : DblCharTable =
- ( ':=', '<>', '<=', '>=', '//','(*','*)' );
- SglChar : SglCharTable =
- ('{', '}', ';', ':', '=', '(', ')', '.' );
- { ---------------------------------------------------------------------
- General functions, not part of the object.
- ---------------------------------------------------------------------}
- function upperStr(const s : string) : string;
- var
- i : longint;
- begin
- setLength(upperStr,length(s));
- for i:=1 to length(s) do
- if s[i] in ['a'..'z'] then
- upperStr[i]:=char(byte(s[i])-32)
- else
- upperStr[i]:=s[i];
- end;
- function LowerStr(const s : string) : string;
- var
- i : longint;
- begin
- setLength(LowerStr,length(s));
- for i:=1 to length(s) do
- if s[i] in ['A'..'Z'] then
- LowerStr[i]:=char(byte(s[i])+32)
- else
- LowerStr[i]:=s[i];
- end;
- Function IntToStr(I : LongInt) : String;
- var
- s : string;
- begin
- str(I,s);
- IntToStr := s;
- end;
- Function StrToInt(Const S : String) : Integer;
- Var Code : integer;
- Res : Integer;
- begin
- Val(S, Res, Code);
- StrToInt := Res;
- If Code<>0 then StrToInt:=0;
- end;
- Procedure Strip (Var S : String);
- Const WhiteSpace = [#32,#9,#10,#13];
- Var I,J : Longint;
- begin
- If length(s)=0 then exit;
- I:=1;
- While (S[I] in whitespace) and (I<Length(S)) do inc(i);
- J:=length(S);
- While (S[J] in whitespace) and (J>1) do dec(j);
- If I<=J then
- S:=Copy(S,i,j-i+1)
- else
- S:='';
- end;
- Procedure ClassID(Value: Token;
- lngth: INTEGER;
- VAR idtype: keysymbol;
- VAR IsKeyWord: BOOLEAN);
- { Classify an identifier. We are only interested
- in it if it is a keyword, so we use the hash table. }
- VAR
- Keyvalue: String[MAXKEYLENGTH];
- Sym : keysymbol;
-
- BEGIN
- IF lngth > MAXKEYLENGTH THEN BEGIN
- idtype := othersym;
- IsKeyWord := FALSE
- END
- ELSE
- BEGIN
- IsKeyWord := FALSE;
- KeyValue:= UpperStr(Value);
- sym:=endsym;
- While (Not IsKeyword) and (sym<=lastformatsym) DO
- begin
- iskeyword:=(KeyValue=Keyword[sym]);
- if not iskeyword then
- Sym:=Succ(sym);
- end;
- if IsKeyWord then
- idtype:=sym
- ELSE
- idtype := othersym;
- END
- END; { of ClassID }
- { ---------------------------------------------------------------------
- Functions to create options and set defaults.
- ---------------------------------------------------------------------}
- Procedure CreateOptions (Out Option : OptionTable);
- Var Sym : KeySymbol;
- T : TTokenScope;
- begin
- FOR sym := endsym TO othersym DO
- For T:=Low(TTokenScope) to High(TTokenScope) do
- begin
- NEW(option[T,sym]);
- option[T,sym]^.selected := [];
- option[T,sym]^.dindsym := [];
- option[T,sym]^.terminators := []
- END;
- end;
- Procedure SetTerminators(Var Option : OptionTable);
- Var
- T : TTokenScope;
-
- begin
- For T:=Low(TTokenScope) to High(TTokenScope) do
- begin
- option[t,casesym]^.terminators := [ofsym];
- option[t,casevarsym]^.terminators := [ofsym];
- option[t,forsym]^.terminators := [dosym];
- option[t,whilesym]^.terminators := [dosym];
- option[t,withsym]^.terminators := [dosym];
- option[t,ifsym]^.terminators := [thensym];
- option[t,untilsym]^.terminators := [endsym, untilsym, elsesym, semicolon];
- option[t,becomes]^.terminators := [endsym, untilsym, elsesym, semicolon];
- option[t,openparen]^.terminators := [closeparen];
- option[t,usessym]^.terminators := [semicolon];
- end;
- end;
- Procedure SetDefaultIndents (Var Option : OptionTable);
- Var
- T : TTokenScope;
- begin
- For T:=Low(TTokenScope) to High(TTokenScope) do
- begin
- option[t,recordsym]^.dindsym := [endsym];
- option[t,funcsym]^.dindsym := [labelsym, constsym, typesym, varsym];
- option[t,procsym]^.dindsym := [labelsym, constsym, typesym, varsym];
- option[t,constsym]^.dindsym := [labelsym, constsym, typesym, varsym];
- option[t,typesym]^.dindsym := [labelsym, constsym, typesym, varsym];
- option[t,varsym]^.dindsym := [labelsym, constsym, typesym, varsym];
- option[t,beginsym]^.dindsym := [labelsym, constsym, typesym, varsym];
- option[t,publicsym]^.dindsym := [endsym,protectedsym,privatesym,publicsym,publishedsym];
- option[t,privatesym]^.dindsym := [endsym,protectedsym,privatesym,publicsym,publishedsym];
- option[t,protectedsym]^.dindsym := [endsym,protectedsym,privatesym,publicsym,publishedsym];
- option[t,publishedsym]^.dindsym := [endsym,protectedsym,privatesym,publicsym,publishedsym];
- option[t,finallysym]^.dindsym := [trysym];
- option[t,exceptsym]^.dindsym := [trysym];
- option[t,elsesym]^.dindsym := [ifsym, thensym, elsesym];
- option[t,untilsym]^.dindsym := [ifsym, thensym, elsesym, forsym, whilesym,
- withsym, colon, equals];
- option[t,endsym]^.dindsym := [ifsym, thensym, elsesym, forsym, whilesym,
- withsym, casevarsym, colon, equals, recordsym,
- trysym,classsym,objectsym,protectedsym,privatesym,
- publicsym,publishedsym,finallysym,exceptsym];
- option[t,semicolon]^.dindsym := [ifsym, thensym, elsesym, forsym,
- whilesym, withsym, colon, equals];
- option[t,implementationsym]^.dindsym := [labelsym, varsym, typesym, constsym,
- endsym,propertysym];
- end;
- end;
- Procedure SetDefaults (Var Option : OptionTable);
- { Sets default values for the formatting rules. }
- Var
- T : TTokenScope;
- begin
- For T:=Low(TTokenScope) to High(TTokenScope) do
- begin
- option[t,progsym]^.selected := [capital,blinbefore, spaft];
- option[t,unitsym]^.selected := [capital,blinbefore, spaft];
- option[t,librarysym]^.selected := [capital,blinbefore, spaft];
- option[t,funcsym]^.selected := [capital,blinbefore, dindonkey, spaft];
- option[t,procsym]^.selected := [capital,blinbefore, dindonkey, spaft];
- option[t,labelsym]^.selected := [capital,blinbefore, spaft, inbytab];
- option[t,constsym]^.selected := [capital,blinbefore, dindonkey, spaft, inbytab];
- option[t,typesym]^.selected := [capital,blinbefore, dindonkey, spaft, inbytab];
- option[t,varsym]^.selected := [capital,blinbefore, dindonkey, spaft, inbytab];
- option[t,beginsym]^.selected := [capital,dindonkey, crbefore, crafter, inbytab];
- option[t,repeatsym]^.selected := [capital,inbytab, crafter];
- option[t,recordsym]^.selected := [capital,inbyIndent, crafter];
- option[t,objectsym]^.selected := [capital,inbyIndent];
- option[t,classsym]^.selected := [capital,inbyIndent];
- option[t,publicsym]^.selected := [capital,crbefore, dindonkey, spaft,inbytab];
- option[t,publishedsym]^.selected := [capital,crbefore, dindonkey, spaft,inbytab];
- option[t,protectedsym]^.selected := [capital,crbefore, dindonkey, spaft,inbytab];
- option[t,privatesym]^.selected := [capital,crbefore, dindonkey, spaft,inbytab];
- option[t,trysym]^.Selected := [capital,crbefore,crafter,inbytab];
- option[t,finallysym]^.selected := [capital,crbefore,dindent,crafter,inbytab];
- option[t,exceptsym]^.selected := [capital,crbefore,dindent,crafter,inbytab];
- option[t,casesym]^.selected := [capital,spaft, inbytab, gobsym, crafter];
- option[t,casevarsym]^.selected := [capital,spaft, inbytab, gobsym, crafter];
- option[t,ofsym]^.selected := [capital,crsupp, spbef, spaft];
- option[t,forsym]^.selected := [capital,spaft, inbytab, gobsym, crafter];
- option[t,whilesym]^.selected := [capital,spaft, inbytab, gobsym, crafter];
- option[t,withsym]^.selected := [capital,spaft, inbytab, gobsym, crafter];
- option[t,dosym]^.selected := [capital,crsupp, spbef];
- option[t,ifsym]^.selected := [capital,spaft, inbytab, gobsym];
- option[t,implementationsym]^.selected := [capital,blinbefore,crafter,dindonkey];
- option[t,interfacesym]^.selected := [capital,blinbefore,crafter];
- option[t,usessym]^.selected := [capital,blinbefore,spaft];
- option[t,thensym]^.selected := [capital];
- option[t,elsesym]^.selected := [capital,crbefore, dindonkey, inbytab];
- option[t,endsym]^.selected := [capital,crbefore, crafter,dindonkey,dindent];
- option[t,untilsym]^.selected := [capital,crbefore, dindonkey, dindent, spaft,
- gobsym, crafter];
- option[t,becomes]^.selected := [capital,spbef, spaft, gobsym];
- option[t,Delphicomment]^.Selected := [crafter];
- option[t,opencomment]^.selected := [capital,crsupp];
- option[t,closecomment]^.selected := [capital,crsupp];
- option[t,semicolon]^.selected := [capital,crsupp, dindonkey, crafter];
- option[t,colon]^.selected := [capital,inbytab];
- option[t,equals]^.selected := [capital,spbef, spaft, inbytab];
- option[t,openparen]^.selected := [capital,gobsym];
- option[t,period]^.selected := [capital,crsupp];
- end;
- option[tsInterface,funcsym]^.selected := [capital, dindonkey, spaft];
- option[tsInterface,procsym]^.selected := [capital, dindonkey, spaft];
- end;
- { ---------------------------------------------------------------------
- Stream handling routines
- ---------------------------------------------------------------------}
- Function ReadChar (S : TStream) : Char;
- Var C : Char;
- begin
- repeat
- if S.Position=S.Size then
- C:=#0
- else
- S.Read(C,1);
- Until (C<>#13);
- ReadChar:=C;
- end;
- Function EoSLn (S : TStream) : Char;
- Const WhiteSpace = [' ', #9, #13 ];
- Var C : Char;
- begin
- Repeat
- if S.Position = S.Size then
- C:=#0
- else
- S.Read(C,1);
- Until (Not (C in WhiteSpace)) or ((C=#10));
- EoSln:=C;
- end;
- Function ReadString (S: TStream): String;
- Var
- I : Byte;
- Count : Integer;
-
- begin
- Result:='';
- I:=0;
- Repeat
- If ((I+1)>Length(Result)) then
- SetLength(Result,Length(Result)+255);
- Count:=S.Read(Result[I+1],1);
- If Count>0 then
- Inc(I);
- until (Result[I]=#10) or (Count=0);
- If Result[i]=#10 Then Dec(I);
- If Result[I]=#13 then Dec(I);
- SetLength(Result,I);
- end;
- Procedure WriteString (S : TStream; ST : String);
- begin
- S.Write(St[1],length(St));
- end;
- Procedure WriteAnsiString (S : TStream; ST : AnsiString);
- begin
- S.Write(St[1],length(St));
- end;
- Procedure WriteCR (S: TStream);
- Const
- Newline = System.LineEnding;
- begin
- WriteString(S,Newline);
- end;
- Procedure WriteLnString (S : TStream; ST : String);
- begin
- WriteString(S,ST);
- WriteCR(S);
- end;
- { ---------------------------------------------------------------------
- TPrettyPrinter object
- ---------------------------------------------------------------------}
- Procedure TPrettyPrinter.Verbose (Const Msg : String);
- begin
- If Assigned (FOnVerbose) then
- FOnVerbose(Self,Msg);
- end;
- Procedure TPrettyPrinter.GetChar;
- { Read the next character and classify it }
- VAR Ch: CHAR;
- BEGIN
- currchar := nextchar;
- WITH nextchar DO
- begin
- Ch:=ReadCHar(Ins);
- If Ch=#0 then
- BEGIN
- name := filemark;
- Value := Blank
- END
- ELSE If (Ch=#10) THEN
- BEGIN
- name := endofline;
- Value := Ch;
- Inc(inlines);
- END
- ELSE
- BEGIN
- Value := Ch;
- IF Ch IN ['a'..'z', 'A'..'Z', '_'] THEN name := letter
- ELSE IF Ch IN ['0'..'9'] THEN name := digit
- ELSE IF Ch = '''' THEN name := quote
- ELSE IF Ch in [#13,' ',#9] THEN name := space
- ELSE name := otherchar
- END
- end;
- END; { of GetChar }
- Procedure TPrettyPrinter.StoreNextChar(VAR lngth: INTEGER;
- VAR Value: Token);
- { Store a character in the current symbol }
- BEGIN
- GetChar;
- IF lngth < MAXSYMBOLSIZE THEN BEGIN {XXX - should there be a limit at all?}
- Inc(lngth);
- setlength(Value,lngth);
- Value[lngth] := currchar.Value;
- END;
- END; { of StoreNextChar }
- Procedure TPrettyPrinter.SkipBlanks(out spacesbefore, crsbefore: INTEGER);
- { Count the spaces between symbols }
- BEGIN
- spacesbefore := 0;
- crsbefore := 0;
- WHILE nextchar.name IN [space, endofline] DO BEGIN
- GetChar;
- CASE currchar.name OF
- space: Inc(spacesbefore);
- endofline: BEGIN
- Inc(crsbefore);
- spacesbefore := 0;
- END;
- END; {case}
- END;
- END; { of SkipBlanks }
- Procedure TPrettyPrinter.GetComment(sym: symbolinfo);
- { Process comments using brace notation }
- BEGIN
- sym^.name := opencomment;
- WHILE NOT ((currchar.Value = '}')
- OR (nextchar.name = filemark)) DO
- StoreNextChar(sym^.length, sym^.Value);
- IF currchar.Value = '}' THEN sym^.name := closecomment;
- END; { of GetCommment }
- Procedure TPrettyPrinter.GetDoubleComment(sym: symbolinfo);
- { Process comments using parenthesis notation }
- BEGIN
- sym^.name := dopencomment;
- WHILE NOT (((currchar.Value = '*') AND (nextchar.Value = ')'))
- OR (nextchar.name = filemark)) DO
- StoreNextChar(sym^.length, sym^.Value);
- IF (currchar.Value = '*') AND (nextchar.Value = ')') THEN BEGIN
- StoreNextChar(sym^.length, sym^.Value);
- sym^.name := dclosecomment;
- END;
- END; { of GetDoubleCommment }
- Procedure TPrettyPrinter.GetDelphiComment(sym: symbolinfo);
- { Process comments using either brace or parenthesis notation }
- BEGIN
- sym^.name := Delphicomment;
- WHILE NOT ((nextchar.name = endofline) OR (nextchar.name = filemark)) DO
- StoreNextChar(sym^.length, sym^.Value);
- END; { of GetDelphiCommment }
- Procedure TPrettyPrinter.GetIdentifier(sym: symbolinfo);
- { Read an identifier and classify it }
- BEGIN
- WHILE nextchar.name IN [letter, digit] DO
- StoreNextChar(sym^.length, sym^.Value);
- ClassID(sym^.Value, sym^.length, sym^.name, sym^.IsKeyWord);
- IF sym^.name IN [recordsym, objectsym,classsym, casesym, endsym] THEN
- begin
- if sym^.name=implementationsym then
- FTokenScope:=tsImplementation;
- if sym^.name in [recordsym,objectsym,classsym] then
- LastStruct:=sym^.name;
- CASE sym^.name OF
- RecordSym : Inc(RecordLevel);
- ClassSym : ClassSeen:=True;
- objectsym : begin
- if (PreviousSymbol=Ofsym) then
- sym^.name:=ofobjectsym
- else
- ObjectSeen:=True;
- end;
- casesym : IF (RecordLevel>0) and (LastStruct=recordsym) THEN sym^.name := casevarsym;
- endsym : If (LastStruct=recordsym) then
- Dec(Recordlevel);
- else
- begin
- ClassSeen:=False;
- ObjectSeen:=False;
- end
- END; {case}
- end;
- If (PreviousSymbol=ClassSym) and (sym^.Name=ofsym) then
- ClassSeen:=False;
- PreviousSymbol:=sym^.Name;
- END; { of GetIdentifier }
- { Read a number and store it as a string }
- Procedure TPrettyPrinter.GetNumber(sym: symbolinfo);
- BEGIN
- WHILE nextchar.name = digit DO StoreNextChar(sym^.length, sym^.Value);
- sym^.name := othersym;
- END; { of GetNumber }
- PROCEDURE TPrettyPrinter.GetCharLiteral(sym: symbolinfo);
- { Read a quoted string }
- BEGIN
- WHILE nextchar.name = quote DO BEGIN
- StoreNextChar(sym^.length, sym^.Value);
- WHILE NOT (nextchar.name IN [quote, endofline, filemark]) DO
- StoreNextChar(sym^.length, sym^.Value);
- IF nextchar.name = quote THEN StoreNextChar(sym^.length, sym^.Value);
- END;
- sym^.name := othersym;
- END; { of GetCharLiteral }
- FUNCTION TPrettyPrinter.char_Type: keysymbol;
- { Classify a character pair }
- VAR
- NextTwoChars: SpecialChar;
- Hit: BOOLEAN;
- thischar: keysymbol;
- BEGIN
- NextTwoChars[1] := currchar.Value;
- NextTwoChars[2] := nextchar.Value;
- thischar := becomes;
- Hit := FALSE;
- WHILE NOT (Hit OR (thischar = opencomment)) DO BEGIN
- IF NextTwoChars = DblChar[thischar] THEN Hit := TRUE
- ELSE Inc(thischar);
- END;
- IF NOT Hit THEN BEGIN
- thischar := opencomment;
- WHILE NOT (Hit OR (PRED(thischar) = period)) DO BEGIN
- IF currchar.Value = SglChar[thischar] THEN Hit := TRUE
- ELSE Inc(thischar);
- END;
- END;
- IF Hit THEN char_Type := thischar
- ELSE char_Type := othersym;
- END; { of char_Type }
- Procedure TPrettyPrinter.GetSpecialChar(sym: symbolinfo);
- { Read special characters }
- BEGIN
- StoreNextChar(sym^.length, sym^.Value);
- sym^.name := char_Type;
- IF sym^.name IN dblch THEN StoreNextChar(sym^.length, sym^.Value)
- END; { of GetSpecialChar }
- Procedure TPrettyPrinter.GetNextSymbol(sym: symbolinfo);
- { Read a symbol using the appropriate procedure }
- BEGIN
- CASE nextchar.name OF
- letter: GetIdentifier(sym);
- digit: GetNumber(sym);
- quote: GetCharLiteral(sym);
- otherchar: BEGIN
- GetSpecialChar(sym);
- IF sym^.name = opencomment THEN GetComment(sym)
- else IF sym^.name = dopencomment THEN GetDoubleComment(sym)
- else IF sym^.name= DelphiComment then GetDelphiComment(Sym)
- END;
- filemark: sym^.name := endoffile;
- ELSE {:} {Turbo}
- WRITELN('Unknown character type: ', ORD(nextchar.name));
- END; {case}
- END; { of GetNextSymbol }
- Procedure TprettyPrinter.GetSymbol;
- { Store the next symbol in NEXTSYM }
- VAR
- dummy: symbolinfo;
- BEGIN
- dummy := currsym;
- currsym := nextsym;
- nextsym := dummy;
- SkipBlanks(nextsym^.spacesbefore, nextsym^.crsbefore);
- nextsym^.length := 0;
- nextsym^.IsKeyWord := FALSE;
- IF currsym^.name = opencomment THEN GetComment(nextsym)
- ELSE IF currsym^.name = dopencomment THEN GetDoubleComment(nextsym)
- ELSE GetNextSymbol(nextsym);
- END; {of GetSymbol}
- Procedure TprettyPrinter.PopStack(Out indentsymbol: keysymbol;
- Out prevmargin: INTEGER);
- { Manage stack of indentation symbols and margins }
- BEGIN
- IF top > 0 THEN BEGIN
- indentsymbol := stack[top].indentsymbol;
- prevmargin := stack[top].prevmargin;
- Dec(top);
- END
- ELSE BEGIN
- indentsymbol := othersym;
- prevmargin := 0;
- END;
- END; { of PopStack }
- Procedure TPrettyPrinter.PushStack(indentsymbol: keysymbol;
- prevmargin: INTEGER );
- BEGIN
- Inc(top);
- stack[top].indentsymbol := indentsymbol;
- stack[top].prevmargin := prevmargin;
- END; { of PushStack }
- Procedure TPrettyPrinter.WriteCRs(numberofcrs: INTEGER);
- VAR
- i: INTEGER;
- BEGIN
- IF numberofcrs > 0 THEN BEGIN
- FOR i := 1 TO numberofcrs DO
- WriteCr(OutS);
- Inc(outlines,numberofcrs);
- Currlinepos := 0;
- FirstWordStackPos:=-1;
- END;
- END; { of WriteCRs }
- Procedure TPrettyPrinter.InsertCR;
- BEGIN
- IF currsym^.crsbefore = 0 THEN BEGIN
- WriteCRs(1);
- currsym^.spacesbefore := 0;
- END;
- END; { of InsertCR }
- Procedure TPrettyPrinter.InsertBlankLine;
- BEGIN
- IF currsym^.crsbefore = 0 THEN
- BEGIN
- IF currlinepos = 0 THEN
- WriteCRs(1)
- ELSE
- WriteCRs(2);
- currsym^.spacesbefore := 0;
- END
- ELSE
- IF currsym^.crsbefore = 1 THEN
- IF currlinepos > 0 THEN
- begin
- WriteCRs(1);
- currsym^.spacesbefore := 0;
- end;
- END; { of InsertBlankLine }
- Procedure TPrettyPrinter.LShiftOn(dindsym: keysymset);
- { Move margin left according to stack configuration and current symbol }
- VAR
- indentsymbol: keysymbol;
- prevmargin: INTEGER;
- BEGIN
- {$ifdef debug}
- Write('LShiftOn ',EntryNames[currsym^.name],' : ',FirstWordPos,'/',CurrMargin);
- {$endif debug}
- IF top > 0 THEN BEGIN
- REPEAT
- PopStack(indentsymbol, prevmargin);
- IF indentsymbol IN dindsym THEN currmargin := prevmargin;
- UNTIL NOT (indentsymbol IN dindsym) OR (top = 0);
- IF NOT (indentsymbol IN dindsym) THEN
- PushStack(indentsymbol, prevmargin);
- END;
- {$ifdef debug}
- Writeln('-> ',CurrMargin);
- {$endif debug}
- END; { of LShiftOn }
- Procedure TprettyPrinter.LShift;
- { Move margin left according to stack top }
- VAR
- indentsymbol: keysymbol;
- prevmargin: INTEGER;
- BEGIN
- {$ifdef debug}
- Write('LShift ',EntryNames[currsym^.name],' : ',FirstWordPos,'/',CurrMargin);
- {$endif debug}
- IF top > 0 THEN BEGIN
- PopStack(indentsymbol, prevmargin);
- currmargin := prevmargin;
- (* maybe PopStack(indentsymbol,currmargin); *)
- END;
- {$ifdef debug}
- Writeln('-> ',CurrMargin);
- {$endif debug}
- END; { of LShift }
- Procedure TprettyPrinter.RShift(currmsym: keysymbol);
- { Move right, stacking margin positions }
- BEGIN
- {$ifdef debug}
- Write('RShift ',EntryNames[currmsym],' : ',FirstWordPos,'/',Currmargin);
- {$endif debug}
- IF top < MAXSTACKSIZE THEN PushStack(currmsym, currmargin);
- IF startpos > currmargin THEN currmargin := startpos;
- Inc(currmargin,INDENT);
- {$ifdef debug}
- Writeln(' -> ',Currmargin)
- {$endif debug}
- END; { of RShift }
- Procedure TprettyPrinter.RShiftIndent(currmsym: keysymbol);
- { Move right, stacking margin positions }
- BEGIN
- {$ifdef debug}
- Write('RShiftIndent ',EntryNames[currmsym],' : ',FirstWordPos,'/',Currmargin);
- {$endif debug}
- If (FirstWordStackPos>=0) then
- Top:=FirstWordStackPos
- else
- Top:=0;
- {$ifdef debug}
- If (Top>0) then
- Write(' Stackpos ',Top,' Item: ',EntryNames[Stack[Top].IndentSymbol],' Pos: ',Stack[Top].Prevmargin)
- else
- Write(' no item on stack');
- {$endif debug}
- IF top < MAXSTACKSIZE THEN PushStack(othersym, FirstWordPos);
- // IF top < MAXSTACKSIZE THEN PushStack(currmsym, currmargin);
- CurrMargin:=FirstWordPos+Indent;
- {$ifdef debug}
- Writeln(' -> ',Currmargin)
- {$endif debug}
- END; { of RShift }
- Procedure TPrettyPrinter.InsertSpace(VAR symbol: symbolinfo);
- { Insert space if room on line }
- BEGIN
- IF currlinepos < LineSize THEN BEGIN
- WriteString(OutS, Blank);
- Inc(currlinepos);
- IF (symbol^.crsbefore = 0) AND (symbol^.spacesbefore > 0)
- THEN Dec(symbol^.spacesbefore);
- END;
- END; { of InsertSpace }
- Procedure TPrettyPrinter.MoveLinePos(newlinepos: INTEGER);
- { Insert spaces until correct line position reached }
- VAR i: INTEGER;
- BEGIN
- FOR i := SUCC(currlinepos) TO newlinepos DO
- WriteString(OutS, Blank);
- currlinepos := newlinepos;
- END; { of MoveLinePos }
- Procedure TPrettyPrinter.PrintSymbol;
- BEGIN
- IF (currsym^.IsKeyWord) then
- begin
- If upper in sets^.selected Then
- WriteString (OutS,UpperStr(currsym^.value))
- else if lower in sets^.selected then
- WriteString (OutS,LowerStr(currsym^.value))
- else if capital in sets^.selected then
- begin
- WriteString(OutS,UpCase(CurrSym^.Value[1]));
- WriteString(OutS,LowerStr(Copy(CurrSym^.Value,2,MAXSYMBOLSIZE)));{XXX - ?should it be length?}
- end
- else
- WriteString(OutS,Currsym^.Value);
- end
- ELSE
- WriteAnsiString(OutS, currsym^.Value);
- startpos := currlinepos;
- Inc(currlinepos,currsym^.length);
- if (FirstWordStackPos=-1) then
- begin
- FirstWordPos:=startpos;
- FirstWordStackPos:=Top;
- {$ifdef debug}
- write('First word : ',currlinepos,': ',currsym^.value);
- If (FirstWordStackPos>0) then
- writeln(' [Stack: ',FirstWordStackPos,' Item: "',EntryNames[Stack[FirstWordStackPos].IndentSymbol],'" Pos: ',Stack[FirstWordStackPos].Prevmargin,']')
- else
- Writeln(' No stack')
- {$endif debug}
- end;
- END; { of PrintSymbol }
- Procedure TPrettyPrinter.PPSymbol;
- { Find position for symbol and then print it }
- VAR newlinepos: INTEGER;
- BEGIN
- WriteCRs(currsym^.crsbefore);
- IF ((currLinePos<>0) and (currlinepos + currsym^.spacesbefore > currmargin)) OR
- (currsym^.name IN [opencomment, closecomment,dopencomment, dclosecomment])
- THEN
- newlinepos := currlinepos + currsym^.spacesbefore
- ELSE
- newlinepos := currmargin;
- IF newlinepos + currsym^.length > LINESIZE THEN
- BEGIN {XXX - this needs to be cleaned for case of long symbol values}
- WriteCRs(1);
- IF currmargin + currsym^.length <= LINESIZE THEN
- newlinepos := currmargin
- ELSE IF currsym^.length < LINESIZE THEN
- newlinepos := LINESIZE - currsym^.length
- ELSE
- newlinepos := 0;
- END;
- MoveLinePos(newlinepos);
- PrintSymbol;
- END; { of PPSymbol }
- Procedure TPrettyPrinter.Gobble(terminators: keysymset);
- { Print symbols which follow a formatting symbol but which do not
- affect layout }
- BEGIN
- {$ifdef debug}
- Inc(GobbleLevel);
- Writeln('Gobble start ',GobbleLevel,' : ',EntryNames[currsym^.name]);
- {$endif debug}
- IF top < MAXSTACKSIZE THEN PushStack(currsym^.name, currmargin);
- currmargin := currlinepos;
- WHILE NOT ((nextsym^.name IN terminators)
- OR (nextsym^.name = endoffile)) DO BEGIN
- GetSymbol;
- PPSymbol;
- END;
- LShift;
- {$ifdef debug}
- Writeln('Gobble end ',gobblelevel,' : ',EntryNames[nextsym^.name],' ',nextsym^.name in terminators );
- Dec(GobbleLevel);
- {$endif debug}
- END; { of Gobble }
- Function TPrettyPrinter.ReadConfigFile : Boolean;
- Type
- TLineType = (ltNormal,ltIndent,ltGobble);
- Var
- I,J : Longint;
- Procedure SetOption(TheKey : KeySymbol;Var OptionList : String);
- Var TheOpt : Options;
- Found : Boolean;
- K : longint;
- opt : string;
- TS : TTokenScope;
- begin
- Repeat
- K:=pos(',',optionlist);
- If k>0 then
- begin
- opt:=Copy(OptionList,1,k-1);
- strip(opt);
- Delete(OptionList,1,k);
- end
- else
- opt:=OptionList;
- If Length(Opt)>0 then
- begin
- Found:=False;
- for TheOpt :=firstopt to lastopt do
- begin
- found:=opt=OptionNames[Theopt];
- If found then break;
- end;
- If not found then
- Verbose ('Unknown option on line '+inttostr(i)+': '+Opt)
- else
- For TS:=Low(TTokenScope) to High(TTokenScope) do
- Option[TS,TheKey]^.Selected:=Option[TS,TheKey]^.Selected+[TheOpt];
- end;
- until k=0;
- end;
- Function GetKeySimList(Const aType : String; Var OptionList : String) : keysymset;
- Var
- TheIndent : Keysymbol;
- Found : Boolean;
- K : longint;
- opt : string;
- begin
- Result:=[];
- Repeat
- K:=pos(',',optionlist);
- If k>0 then
- begin
- opt:=Copy(OptionList,1,k-1);
- strip(opt);
- Delete(OptionList,1,k);
- end
- else
- opt:=OptionList;
- If Length(Opt)>0 then
- begin
- Found:=False;
- for TheIndent :=firstKey to lastKey do
- begin
- found:=opt=EntryNames[Theindent];
- If found then break;
- end;
- If not found then
- begin
- Verbose ('Unknown indent '+aType+' on line '+inttostr(i)+': '+Opt);
- exit;
- end;
- Include(Result,Theindent);
- end;
- until k=0;
- end;
- Procedure SetIndent(TheKey : KeySymbol; Var OptionList : String);
- Var
- TS : TTokenScope;
- Syms : KeySymSet;
- begin
- Syms:=GetKeySimList('indent',OptionList);
- For TS:=Low(TTokenScope) to High(TTokenScope) do
- With Option[TS,TheKey]^ do
- dindsym:=dindsym+Syms;
- end;
- Procedure SetGobble(TheKey : KeySymbol; Var OptionList : String);
- Var
- TS : TTokenScope;
- Syms : KeySymSet;
- begin
- Syms:=GetKeySimList('gobble',OptionList);
- For TS:=Low(TTokenScope) to High(TTokenScope) do
- With Option[TS,TheKey]^ do
- Terminators:=Terminators+Syms;
- end;
- Function CheckLineType (var Name : String) : TLineType;
- begin
- If (Name[1]='[') and (Name[Length(Name)]=']') then
- begin
- Name:=Copy(Name,2,Length(Name)-2);
- Result:=ltIndent
- end
- else If (Name[1]='<') and (Name[Length(Name)]='>') then
- begin
- Name:=Copy(Name,2,Length(Name)-2);
- Result:=ltgobble
- end
- else
- Result:=ltNormal;
- end;
- Var
- TheKey : KeySymbol;
- Found : Boolean;
- Line, Name : String;
- L : TStringList;
- LT : TLineType;
-
- begin
- ReadConfigFile:=false;
- L:=TStringList.Create;
- Try
- L.LoadFromStream(CfgS);
- For I:=1 to L.Count do
- begin
- Line:=L[i-1];
- { Strip comment }
- If pos('#',Line)<>0 then
- Line:=Copy(Line,1,Pos('#',Line)-1);
- If length(Line)<>0 then
- begin
- J:=Pos('=',Line);
- If J=0 then
- verbose ('Error in config file on line '+IntToStr(i))
- else
- begin
- Line:=LowerStr(Line);
- Name:=Copy(Line,1,j-1);
- Delete(Line,1,J);
- { indents or options ? }
- LT:=CheckLineType(Name);
- Strip(Name);
- found:=false;
- for thekey:=firstkey to lastkey do
- begin
- found:=Name=EntryNames[thekey];
- If Found then break;
- end;
- If not found then
- Verbose ('Unknown keyword on line '+inttostr(i)+': '+Name)
- else
- Case LT of
- ltIndent: SetIndent(TheKey,Line);
- ltNormal: SetOption(TheKey,Line);
- ltGobble: SetGobble(TheKey,Line);
- end;
- end;
- end;
- end;
- Finally
- L.Free;
- end;
- Verbose ('Processed configfile: read '+IntToStr(I)+' lines');
- ReadConfigFile:=true;
- end;
- Procedure GenerateCfgFile(S : TStream);
- Var TheKey,TheIndent : KeySymbol;
- TheOpt : Options;
- Written : Boolean;
- Option : OptionTable;
- begin
- CreateOptions(option);
- SetDefaults(option);
- SetDefaultIndents(option);
- For TheKey:=Firstkey to lastkey do
- begin
- { Write options }
- WriteString (S,EntryNames[TheKey]+'=');
- Written:=False;
- for TheOpt:=FirstOpt to LastOpt do
- If TheOpt in Option[tsInterface,TheKey]^.Selected then
- begin
- if written then
- WriteString (S,',')
- else
- Written:=True;
- writeString (S,OptionNames[TheOpt]);
- end;
- WriteCr (S);
- { Write de-indent keysyms, if any }
- If Option[tsInterface,TheKey]^.dindsym<>[] then
- begin
- WriteString (S,'['+EntryNames[TheKey]+']=');
- Written:=False;
- For TheIndent:=FirstKey to lastkey do
- If TheIndent in Option[tsInterface,TheKey]^.dindsym then
- begin
- if written then
- WriteString (S,',')
- else
- Written:=True;
- WriteString (S,EntryNames[Theindent]);
- end;
- WriteCr (S);
- end;
- end;
- end;
- Function trimMiddle ( a:ansistring; lnght: integer; size: integer):string;
- var
- half:Integer;
- begin
- if lnght > size
- then
- begin
- half := (size - 3) div 2;
- trimMiddle := copy(a,1,half) + '...' + copy(a,lnght-half+1,half);
- end
- else
- trimMiddle := a;
- end;
- Function TPrettyPrinter.PrettyPrint : Boolean;
- Begin
- PrettyPrint:=False;
- If Not Assigned(Ins) or Not Assigned(OutS) then
- exit;
- If Not Assigned(CfgS) then
- begin
- SetDefaults(Option);
- SetDefaultIndents(Option);
- end
- else
- ReadConfigFile;
- { Initialize variables }
- top := 0;
- currlinepos := 0;
- currmargin := 0;
- inlines := 0;
- outlines := 0;
- CrPending := FALSE;
- FirstWordStackPos:=-1;
- RecordLevel := 0;
- GetChar;
- NEW(currsym);
- NEW(nextsym);
- GetSymbol;
- WHILE nextsym^.name <> endoffile DO BEGIN
- GetSymbol;
- {$ifdef debug}
- Writeln('line in-'+IntToStr(inlines)+' out-'+IntToStr(outlines)+
- ' symbol "'+EntryNames[currsym^.name]+'" = "'+
- trimMiddle(currsym^.value,length(currsym^.value),MAXSHOWSIZE)+'"');
- {$endif debug}
- sets := option[FTokenScope,currsym^.name];
- IF (CrPending AND NOT (crsupp IN sets^.selected))
- OR (crbefore IN sets^.selected) THEN BEGIN
- InsertCR;
- CrPending := FALSE
- END;
- IF blinbefore IN sets^.selected THEN BEGIN
- InsertBlankLine;
- CrPending := FALSE
- END;
- IF dindonkey IN sets^.selected THEN
- LShiftOn(sets^.dindsym);
- IF dindent IN sets^.selected THEN
- LShift;
- IF spbef IN sets^.selected THEN InsertSpace(currsym);
- PPSymbol;
- IF spaft IN sets^.selected THEN InsertSpace(nextsym);
- IF inbytab IN sets^.selected THEN
- RShift(currsym^.name)
- else IF inbyindent IN sets^.selected THEN
- RShiftIndent(currsym^.name);
- IF gobsym IN sets^.selected THEN Gobble(sets^.terminators);
- IF crafter IN sets^.selected THEN CrPending := TRUE
- END;
- IF CrPending THEN WriteCRs(1);
- Verbose(IntToStr(inlines)+' lines read, '+IntToStr(outlines)+' lines written.');
- PrettyPrint:=True;
- end;
- Constructor TPrettyPrinter.Create;
- Begin
- Indent:=DefIndent;
- LineSize:=DefLineSize;
- CreateOptions (Option);
- SetTerminators(Option);
- InS:=Nil;
- OutS:=Nil;
- CfgS:=Nil;
- End;
- { ---------------------------------------------------------------------
- Unit initialization
- ---------------------------------------------------------------------}
- Begin
- dblch := [becomes, notequal, lessorequal, greaterorequal, opencomment];
- end.
|