tcscanner.pas 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220
  1. unit tcscanner;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, typinfo, fpcunit, testregistry, pscanner;
  6. type
  7. { TTestTokenFinder }
  8. TTestTokenFinder = class(TTestCase)
  9. Published
  10. Procedure TestFind;
  11. end;
  12. { TTestStreamLineReader }
  13. TTestStreamLineReader = class(TTestCase)
  14. Private
  15. FReader: TStreamLineReader;
  16. Protected
  17. procedure NewSource(Const Source : string);
  18. Procedure TestLine(Const ALine : String; ExpectEOF : Boolean = True);
  19. procedure TearDown; override;
  20. Published
  21. Procedure TestCreate;
  22. Procedure TestEOF;
  23. Procedure TestEmptyLine;
  24. Procedure TestEmptyLineCR;
  25. Procedure TestEmptyLineLF;
  26. Procedure TestEmptyLineCRLF;
  27. Procedure TestEmptyLineLFCR;
  28. Procedure TestOneLine;
  29. Procedure TestTwoLines;
  30. end;
  31. { TTestingPascalScanner }
  32. TTestingPascalScanner = Class(TPascalScanner)
  33. private
  34. FDoSpecial: Boolean;
  35. protected
  36. function HandleMacro(AIndex: integer): TToken;override;
  37. Public
  38. Property DoSpecial : Boolean Read FDoSpecial Write FDoSpecial;
  39. end;
  40. { TTestScanner }
  41. TTestScanner= class(TTestCase)
  42. Private
  43. FLI: String;
  44. FLibAlias: String;
  45. FLibName: String;
  46. FLibOptions: String;
  47. FLinkLibHandled: Boolean;
  48. FScanner : TPascalScanner;
  49. FResolver : TStreamResolver;
  50. FDoCommentCalled : Boolean;
  51. FComment: string;
  52. FPathPrefix : String;
  53. FTestTokenString: String;
  54. protected
  55. procedure DoComment(Sender: TObject; aComment: String);
  56. procedure DoLinkLib(Sender: TObject; const aLibName,aAlias,aOptions : String; var aHandled : Boolean);
  57. procedure SetUp; override;
  58. procedure TearDown; override;
  59. Procedure DoMultilineError;
  60. Function TokenToString(tk : TToken) : string;
  61. Procedure AssertEquals(Msg : String; Expected,Actual : TToken); overload;
  62. Procedure AssertEquals(Msg : String; Expected,Actual : TModeSwitch); overload;
  63. Procedure AssertEquals(Msg : String; Expected,Actual : TModeSwitches); overload;
  64. // creates a virtual source file with name 'afile.pp', prepended with PathPrefix
  65. procedure NewSource(Const Source : string; DoClear : Boolean = True);
  66. Procedure DoTestToken(t : TToken; Const ASource : String; Const CheckEOF : Boolean = True);
  67. Procedure TestToken(t : TToken; Const ASource : String; Const CheckEOF : Boolean = True);
  68. Procedure TestTokens(t : array of TToken; Const ASource : String; Const CheckEOF : Boolean = True;Const DoClear : Boolean = True);
  69. Property LastIDentifier : String Read FLI Write FLi;
  70. Property Scanner : TPascalScanner Read FScanner;
  71. // Path for source filename.
  72. Property PathPrefix : String Read FPathPrefix Write FPathPrefix;
  73. Property TestTokenString : String Read FTestTokenString;
  74. // Results from DoLinkLib;
  75. Property LibName : String Read FLibName;
  76. Property LibAlias : String Read FLibAlias;
  77. Property LibOptions : String read FLibOptions;
  78. // Will be returned in aHandled in DoLinkLib
  79. Property LinkLibHandled : Boolean Read FLinkLibHandled Write FLinkLibHandled;
  80. published
  81. Procedure TestEmpty;
  82. procedure TestEOF;
  83. procedure TestWhitespace;
  84. procedure TestComment1;
  85. procedure TestComment2;
  86. procedure TestComment3;
  87. procedure TestComment4;
  88. procedure TestComment5;
  89. procedure TestComment6;
  90. procedure TestComment7;
  91. procedure TestComment8;
  92. procedure TestComment9;
  93. procedure TestNestedComment1;
  94. procedure TestNestedComment2;
  95. procedure TestNestedComment3;
  96. procedure TestNestedComment4;
  97. procedure TestNestedComment5;
  98. procedure TestonComment;
  99. procedure TestIdentifier;
  100. procedure TestSelf;
  101. procedure TestSelfNoToken;
  102. procedure TestString;
  103. procedure TestMultilineStringError;
  104. procedure TestMultilineStringSource;
  105. Procedure TestMultilineStringLF;
  106. Procedure TestMultilineStringCR;
  107. Procedure TestMultilineStringCRLF;
  108. Procedure TestMultilineStringPlatform;
  109. Procedure TestMultilineLineEndingDirective;
  110. Procedure TestMultilineTrimLeftDirective;
  111. procedure TestMultilineStringTrimAll;
  112. procedure TestMultilineStringTrimAuto;
  113. procedure TestMultilineStringTrim2;
  114. procedure TestNumber;
  115. procedure TestChar;
  116. procedure TestCharString;
  117. procedure TestCaretString;
  118. procedure TestBraceOpen;
  119. procedure TestBraceClose;
  120. procedure TestMul;
  121. procedure TestPlus;
  122. procedure TestComma;
  123. procedure TestMinus;
  124. procedure TestDot;
  125. procedure TestDivision;
  126. procedure TestColon;
  127. procedure TestSemicolon;
  128. procedure TestLessThan;
  129. procedure TestEqual;
  130. procedure TestGreaterThan;
  131. procedure TestAt;
  132. procedure TestSquaredBraceOpen;
  133. procedure TestSquaredBraceClose;
  134. procedure TestCaret;
  135. procedure TestBackslash;
  136. procedure TestDotDot;
  137. procedure TestAssign;
  138. procedure TestAssignPlus;
  139. procedure TestAssignMinus;
  140. procedure TestAssignMul;
  141. procedure TestAssignDivision;
  142. procedure TestNotEqual;
  143. procedure TestLessEqualThan;
  144. procedure TestGreaterEqualThan;
  145. procedure TestPower;
  146. procedure TestSymmetricalDifference;
  147. procedure TestAbsolute;
  148. procedure TestAnd;
  149. procedure TestArray;
  150. procedure TestAs;
  151. procedure TestAsm;
  152. procedure TestBegin;
  153. procedure TestBitpacked;
  154. procedure TestCase;
  155. procedure TestClass;
  156. procedure TestConst;
  157. procedure TestConstructor;
  158. procedure TestDestructor;
  159. procedure TestDispinterface;
  160. procedure TestDiv;
  161. procedure TestDo;
  162. procedure TestDownto;
  163. procedure TestElse;
  164. procedure TestEnd;
  165. procedure TestExcept;
  166. procedure TestExports;
  167. procedure TestFalse;
  168. procedure TestFile;
  169. procedure TestFinalization;
  170. procedure TestFinally;
  171. procedure TestFor;
  172. procedure TestFunction;
  173. procedure TestGeneric;
  174. procedure TestGoto;
  175. Procedure TestHelper;
  176. procedure TestIf;
  177. procedure TestImplementation;
  178. procedure TestIn;
  179. procedure TestInherited;
  180. procedure TestInitialization;
  181. procedure TestInline;
  182. procedure TestInterface;
  183. procedure TestIs;
  184. procedure TestLabel;
  185. procedure TestLibrary;
  186. procedure TestMod;
  187. procedure TestNil;
  188. procedure TestNot;
  189. procedure TestObject;
  190. procedure TestOf;
  191. procedure TestOn;
  192. procedure TestOperator;
  193. procedure TestOr;
  194. procedure TestPacked;
  195. procedure TestProcedure;
  196. procedure TestProgram;
  197. procedure TestProperty;
  198. procedure TestRaise;
  199. procedure TestRecord;
  200. procedure TestRepeat;
  201. procedure TestResourceString;
  202. procedure TestSet;
  203. procedure TestShl;
  204. procedure TestShr;
  205. procedure TestShlC;
  206. procedure TestShrC;
  207. procedure TestSpecialize;
  208. procedure TestThen;
  209. procedure TestThreadvar;
  210. procedure TestTo;
  211. procedure TestTrue;
  212. procedure TestTry;
  213. procedure TestType;
  214. procedure TestUnit;
  215. procedure TestUntil;
  216. procedure TestUses;
  217. procedure TestVar;
  218. procedure TestWhile;
  219. procedure TestWith;
  220. procedure TestXor;
  221. procedure TestLineEnding;
  222. procedure TestObjCClass;
  223. procedure TestObjCClass2;
  224. procedure TestObjCProtocol;
  225. procedure TestObjCProtocol2;
  226. procedure TestObjCCategory;
  227. procedure TestObjCCategory2;
  228. procedure TestTab;
  229. Procedure TestEscapedKeyWord;
  230. Procedure TestTokenSeries;
  231. Procedure TestTokenSeriesNoWhiteSpace;
  232. Procedure TestTokenSeriesComments;
  233. Procedure TestTokenSeriesNoComments;
  234. Procedure TestDefine0;
  235. procedure TestDefine0Spaces;
  236. procedure TestDefine0Spaces2;
  237. procedure TestDefine01;
  238. Procedure TestDefine1;
  239. Procedure TestDefine2;
  240. Procedure TestDefine21;
  241. procedure TestDefine22;
  242. Procedure TestDefine3;
  243. Procedure TestDefine4;
  244. Procedure TestDefine5;
  245. Procedure TestDefine6;
  246. Procedure TestDefine7;
  247. Procedure TestDefine8;
  248. Procedure TestDefine9;
  249. Procedure TestDefine10;
  250. Procedure TestDefine11;
  251. Procedure TestDefine12;
  252. Procedure TestDefine13;
  253. Procedure TestDefine14;
  254. Procedure TestInclude;
  255. Procedure TestInclude2;
  256. Procedure TestInclude3;
  257. Procedure TestIncludeString;
  258. Procedure TestIncludeStringFile;
  259. Procedure TestIncludeString2Lines;
  260. Procedure TestUnDefine1;
  261. Procedure TestMacro1;
  262. procedure TestMacro2;
  263. procedure TestMacro3;
  264. procedure TestMacroHandling;
  265. procedure TestIFDefined;
  266. procedure TestIFUnDefined;
  267. procedure TestIFAnd;
  268. procedure TestIFAndShortEval;
  269. procedure TestIFOr;
  270. procedure TestIFOrShortEval;
  271. procedure TestIFXor;
  272. procedure TestIFAndOr;
  273. procedure TestIFEqual;
  274. procedure TestIFNotEqual;
  275. procedure TestIFGreaterThan;
  276. procedure TestIFGreaterEqualThan;
  277. procedure TestIFLesserThan;
  278. procedure TestIFLesserEqualThan;
  279. procedure TestIFDefinedElseIf;
  280. procedure TestIfError;
  281. procedure TestIFCDefined;
  282. procedure TestIFCNotDefined;
  283. procedure TestIFCAndDefined;
  284. procedure TestIFCFalse;
  285. Procedure TestModeSwitch;
  286. Procedure TestOperatorIdentifier;
  287. Procedure TestUTF8BOM;
  288. Procedure TestBooleanSwitch;
  289. Procedure TestLinkLibSimple;
  290. Procedure TestLinkLibAlias;
  291. Procedure TestLinkLibDefaultAlias;
  292. Procedure TestLinkLibDefaultAliasStrip;
  293. Procedure TestLinkLibOptions;
  294. end;
  295. implementation
  296. { TTestingPascalScanner }
  297. function TTestingPascalScanner.HandleMacro(AIndex: integer): TToken;
  298. begin
  299. if DoSpecial then
  300. begin
  301. Result:=tkIdentifier;
  302. SetCurTokenstring('somethingweird');
  303. end
  304. else
  305. Result:=inherited HandleMacro(AIndex);
  306. end;
  307. { TTestTokenFinder }
  308. procedure TTestTokenFinder.TestFind;
  309. Var
  310. tk,tkr : TToken;
  311. S : string;
  312. B : Boolean;
  313. begin
  314. For tk:=tkAbsolute to tkXor do
  315. begin
  316. S:=tokenInfos[tk];
  317. B:=IsNamedToken(S,tkr);
  318. AssertEquals('Token '+S+' is a token',true,B);
  319. AssertEquals('Token '+S+' returns correct token',Ord(tk),Ord(tkr));
  320. end;
  321. end;
  322. { TTestStreamLineReader }
  323. procedure TTestStreamLineReader.NewSource(Const Source: string);
  324. begin
  325. FReader:=TStringStreamLineReader.Create('afile',Source);
  326. end;
  327. procedure TTestStreamLineReader.TestLine(const ALine: String; ExpectEOF: Boolean);
  328. begin
  329. AssertNotNull('Have reader',FReader);
  330. AssertEquals('Reading source line',ALine,FReader.ReadLine);
  331. if ExpectEOF then
  332. AssertEquals('End of file reached',True,FReader.IsEOF);
  333. end;
  334. procedure TTestStreamLineReader.TearDown;
  335. begin
  336. inherited TearDown;
  337. If Assigned(FReader) then
  338. FreeAndNil(Freader);
  339. end;
  340. procedure TTestStreamLineReader.TestCreate;
  341. begin
  342. FReader:=TStreamLineReader.Create('afile');
  343. AssertEquals('Correct filename','afile',FReader.FileName);
  344. AssertEquals('Initially empty',True,FReader.isEOF);
  345. end;
  346. procedure TTestStreamLineReader.TestEOF;
  347. begin
  348. NewSource('');
  349. AssertEquals('Empty stream',True,FReader.IsEOF);
  350. end;
  351. procedure TTestStreamLineReader.TestEmptyLine;
  352. begin
  353. NewSource('');
  354. TestLine('');
  355. end;
  356. procedure TTestStreamLineReader.TestEmptyLineCR;
  357. begin
  358. NewSource(#13);
  359. TestLine('');
  360. end;
  361. procedure TTestStreamLineReader.TestEmptyLineLF;
  362. begin
  363. NewSource(#10);
  364. TestLine('');
  365. end;
  366. procedure TTestStreamLineReader.TestEmptyLineCRLF;
  367. begin
  368. NewSource(#13#10);
  369. TestLine('');
  370. end;
  371. procedure TTestStreamLineReader.TestEmptyLineLFCR;
  372. begin
  373. NewSource(#10#13);
  374. TestLine('',False);
  375. TestLine('');
  376. end;
  377. procedure TTestStreamLineReader.TestOneLine;
  378. Const
  379. S = 'a line with text';
  380. begin
  381. NewSource(S);
  382. TestLine(S);
  383. end;
  384. procedure TTestStreamLineReader.TestTwoLines;
  385. Const
  386. S = 'a line with text';
  387. begin
  388. NewSource(S+sLineBreak+S);
  389. TestLine(S,False);
  390. TestLine(S);
  391. end;
  392. { ---------------------------------------------------------------------
  393. TTestScanner
  394. ---------------------------------------------------------------------}
  395. procedure TTestScanner.DoComment(Sender: TObject; aComment: String);
  396. begin
  397. FDoCommentCalled:=True;
  398. FComment:=aComment;
  399. end;
  400. procedure TTestScanner.DoLinkLib(Sender: TObject; const aLibName, aAlias, aOptions: String; var aHandled: Boolean);
  401. begin
  402. FLibName:=aLibName;
  403. FLibAlias:=aAlias;
  404. FLibOptions:=aOptions;
  405. aHandled:=FLinkLibHandled;
  406. end;
  407. procedure TTestScanner.SetUp;
  408. begin
  409. FTestTokenString:='';
  410. FLibAlias:='';
  411. FLibName:='';
  412. FLibOptions:='';
  413. FLinkLibHandled:=False;
  414. FDoCommentCalled:=False;
  415. FResolver:=TStreamResolver.Create;
  416. FResolver.OwnsStreams:=True;
  417. FScanner:=TTestingPascalScanner.Create(FResolver);
  418. // Do nothing
  419. end;
  420. procedure TTestScanner.TearDown;
  421. begin
  422. FreeAndNil(FScanner);
  423. FreeAndNil(FResolver);
  424. end;
  425. procedure TTestScanner.DoMultilineError;
  426. begin
  427. TestToken(pscanner.tkString,'`A '#10'multiline string`');
  428. end;
  429. function TTestScanner.TokenToString(tk: TToken): string;
  430. begin
  431. Result:=GetEnumName(TypeInfo(TToken),Ord(tk));
  432. end;
  433. procedure TTestScanner.AssertEquals(Msg: String; Expected, Actual: TToken);
  434. begin
  435. AssertEquals(Msg,TokenToString(Expected),TokenToString(Actual));
  436. end;
  437. procedure TTestScanner.AssertEquals(Msg: String; Expected, Actual: TModeSwitch);
  438. begin
  439. AssertEquals(Msg,GetEnumName(TypeInfo(TModeSwitch),Ord(Expected)),
  440. GetEnumName(TypeInfo(TModeSwitch),Ord(Actual)))
  441. end;
  442. procedure TTestScanner.AssertEquals(Msg: String; Expected, Actual: TModeSwitches);
  443. Function ToString(S : TModeSwitches) : String;
  444. Var
  445. M : TModeSwitch;
  446. begin
  447. Result:='';
  448. For M in TModeswitch do
  449. if M in S then
  450. begin
  451. If (Result<>'') then
  452. Result:=Result+', ';
  453. Result:=Result+GetEnumName(TypeInfo(TModeSwitch), Ord(M));
  454. end;
  455. end;
  456. begin
  457. AssertEquals(Msg,ToString(Expected),ToString(Actual));
  458. end;
  459. procedure TTestScanner.NewSource(const Source: string; DoClear : Boolean = True);
  460. Var
  461. aFile : String;
  462. begin
  463. aFile:='';
  464. if DoClear then
  465. FResolver.Clear;
  466. if (FPathPrefix<>'') then
  467. aFile:=IncludeTrailingPathDelimiter(FPathPrefix);
  468. aFile:=aFile+'afile.pp';
  469. FResolver.AddStream(aFile,TStringStream.Create(Source));
  470. {$ifndef NOCONSOLE} // JC: To get the tests to run with GUI
  471. Writeln('// '+TestName);
  472. Writeln(Source);
  473. {$EndIf}
  474. // FreeAndNil(FScanner);
  475. // FScanner:=TTestingPascalScanner.Create(FResolver);
  476. FScanner.OpenFile(aFile);
  477. end;
  478. procedure TTestScanner.DoTestToken(t: TToken; const ASource: String;
  479. const CheckEOF: Boolean);
  480. Var
  481. tk : ttoken;
  482. begin
  483. NewSource(ASource);
  484. tk:=FScanner.FetchToken;
  485. AssertEquals('Read token equals expected token.',t,tk);
  486. FTestTokenString:=FScanner.CurTokenString;
  487. if CheckEOF then
  488. begin
  489. tk:=FScanner.FetchToken;
  490. if (tk=tkLineEnding) and not (t in [tkEOF,tkLineEnding]) then
  491. tk:=FScanner.FetchToken;
  492. AssertEquals('EOF reached.',tkEOF,FScanner.FetchToken);
  493. end;
  494. end;
  495. procedure TTestScanner.TestToken(t: TToken; const ASource: String;
  496. const CheckEOF: Boolean);
  497. Var
  498. S : String;
  499. begin
  500. DoTestToken(t,ASource);
  501. if (ASource<>'') then
  502. begin
  503. S:=ASource;
  504. S[1]:=Upcase(S[1]);
  505. DoTestToken(t,S);
  506. end;
  507. DoTestToken(t,UpperCase(ASource));
  508. DoTestToken(t,LowerCase(ASource),CheckEOF);
  509. end;
  510. procedure TTestScanner.TestTokens(t: array of TToken; const ASource: String;
  511. const CheckEOF: Boolean; const DoClear: Boolean);
  512. Var
  513. tk : ttoken;
  514. i : integer;
  515. begin
  516. NewSource(ASource,DoClear);
  517. For I:=Low(t) to High(t) do
  518. begin
  519. tk:=FScanner.FetchToken;
  520. AssertEquals(Format('Read token %d equals expected token.',[i]),t[i],tk);
  521. if tk=tkIdentifier then
  522. LastIdentifier:=FScanner.CurtokenString
  523. else if tk=tkString then
  524. fTestTokenString:=FScanner.CurTokenString;
  525. end;
  526. if CheckEOF then
  527. begin
  528. tk:=FScanner.FetchToken;
  529. if (tk=tkLineEnding) then
  530. tk:=FScanner.FetchToken;
  531. AssertEquals('EOF reached.',tkEOF,FScanner.FetchToken);
  532. end;
  533. end;
  534. procedure TTestScanner.TestEmpty;
  535. begin
  536. AssertNotNull('Have Scanner',Scanner);
  537. AssertTrue('Options is empty',[]=Scanner.Options);
  538. AssertEquals('FPC modes is default',FPCModeSwitches,Scanner.CurrentModeSwitches);
  539. end;
  540. procedure TTestScanner.TestEOF;
  541. begin
  542. TestToken(tkEOF,'')
  543. end;
  544. procedure TTestScanner.TestWhitespace;
  545. begin
  546. TestToken(tkWhitespace,' ');
  547. TestToken(tkWhitespace,' ');
  548. end;
  549. procedure TTestScanner.TestComment1;
  550. begin
  551. TestToken(tkComment,'{ comment }');
  552. end;
  553. procedure TTestScanner.TestComment2;
  554. begin
  555. TestToken(tkComment,'(* comment *)');
  556. end;
  557. procedure TTestScanner.TestComment3;
  558. begin
  559. TestToken(tkComment,'//');
  560. end;
  561. procedure TTestScanner.TestComment4;
  562. begin
  563. DoTestToken(tkComment,'(* abc *)',False);
  564. AssertEquals('Correct comment',' abc ',Scanner.CurTokenString);
  565. end;
  566. procedure TTestScanner.TestComment5;
  567. begin
  568. DoTestToken(tkComment,'(* abc'+LineEnding+'def *)',False);
  569. AssertEquals('Correct comment',' abc'+LineEnding+'def ',Scanner.CurTokenString);
  570. end;
  571. procedure TTestScanner.TestComment6;
  572. begin
  573. DoTestToken(tkComment,'{ abc }',False);
  574. AssertEquals('Correct comment',' abc ',Scanner.CurTokenString);
  575. end;
  576. procedure TTestScanner.TestComment7;
  577. begin
  578. DoTestToken(tkComment,'{ abc'+LineEnding+'def }',False);
  579. AssertEquals('Correct comment',' abc'+LineEnding+'def ',Scanner.CurTokenString);
  580. end;
  581. procedure TTestScanner.TestComment8;
  582. begin
  583. DoTestToken(tkComment,'// abc ',False);
  584. AssertEquals('Correct comment',' abc ',Scanner.CurTokenString);
  585. end;
  586. procedure TTestScanner.TestComment9;
  587. begin
  588. DoTestToken(tkComment,'// abc '+LineEnding,False);
  589. AssertEquals('Correct comment',' abc ',Scanner.CurTokenString);
  590. end;
  591. procedure TTestScanner.TestNestedComment1;
  592. begin
  593. TestToken(tkComment,'// { comment } ');
  594. end;
  595. procedure TTestScanner.TestNestedComment2;
  596. begin
  597. TestToken(tkComment,'(* { comment } *)');
  598. end;
  599. procedure TTestScanner.TestNestedComment3;
  600. begin
  601. TestToken(tkComment,'{ { comment } }');
  602. end;
  603. procedure TTestScanner.TestNestedComment4;
  604. begin
  605. TestToken(tkComment,'{ (* comment *) }');
  606. end;
  607. procedure TTestScanner.TestNestedComment5;
  608. begin
  609. TestToken(tkComment,'(* (* comment *) *)');
  610. end;
  611. procedure TTestScanner.TestonComment;
  612. begin
  613. FScanner.OnComment:=@DoComment;
  614. DoTestToken(tkComment,'(* abc *)',False);
  615. assertTrue('Comment called',FDoCommentCalled);
  616. AssertEquals('Correct comment',' abc ',Scanner.CurTokenString);
  617. AssertEquals('Correct comment token',' abc ',FComment);
  618. end;
  619. procedure TTestScanner.TestIdentifier;
  620. begin
  621. TestToken(tkIdentifier,'identifier');
  622. end;
  623. procedure TTestScanner.TestString;
  624. begin
  625. TestToken(pscanner.tkString,'''A string''');
  626. end;
  627. procedure TTestScanner.TestMultilineStringError;
  628. begin
  629. AssertException('Need modeswitch',EScannerError,@DoMultilineError);
  630. end;
  631. procedure TTestScanner.TestMultilineStringSource;
  632. const
  633. S = '''AB'#13#10'CD''';
  634. begin
  635. Scanner.CurrentModeSwitches:=[msMultiLineStrings];
  636. Scanner.MultilineLineFeedStyle:=elSource;
  637. DoTestToken(pscanner.tkString,'`AB'#13#10'CD`');
  638. AssertEquals('Correct lineending',S,TestTokenString);
  639. end;
  640. procedure TTestScanner.TestMultilineStringLF;
  641. const
  642. S = '''AB'#10'CD''';
  643. begin
  644. Scanner.CurrentModeSwitches:=[msMultiLineStrings];
  645. Scanner.MultilineLineFeedStyle:=elLF;
  646. DoTestToken(pscanner.tkString,'`AB'#13#10'CD`');
  647. AssertEquals('Correct lineending',S,TestTokenString);
  648. end;
  649. procedure TTestScanner.TestMultilineStringCR;
  650. const
  651. S = '''AB'#13'CD''';
  652. begin
  653. Scanner.CurrentModeSwitches:=[msMultiLineStrings];
  654. Scanner.MultilineLineFeedStyle:=elCR;
  655. DoTestToken(pscanner.tkString,'`AB'#10'CD`');
  656. AssertEquals('Correct lineending',S,TestTokenString);
  657. end;
  658. procedure TTestScanner.TestMultilineStringCRLF;
  659. const
  660. S = '''AB'#13#10'CD''';
  661. begin
  662. Scanner.CurrentModeSwitches:=[msMultiLineStrings];
  663. Scanner.MultilineLineFeedStyle:=elCRLF;
  664. DoTestToken(pscanner.tkString,'`AB'#10'CD`');
  665. AssertEquals('Correct lineending',S,TestTokenString);
  666. end;
  667. procedure TTestScanner.TestMultilineStringPlatform;
  668. const
  669. S = '''AB'+sLineBreak+'CD''';
  670. begin
  671. Scanner.CurrentModeSwitches:=[msMultiLineStrings];
  672. Scanner.MultilineLineFeedStyle:=elPlatform;
  673. DoTestToken(pscanner.tkString,'`AB'#13#10'CD`');
  674. AssertEquals('Correct lineending',S,TestTokenString);
  675. end;
  676. procedure TTestScanner.TestMultilineLineEndingDirective;
  677. begin
  678. AssertTrue('Default platform', FSCanner.MultilineLineFeedStyle=elPlatform);
  679. TestTokens([tkComment],'{$MULTILINESTRINGLINEENDING CR}');
  680. AssertTrue('CR', FSCanner.MultilineLineFeedStyle=elCR);
  681. TestTokens([tkComment],'{$MULTILINESTRINGLINEENDING LF}');
  682. AssertTrue('LF', FSCanner.MultilineLineFeedStyle=elLF);
  683. TestTokens([tkComment],'{$MULTILINESTRINGLINEENDING CRLF}');
  684. AssertTrue('CRLF', FSCanner.MultilineLineFeedStyle=elCRLF);
  685. TestTokens([tkComment],'{$MULTILINESTRINGLINEENDING SOURCE}');
  686. AssertTrue('SOURCE', FSCanner.MultilineLineFeedStyle=elSOURCE);
  687. TestTokens([tkComment],'{$MULTILINESTRINGLINEENDING PLATFORM}');
  688. AssertTrue('Platform', FSCanner.MultilineLineFeedStyle=elPlatform);
  689. end;
  690. procedure TTestScanner.TestMultilineTrimLeftDirective;
  691. begin
  692. AssertTrue('Default', FSCanner.MultilineLineTrimLeft=0);
  693. TestTokens([tkComment],'{$MULTILINESTRINGTRIMLEFT 1}');
  694. AssertTrue('1', FSCanner.MultilineLineTrimLeft=1);
  695. TestTokens([tkComment],'{$MULTILINESTRINGTRIMLEFT 2}');
  696. AssertTrue('2', FSCanner.MultilineLineTrimLeft=2);
  697. TestTokens([tkComment],'{$MULTILINESTRINGTRIMLEFT ALL}');
  698. AssertTrue('ALL', FSCanner.MultilineLineTrimLeft=-2);
  699. TestTokens([tkComment],'{$MULTILINESTRINGTRIMLEFT AUTO}');
  700. AssertTrue('AUTO', FSCanner.MultilineLineTrimLeft=-1);
  701. end;
  702. procedure TTestScanner.TestMultilineStringTrimAll;
  703. const
  704. S = '''AB'#10'CD''';
  705. begin
  706. SCanner.MultilineLineTrimLeft:=-2;
  707. Scanner.CurrentModeSwitches:=[msMultiLineStrings];
  708. Scanner.MultilineLineFeedStyle:=elLF;
  709. DoTestToken(pscanner.tkString,'`AB'#13#10' CD`');
  710. AssertEquals('Correct trim',S,TestTokenString);
  711. end;
  712. procedure TTestScanner.TestMultilineStringTrimAuto;
  713. const
  714. S = '''AB'#10' CD''';
  715. begin
  716. SCanner.MultilineLineTrimLeft:=-1;
  717. Scanner.CurrentModeSwitches:=[msMultiLineStrings];
  718. Scanner.MultilineLineFeedStyle:=elLF;
  719. Scanner.SkipWhiteSpace:=True;
  720. DoTestToken(pscanner.tkString,' `AB'#13#10' CD`');
  721. AssertEquals('Correct trim',S,TestTokenString);
  722. end;
  723. procedure TTestScanner.TestMultilineStringTrim2;
  724. const
  725. S = '''AB'#10' CD''';
  726. S2 = '''AB'#10'CD''';
  727. begin
  728. SCanner.MultilineLineTrimLeft:=2;
  729. Scanner.CurrentModeSwitches:=[msMultiLineStrings];
  730. Scanner.MultilineLineFeedStyle:=elLF;
  731. Scanner.SkipWhiteSpace:=True;
  732. DoTestToken(pscanner.tkString,' `AB'#13#10' CD`');
  733. AssertEquals('Correct trim',S,TestTokenString);
  734. DoTestToken(pscanner.tkString,' `AB'#13#10' CD`');
  735. AssertEquals('Correct trim 2',S2,TestTokenString);
  736. end;
  737. procedure TTestScanner.TestCharString;
  738. begin
  739. TestToken(pscanner.tkChar,'''A''');
  740. end;
  741. procedure TTestScanner.TestCaretString;
  742. begin
  743. TestTokens([tkIdentifier,tkWhiteSpace,tkEqual,tkwhiteSpace,pscanner.tkString,tkSemicolon],'a = ^C''abc'';',false);
  744. end;
  745. procedure TTestScanner.TestNumber;
  746. begin
  747. TestToken(tkNumber,'123');
  748. end;
  749. procedure TTestScanner.TestChar;
  750. begin
  751. TestToken(pscanner.tkChar,'#65 ', false);
  752. end;
  753. procedure TTestScanner.TestBraceOpen;
  754. begin
  755. TestToken(tkBraceOpen,'(');
  756. end;
  757. procedure TTestScanner.TestBraceClose;
  758. begin
  759. TestToken(tkBraceClose,')');
  760. end;
  761. procedure TTestScanner.TestMul;
  762. begin
  763. TestToken(tkMul,'*');
  764. end;
  765. procedure TTestScanner.TestPlus;
  766. begin
  767. TestToken(tkPlus,'+');
  768. end;
  769. procedure TTestScanner.TestComma;
  770. begin
  771. TestToken(tkComma,',');
  772. end;
  773. procedure TTestScanner.TestMinus;
  774. begin
  775. TestToken(tkMinus,'-');
  776. end;
  777. procedure TTestScanner.TestDot;
  778. begin
  779. TestToken(tkDot,'.');
  780. end;
  781. procedure TTestScanner.TestDivision;
  782. begin
  783. TestToken(tkDivision,'/');
  784. end;
  785. procedure TTestScanner.TestColon;
  786. begin
  787. TestToken(tkColon,':');
  788. end;
  789. procedure TTestScanner.TestSemicolon;
  790. begin
  791. TestToken(tkSemicolon,';');
  792. end;
  793. procedure TTestScanner.TestLessThan;
  794. begin
  795. TestToken(tkLessThan,'<');
  796. end;
  797. procedure TTestScanner.TestEqual;
  798. begin
  799. TestToken(tkEqual,'=');
  800. end;
  801. procedure TTestScanner.TestGreaterThan;
  802. begin
  803. TestToken(tkGreaterThan,'>');
  804. end;
  805. procedure TTestScanner.TestAt;
  806. begin
  807. TestToken(tkAt,'@');
  808. end;
  809. procedure TTestScanner.TestSquaredBraceOpen;
  810. begin
  811. TestToken(tkSquaredBraceOpen,'[');
  812. TestToken(tkSquaredBraceOpen,'(.'); // JC: Test for the BraceDotOpen
  813. end;
  814. procedure TTestScanner.TestSquaredBraceClose;
  815. begin
  816. TestToken(tkSquaredBraceClose,']');
  817. TestToken(tkSquaredBraceClose,'.)'); // JC: Test for the DotBraceClose
  818. TestTokens([tkNumber,tkSquaredBraceClose],'1.)'); // JC: Test for a Number followed by DotBraceClose
  819. end;
  820. procedure TTestScanner.TestCaret;
  821. begin
  822. TestToken(tkCaret,'^');
  823. end;
  824. procedure TTestScanner.TestBackslash;
  825. begin
  826. TestToken(tkBackslash,'\');
  827. end;
  828. procedure TTestScanner.TestDotDot;
  829. begin
  830. TestToken(tkDotDot,'..');
  831. end;
  832. procedure TTestScanner.TestAssign;
  833. begin
  834. TestToken(tkAssign,':=');
  835. end;
  836. procedure TTestScanner.TestAssignPlus;
  837. begin
  838. TestTokens([tkPlus,tkEqual],'+=');
  839. FScanner.Options:=[po_cassignments];
  840. TestToken(tkAssignPlus,'+=');
  841. end;
  842. procedure TTestScanner.TestAssignMinus;
  843. begin
  844. TestTokens([tkMinus,tkEqual],'-=');
  845. FScanner.Options:=[po_cassignments];
  846. TestToken(tkAssignMinus,'-=');
  847. end;
  848. procedure TTestScanner.TestAssignMul;
  849. begin
  850. TestTokens([tkMul,tkEqual],'*=');
  851. FScanner.Options:=[po_cassignments];
  852. TestToken(tkAssignMul,'*=');
  853. end;
  854. procedure TTestScanner.TestAssignDivision;
  855. begin
  856. TestTokens([tkDivision,tkEqual],'/=');
  857. FScanner.Options:=[po_cassignments];
  858. TestToken(tkAssignDivision,'/=');
  859. end;
  860. procedure TTestScanner.TestNotEqual;
  861. begin
  862. TestToken(tkNotEqual,'<>');
  863. end;
  864. procedure TTestScanner.TestLessEqualThan;
  865. begin
  866. TestToken(tkLessEqualThan,'<=');
  867. end;
  868. procedure TTestScanner.TestGreaterEqualThan;
  869. begin
  870. TestToken(tkGreaterEqualThan,'>=');
  871. end;
  872. procedure TTestScanner.TestPower;
  873. begin
  874. TestToken(tkPower,'**');
  875. end;
  876. procedure TTestScanner.TestSymmetricalDifference;
  877. begin
  878. TestToken(tkSymmetricalDifference,'><');
  879. end;
  880. procedure TTestScanner.TestAbsolute;
  881. begin
  882. TestToken(tkabsolute,'absolute');
  883. end;
  884. procedure TTestScanner.TestAnd;
  885. begin
  886. TestToken(tkand,'and');
  887. end;
  888. procedure TTestScanner.TestArray;
  889. begin
  890. TestToken(tkarray,'array');
  891. end;
  892. procedure TTestScanner.TestAs;
  893. begin
  894. TestToken(tkas,'as');
  895. end;
  896. procedure TTestScanner.TestAsm;
  897. begin
  898. TestToken(tkasm,'asm');
  899. end;
  900. procedure TTestScanner.TestBegin;
  901. begin
  902. TestToken(tkbegin,'begin');
  903. end;
  904. procedure TTestScanner.TestBitpacked;
  905. begin
  906. TestToken(tkbitpacked,'bitpacked');
  907. end;
  908. procedure TTestScanner.TestCase;
  909. begin
  910. TestToken(tkcase,'case');
  911. end;
  912. procedure TTestScanner.TestClass;
  913. begin
  914. TestToken(tkclass,'class');
  915. end;
  916. procedure TTestScanner.TestConst;
  917. begin
  918. TestToken(tkconst,'const');
  919. end;
  920. procedure TTestScanner.TestConstructor;
  921. begin
  922. TestToken(tkconstructor,'constructor');
  923. end;
  924. procedure TTestScanner.TestDestructor;
  925. begin
  926. TestToken(tkdestructor,'destructor');
  927. end;
  928. procedure TTestScanner.TestDispinterface;
  929. begin
  930. TestToken(tkdispinterface,'dispinterface');
  931. end;
  932. procedure TTestScanner.TestDiv;
  933. begin
  934. TestToken(tkdiv,'div');
  935. end;
  936. procedure TTestScanner.TestDo;
  937. begin
  938. TestToken(tkdo,'do');
  939. end;
  940. procedure TTestScanner.TestDownto;
  941. begin
  942. TestToken(tkdownto,'downto');
  943. end;
  944. procedure TTestScanner.TestElse;
  945. begin
  946. TestToken(tkelse,'else');
  947. end;
  948. procedure TTestScanner.TestEnd;
  949. begin
  950. TestToken(tkend,'end');
  951. end;
  952. procedure TTestScanner.TestExcept;
  953. begin
  954. TestToken(tkexcept,'except');
  955. end;
  956. procedure TTestScanner.TestExports;
  957. begin
  958. TestToken(tkexports,'exports');
  959. end;
  960. procedure TTestScanner.TestFalse;
  961. begin
  962. TestToken(tkfalse,'false');
  963. end;
  964. procedure TTestScanner.TestFile;
  965. begin
  966. TestToken(tkfile,'file');
  967. end;
  968. procedure TTestScanner.TestFinalization;
  969. begin
  970. TestToken(tkfinalization,'finalization');
  971. end;
  972. procedure TTestScanner.TestFinally;
  973. begin
  974. TestToken(tkfinally,'finally');
  975. end;
  976. procedure TTestScanner.TestFor;
  977. begin
  978. TestToken(tkfor,'for');
  979. end;
  980. procedure TTestScanner.TestFunction;
  981. begin
  982. TestToken(tkfunction,'function');
  983. end;
  984. procedure TTestScanner.TestGeneric;
  985. begin
  986. TestToken(tkgeneric,'generic');
  987. end;
  988. procedure TTestScanner.TestGoto;
  989. begin
  990. TestToken(tkgoto,'goto');
  991. end;
  992. procedure TTestScanner.TestHelper;
  993. begin
  994. TestToken(tkIdentifier,'helper');
  995. end;
  996. procedure TTestScanner.TestIf;
  997. begin
  998. TestToken(tkif,'if');
  999. end;
  1000. procedure TTestScanner.TestImplementation;
  1001. begin
  1002. TestToken(tkimplementation,'implementation');
  1003. end;
  1004. procedure TTestScanner.TestIn;
  1005. begin
  1006. TestToken(tkin,'in');
  1007. end;
  1008. procedure TTestScanner.TestInherited;
  1009. begin
  1010. TestToken(tkinherited,'inherited');
  1011. end;
  1012. procedure TTestScanner.TestInitialization;
  1013. begin
  1014. TestToken(tkinitialization,'initialization');
  1015. end;
  1016. procedure TTestScanner.TestInline;
  1017. begin
  1018. TestToken(tkinline,'inline');
  1019. end;
  1020. procedure TTestScanner.TestInterface;
  1021. begin
  1022. TestToken(tkinterface,'interface');
  1023. end;
  1024. procedure TTestScanner.TestIs;
  1025. begin
  1026. TestToken(tkis,'is');
  1027. end;
  1028. procedure TTestScanner.TestLabel;
  1029. begin
  1030. TestToken(tklabel,'label');
  1031. end;
  1032. procedure TTestScanner.TestLibrary;
  1033. begin
  1034. TestToken(tklibrary,'library');
  1035. end;
  1036. procedure TTestScanner.TestMod;
  1037. begin
  1038. TestToken(tkmod,'mod');
  1039. end;
  1040. procedure TTestScanner.TestNil;
  1041. begin
  1042. TestToken(tknil,'nil');
  1043. end;
  1044. procedure TTestScanner.TestNot;
  1045. begin
  1046. TestToken(tknot,'not');
  1047. end;
  1048. procedure TTestScanner.TestObject;
  1049. begin
  1050. TestToken(tkobject,'object');
  1051. end;
  1052. procedure TTestScanner.TestOf;
  1053. begin
  1054. TestToken(tkof,'of');
  1055. end;
  1056. procedure TTestScanner.TestOn;
  1057. begin
  1058. TestToken(tkIdentifier,'on');
  1059. end;
  1060. procedure TTestScanner.TestOperator;
  1061. begin
  1062. Scanner.SetTokenOption(toOperatorToken);
  1063. TestToken(tkoperator,'operator');
  1064. end;
  1065. procedure TTestScanner.TestOr;
  1066. begin
  1067. TestToken(tkor,'or');
  1068. end;
  1069. procedure TTestScanner.TestPacked;
  1070. begin
  1071. TestToken(tkpacked,'packed');
  1072. end;
  1073. procedure TTestScanner.TestProcedure;
  1074. begin
  1075. TestToken(tkprocedure,'procedure');
  1076. end;
  1077. procedure TTestScanner.TestProgram;
  1078. begin
  1079. TestToken(tkprogram,'program');
  1080. end;
  1081. procedure TTestScanner.TestProperty;
  1082. begin
  1083. TestToken(tkproperty,'property');
  1084. end;
  1085. procedure TTestScanner.TestRaise;
  1086. begin
  1087. TestToken(tkraise,'raise');
  1088. end;
  1089. procedure TTestScanner.TestRecord;
  1090. begin
  1091. TestToken(tkrecord,'record');
  1092. end;
  1093. procedure TTestScanner.TestRepeat;
  1094. begin
  1095. TestToken(tkrepeat,'repeat');
  1096. end;
  1097. procedure TTestScanner.TestResourceString;
  1098. begin
  1099. TestToken(tkResourceString,'resourcestring');
  1100. end;
  1101. procedure TTestScanner.TestSelf;
  1102. begin
  1103. FScanner.Options:=FScanner.Options + [po_selftoken];
  1104. TestToken(tkself,'self');
  1105. end;
  1106. procedure TTestScanner.TestSelfNoToken;
  1107. begin
  1108. TestToken(tkIdentifier,'self');
  1109. end;
  1110. procedure TTestScanner.TestSet;
  1111. begin
  1112. TestToken(tkset,'set');
  1113. end;
  1114. procedure TTestScanner.TestShl;
  1115. begin
  1116. TestToken(tkshl,'shl');
  1117. end;
  1118. procedure TTestScanner.TestShr;
  1119. begin
  1120. TestToken(tkshr,'shr');
  1121. end;
  1122. procedure TTestScanner.TestShlC;
  1123. begin
  1124. TestToken(tkshl,'<<');
  1125. end;
  1126. procedure TTestScanner.TestShrC;
  1127. begin
  1128. TestToken(tkshr,'>>');
  1129. end;
  1130. procedure TTestScanner.TestSpecialize;
  1131. begin
  1132. TestToken(tkspecialize,'specialize');
  1133. end;
  1134. procedure TTestScanner.TestThen;
  1135. begin
  1136. TestToken(tkthen,'then');
  1137. end;
  1138. procedure TTestScanner.TestThreadvar;
  1139. begin
  1140. TestToken(tkthreadvar,'threadvar');
  1141. end;
  1142. procedure TTestScanner.TestTo;
  1143. begin
  1144. TestToken(tkto,'to');
  1145. end;
  1146. procedure TTestScanner.TestTrue;
  1147. begin
  1148. TestToken(tktrue,'true');
  1149. end;
  1150. procedure TTestScanner.TestTry;
  1151. begin
  1152. TestToken(tktry,'try');
  1153. end;
  1154. procedure TTestScanner.TestType;
  1155. begin
  1156. TestToken(tktype,'type');
  1157. end;
  1158. procedure TTestScanner.TestUnit;
  1159. begin
  1160. TestToken(tkunit,'unit');
  1161. end;
  1162. procedure TTestScanner.TestUntil;
  1163. begin
  1164. TestToken(tkuntil,'until');
  1165. end;
  1166. procedure TTestScanner.TestUses;
  1167. begin
  1168. TestToken(tkuses,'uses');
  1169. end;
  1170. procedure TTestScanner.TestVar;
  1171. begin
  1172. TestToken(tkvar,'var');
  1173. end;
  1174. procedure TTestScanner.TestWhile;
  1175. begin
  1176. TestToken(tkwhile,'while');
  1177. end;
  1178. procedure TTestScanner.TestWith;
  1179. begin
  1180. TestToken(tkwith,'with');
  1181. end;
  1182. procedure TTestScanner.TestXor;
  1183. begin
  1184. TestToken(tkxor,'xor');
  1185. end;
  1186. procedure TTestScanner.TestLineEnding;
  1187. begin
  1188. TestToken(tkLineEnding,#10);
  1189. end;
  1190. procedure TTestScanner.TestObjCClass;
  1191. begin
  1192. TestToken(tkObjCClass,'objcclass');
  1193. end;
  1194. procedure TTestScanner.TestObjCClass2;
  1195. begin
  1196. TestTokens([tkComment,tkWhitespace,tkidentifier],'{$mode fpc} objcclass');
  1197. end;
  1198. procedure TTestScanner.TestObjCProtocol;
  1199. begin
  1200. TestToken(tkObjCProtocol,'objcprotocol');
  1201. end;
  1202. procedure TTestScanner.TestObjCProtocol2;
  1203. begin
  1204. TestTokens([tkComment,tkWhitespace,tkidentifier],'{$mode fpc} objcprotocol');
  1205. end;
  1206. procedure TTestScanner.TestObjCCategory;
  1207. begin
  1208. TestToken(tkObjCCategory,'objccategory');
  1209. end;
  1210. procedure TTestScanner.TestObjCCategory2;
  1211. begin
  1212. TestTokens([tkComment,tkWhitespace,tkidentifier],'{$mode fpc} objccategory');
  1213. end;
  1214. procedure TTestScanner.TestTab;
  1215. begin
  1216. TestToken(tkTab,#9);
  1217. end;
  1218. procedure TTestScanner.TestEscapedKeyWord;
  1219. begin
  1220. TestToken(tkIdentifier,'&xor');
  1221. end;
  1222. procedure TTestScanner.TestTokenSeries;
  1223. begin
  1224. TestTokens([tkin,tkWhitespace,tkOf,tkWhiteSpace,tkthen,tkWhiteSpace,tkIdentifier],'in of then aninteger')
  1225. end;
  1226. procedure TTestScanner.TestTokenSeriesNoWhiteSpace;
  1227. begin
  1228. FScanner.SkipWhiteSpace:=True;
  1229. TestTokens([tkin,tkOf,tkthen,tkIdentifier],'in of then aninteger')
  1230. end;
  1231. procedure TTestScanner.TestTokenSeriesComments;
  1232. begin
  1233. TestTokens([tkin,tkWhitespace,tkOf,tkWhiteSpace,tkComment,tkWhiteSpace,tkIdentifier],'in of {then} aninteger')
  1234. end;
  1235. procedure TTestScanner.TestTokenSeriesNoComments;
  1236. begin
  1237. FScanner.SkipComments:=True;
  1238. TestTokens([tkin,tkWhitespace,tkOf,tkWhiteSpace,tkWhiteSpace,tkIdentifier],'in of {then} aninteger')
  1239. end;
  1240. procedure TTestScanner.TestDefine0;
  1241. begin
  1242. TestTokens([tkComment],'{$DEFINE NEVER}');
  1243. AssertTrue('Define not defined', FSCanner.Defines.IndexOf('NEVER')<>-1);
  1244. end;
  1245. procedure TTestScanner.TestDefine0Spaces;
  1246. begin
  1247. TestTokens([tkComment],'{$DEFINE NEVER}');
  1248. AssertTrue('Define not defined',FSCanner.Defines.IndexOf('NEVER')<>-1);
  1249. end;
  1250. procedure TTestScanner.TestDefine0Spaces2;
  1251. begin
  1252. TestTokens([tkComment],'{$DEFINE NEVER }');
  1253. AssertTrue('Define not defined',FSCanner.Defines.IndexOf('NEVER')<>-1);
  1254. end;
  1255. procedure TTestScanner.TestDefine01;
  1256. begin
  1257. TestTokens([tkComment],'(*$DEFINE NEVER*)');
  1258. AssertTrue('Define not defined',FSCanner.Defines.IndexOf('NEVER')<>-1);
  1259. end;
  1260. procedure TTestScanner.TestDefine1;
  1261. begin
  1262. TestTokens([tkComment],'{$IFDEF NEVER} of {$ENDIF}');
  1263. end;
  1264. procedure TTestScanner.TestDefine2;
  1265. begin
  1266. FSCanner.Defines.Add('ALWAYS');
  1267. TestTokens([tkComment,tkWhitespace,tkOf,tkWhitespace,tkcomment],'{$IFDEF ALWAYS comment} of {$ENDIF}');
  1268. end;
  1269. procedure TTestScanner.TestDefine21;
  1270. begin
  1271. FSCanner.Defines.Add('ALWAYS');
  1272. TestTokens([tkComment,tkWhitespace,tkOf,tkWhitespace,tkcomment],'(*$IFDEF ALWAYS*) of (*$ENDIF*)');
  1273. end;
  1274. procedure TTestScanner.TestDefine22;
  1275. begin
  1276. FSCanner.Defines.Add('ALWAYS');
  1277. // No whitespace. Test border of *)
  1278. TestTokens([tkComment,tkOf,tkWhitespace,tkcomment],'(*$IFDEF ALWAYS*)of (*$ENDIF*)');
  1279. end;
  1280. procedure TTestScanner.TestDefine3;
  1281. begin
  1282. FSCanner.Defines.Add('ALWAYS');
  1283. TestTokens([tkComment,tkWhitespace,tkOf,tkWhitespace,tkcomment],'{$IFDEF ALWAYS} of {$ELSE} in {$ENDIF}');
  1284. end;
  1285. procedure TTestScanner.TestDefine4;
  1286. begin
  1287. TestTokens([tkComment,tkWhitespace,tkin,tkWhitespace,tkcomment],'{$IFDEF ALWAYS} of {$ELSE} in {$ENDIF}');
  1288. end;
  1289. procedure TTestScanner.TestDefine5;
  1290. begin
  1291. FScanner.SkipComments:=True;
  1292. TestTokens([tkLineEnding],'{$IFDEF NEVER} of {$ENDIF}');
  1293. end;
  1294. procedure TTestScanner.TestDefine6;
  1295. begin
  1296. FSCanner.Defines.Add('ALWAYS');
  1297. FScanner.SkipComments:=True;
  1298. TestTokens([tkWhitespace,tkOf,tkWhitespace],'{$IFDEF ALWAYS} of {$ENDIF}');
  1299. end;
  1300. procedure TTestScanner.TestDefine7;
  1301. begin
  1302. FSCanner.Defines.Add('ALWAYS');
  1303. FScanner.SkipComments:=True;
  1304. TestTokens([tkWhitespace,tkOf,tkWhitespace],'{$IFDEF ALWAYS} of {$ELSE} in {$ENDIF}');
  1305. end;
  1306. procedure TTestScanner.TestDefine8;
  1307. begin
  1308. FScanner.SkipComments:=True;
  1309. TestTokens([tkWhitespace,tkin,tkWhitespace],'{$IFDEF ALWAYS} of {$ELSE} in {$ENDIF}');
  1310. end;
  1311. procedure TTestScanner.TestDefine9;
  1312. begin
  1313. FScanner.SkipWhiteSpace:=True;
  1314. TestTokens([],'{$IFDEF NEVER} of {$ENDIF}');
  1315. end;
  1316. procedure TTestScanner.TestDefine10;
  1317. begin
  1318. FSCanner.Defines.Add('ALWAYS');
  1319. FScanner.SkipComments:=True;
  1320. TestTokens([tkWhitespace,tkOf,tkWhitespace],'{$IFDEF ALWAYS} of {$ENDIF}');
  1321. end;
  1322. procedure TTestScanner.TestDefine11;
  1323. begin
  1324. FSCanner.Defines.Add('ALWAYS');
  1325. FScanner.SkipComments:=True;
  1326. FScanner.SkipWhiteSpace:=True;
  1327. TestTokens([tkOf],'{$IFDEF ALWAYS} of {$ELSE} in {$ENDIF}');
  1328. end;
  1329. procedure TTestScanner.TestDefine12;
  1330. begin
  1331. FScanner.SkipComments:=True;
  1332. FScanner.SkipWhiteSpace:=True;
  1333. TestTokens([tkin],'{$IFDEF ALWAYS} of {$ELSE} in {$ENDIF}');
  1334. end;
  1335. procedure TTestScanner.TestDefine13;
  1336. begin
  1337. FScanner.SkipComments:=True;
  1338. FScanner.SkipWhiteSpace:=True;
  1339. TestTokens([tkin],'{$IFDEF ALWAYS} }; ą è {$ELSE} in {$ENDIF}');
  1340. end;
  1341. procedure TTestScanner.TestDefine14;
  1342. Const
  1343. Source = '{$ifdef NEVER_DEFINED}' +sLineBreak+
  1344. 'type'+sLineBreak+
  1345. ' TNPEventModel = ('+sLineBreak+
  1346. ' NPEventModelCarbon = 0,'+sLineBreak+
  1347. ' NPEventModelCocoa = 1'+sLineBreak+
  1348. '}; // yes, this is an error... except this code should never be included.'+sLineBreak+
  1349. 'ą'+sLineBreak+
  1350. '|'+sLineBreak+
  1351. '{$endif}'+sLineBreak+
  1352. ''+sLineBreak+
  1353. 'begin'+sLineBreak+
  1354. 'end.'+sLineBreak;
  1355. begin
  1356. NewSource(Source,True);
  1357. While FScanner.fetchToken<>tkEOF do
  1358. end;
  1359. procedure TTestScanner.TestInclude;
  1360. begin
  1361. FResolver.AddStream('myinclude.inc',TStringStream.Create('if true then'));
  1362. FScanner.SkipWhiteSpace:=True;
  1363. FScanner.SkipComments:=True;
  1364. TestTokens([tkIf,tkTrue,tkThen],'{$I myinclude.inc}',True,False);
  1365. end;
  1366. procedure TTestScanner.TestInclude2;
  1367. begin
  1368. FResolver.AddStream('myinclude.inc',TStringStream.Create('if true then'));
  1369. FScanner.SkipWhiteSpace:=True;
  1370. FScanner.SkipComments:=True;
  1371. TestTokens([tkIf,tkTrue,tkThen,tkElse],'{$I myinclude.inc} else',True,False);
  1372. end;
  1373. procedure TTestScanner.TestInclude3;
  1374. begin
  1375. PathPrefix:='src';
  1376. FResolver.AddStream('src/myinclude2.inc',TStringStream.Create(' true '));
  1377. FResolver.AddStream('src/myinclude1.inc',TStringStream.Create('if {$i myinclude2.inc} then '));
  1378. FScanner.SkipWhiteSpace:=True;
  1379. FScanner.SkipComments:=True;
  1380. TestTokens([tkIf,tkTrue,tkThen,tkElse],'{$I src/myinclude1.inc} else',True,False);
  1381. end;
  1382. procedure TTestScanner.TestIncludeString;
  1383. begin
  1384. FResolver.AddStream('myinclude.inc',TStringStream.Create('if true then'));
  1385. FScanner.SkipWhiteSpace:=True;
  1386. FScanner.SkipComments:=True;
  1387. TestTokens([tkString],'{$INCLUDESTRING myinclude.inc}',False,False);
  1388. AssertEquals('Correct string','''if true then''',TestTokenString)
  1389. end;
  1390. procedure TTestScanner.TestIncludeStringFile;
  1391. begin
  1392. FResolver.AddStream('myinclude.inc',TStringStream.Create('if true then'));
  1393. FScanner.SkipWhiteSpace:=True;
  1394. FScanner.SkipComments:=True;
  1395. TestTokens([tkString],'{$INCLUDESTRINGFILE myinclude.inc}',False,False);
  1396. AssertEquals('Correct string','''if true then''',TestTokenString)
  1397. end;
  1398. procedure TTestScanner.TestIncludeString2Lines;
  1399. begin
  1400. FResolver.AddStream('myinclude.inc',TStringStream.Create('if true then'#10'else'));
  1401. FScanner.SkipWhiteSpace:=True;
  1402. FScanner.SkipComments:=True;
  1403. FScanner.MultilineLineFeedStyle:=elCRLF;
  1404. TestTokens([tkString],'{$INCLUDESTRING myinclude.inc}',False,False);
  1405. AssertEquals('Correct string','''if true then'#13#10'else''',TestTokenString)
  1406. end;
  1407. procedure TTestScanner.TestUnDefine1;
  1408. begin
  1409. FSCanner.Defines.Add('ALWAYS');
  1410. TestTokens([tkComment],'{$UNDEF ALWAYS}');
  1411. AssertEquals('No more define',-1,FScanner.Defines.INdexOf('ALWAYS'));
  1412. end;
  1413. procedure TTestScanner.TestMacro1;
  1414. begin
  1415. FScanner.SkipWhiteSpace:=True;
  1416. FScanner.SkipComments:=True;
  1417. TestTokens([tkbegin,tkend,tkDot],'{$MACRO on}{$DEFINE MM:=begin end.}'#13#10'MM',True,False);
  1418. end;
  1419. procedure TTestScanner.TestMacro2;
  1420. begin
  1421. FScanner.SkipWhiteSpace:=True;
  1422. FScanner.SkipComments:=True;
  1423. TestTokens([tkbegin,tkend,tkDot],'{$MACRO on}{$DEFINE MM:=begin end}'#13#10'MM .',True,False);
  1424. end;
  1425. procedure TTestScanner.TestMacro3;
  1426. begin
  1427. FScanner.SkipComments:=True;
  1428. FScanner.SkipWhiteSpace:=True;
  1429. TestTokens([tkof],'{$MACRO on}{$DEFINE MM:=begin end}'#13#10'{$IFDEF MM} of {$ELSE} in {$ENDIF}');
  1430. end;
  1431. procedure TTestScanner.TestMacroHandling;
  1432. begin
  1433. TTestingPascalScanner(FScanner).DoSpecial:=True;
  1434. FScanner.SkipComments:=True;
  1435. FScanner.SkipWhiteSpace:=True;
  1436. TestTokens([tkIdentifier],'{$MACRO on}{$DEFINE MM:=begin end}'#13#10'MM');
  1437. AssertEQuals('Correct identifier', 'somethingweird',LastIdentifier);
  1438. end;
  1439. procedure TTestScanner.TestIFDefined;
  1440. begin
  1441. FScanner.SkipWhiteSpace:=True;
  1442. FScanner.SkipComments:=True;
  1443. TestTokens([tkbegin,tkend,tkDot],'{$DEFINE A}{$IF defined(A)}begin{$ENDIF}end.',True,False);
  1444. end;
  1445. procedure TTestScanner.TestIFUnDefined;
  1446. begin
  1447. FScanner.SkipWhiteSpace:=True;
  1448. FScanner.SkipComments:=True;
  1449. TestTokens([tkbegin,tkend,tkDot],'{$IF undefined(A)}begin{$ENDIF}end.',True,False);
  1450. end;
  1451. procedure TTestScanner.TestIFAnd;
  1452. begin
  1453. FScanner.SkipWhiteSpace:=True;
  1454. FScanner.SkipComments:=True;
  1455. TestTokens([tkbegin,tkend,tkDot],
  1456. '{$DEFINE A}{$IF defined(A) and undefined(B)}begin{$ENDIF}end.',True,False);
  1457. end;
  1458. procedure TTestScanner.TestIFAndShortEval;
  1459. begin
  1460. FScanner.SkipWhiteSpace:=True;
  1461. FScanner.SkipComments:=True;
  1462. TestTokens([tkbegin,tkend,tkDot],
  1463. '{$UNDEFINE A}{$IF defined(A) and undefined(B)}wrong{$ELSE}begin{$ENDIF}end.',
  1464. True,False);
  1465. end;
  1466. procedure TTestScanner.TestIFOr;
  1467. begin
  1468. FScanner.SkipWhiteSpace:=True;
  1469. FScanner.SkipComments:=True;
  1470. TestTokens([tkbegin,tkend,tkDot],
  1471. '{$DEFINE B}{$IF defined(A) or defined(B)}begin{$ENDIF}end.',True,False);
  1472. end;
  1473. procedure TTestScanner.TestIFOrShortEval;
  1474. begin
  1475. FScanner.SkipWhiteSpace:=True;
  1476. FScanner.SkipComments:=True;
  1477. TestTokens([tkbegin,tkend,tkDot],
  1478. '{$DEFINE A}{$IF defined(A) or defined(B)}begin{$ENDIF}end.',True,False);
  1479. end;
  1480. procedure TTestScanner.TestIFXor;
  1481. begin
  1482. FScanner.SkipWhiteSpace:=True;
  1483. FScanner.SkipComments:=True;
  1484. TestTokens([tkbegin,tkend,tkDot],
  1485. '{$DEFINE B}{$IF defined(A) xor defined(B)}begin{$ENDIF}end.',True,False);
  1486. end;
  1487. procedure TTestScanner.TestIFAndOr;
  1488. begin
  1489. FScanner.SkipWhiteSpace:=True;
  1490. FScanner.SkipComments:=True;
  1491. TestTokens([tkbegin,tkend,tkDot],
  1492. '{$IF defined(A) and defined(B) or defined(C)}wrong1{$ENDIF}'+LineEnding
  1493. +'{$IF defined(A) and defined(B) or undefined(C)}{$ELSE}wrong2{$ENDIF}'+LineEnding
  1494. +'{$IF defined(A) and undefined(B) or defined(C)}wrong3{$ENDIF}'+LineEnding
  1495. +'{$IF defined(A) and undefined(B) or undefined(C)}{$ELSE}wrong4{$ENDIF}'+LineEnding
  1496. +'{$IF undefined(A) and defined(B) or defined(C)}wrong5{$ENDIF}'+LineEnding
  1497. +'{$IF undefined(A) and defined(B) or undefined(C)}{$ELSE}wrong6{$ENDIF}'+LineEnding
  1498. +'{$IF undefined(A) and undefined(B) or defined(C)}{$ELSE}wrong7{$ENDIF}'+LineEnding
  1499. +'{$IF undefined(A) and undefined(B) or undefined(C)}begin{$ENDIF}end.',
  1500. True,False);
  1501. end;
  1502. procedure TTestScanner.TestIFEqual;
  1503. begin
  1504. FScanner.SkipWhiteSpace:=True;
  1505. FScanner.SkipComments:=True;
  1506. FScanner.AddMacro('Version','30101');
  1507. TestTokens([tkbegin,tkend,tkDot],
  1508. '{$IF Version=30101}begin{$ENDIF}end.',True,False);
  1509. end;
  1510. procedure TTestScanner.TestIFNotEqual;
  1511. begin
  1512. FScanner.SkipWhiteSpace:=True;
  1513. FScanner.SkipComments:=True;
  1514. FScanner.AddMacro('Version','30101');
  1515. TestTokens([tkbegin,tkend,tkDot],
  1516. '{$IF Version<>30000}begin{$ENDIF}end.',True,False);
  1517. end;
  1518. procedure TTestScanner.TestIFGreaterThan;
  1519. begin
  1520. FScanner.SkipWhiteSpace:=True;
  1521. FScanner.SkipComments:=True;
  1522. FScanner.AddMacro('Version','30101');
  1523. TestTokens([tkbegin,tkend,tkDot],
  1524. '{$IF Version>30000}begin{$ENDIF}end.',True,False);
  1525. end;
  1526. procedure TTestScanner.TestIFGreaterEqualThan;
  1527. begin
  1528. FScanner.SkipWhiteSpace:=True;
  1529. FScanner.SkipComments:=True;
  1530. FScanner.AddMacro('Version','30101');
  1531. TestTokens([tkbegin,tkend,tkDot],
  1532. '{$IF Version>=30000}begin{$ENDIF}end.',True,False);
  1533. end;
  1534. procedure TTestScanner.TestIFLesserThan;
  1535. begin
  1536. FScanner.SkipWhiteSpace:=True;
  1537. FScanner.SkipComments:=True;
  1538. FScanner.AddMacro('Version','30101');
  1539. TestTokens([tkbegin,tkend,tkDot],
  1540. '{$IF Version<40000}begin{$ENDIF}end.',True,False);
  1541. end;
  1542. procedure TTestScanner.TestIFLesserEqualThan;
  1543. begin
  1544. FScanner.SkipWhiteSpace:=True;
  1545. FScanner.SkipComments:=True;
  1546. FScanner.AddMacro('Version','30101');
  1547. TestTokens([tkbegin,tkend,tkDot],
  1548. '{$IF Version<=30101}begin{$ENDIF}end.',True,False);
  1549. end;
  1550. procedure TTestScanner.TestIFDefinedElseIf;
  1551. begin
  1552. FScanner.SkipWhiteSpace:=True;
  1553. FScanner.SkipComments:=True;
  1554. FScanner.AddDefine('cpu32');
  1555. TestTokens([tkconst,tkIdentifier,tkEqual,tkString,tkSemicolon,tkbegin,tkend,tkDot],
  1556. 'const platform = '+LineEnding
  1557. +'{$if defined(cpu32)} ''x86'''+LineEnding
  1558. +'{$elseif defined(cpu64)} ''x64'''+LineEnding
  1559. +'{$else} {$error unknown platform} {$endif};'+LineEnding
  1560. +'begin end.',True,False);
  1561. end;
  1562. procedure TTestScanner.TestIfError;
  1563. begin
  1564. FScanner.SkipWhiteSpace:=True;
  1565. FScanner.SkipComments:=True;
  1566. TestTokens([tkprogram,tkIdentifier,tkSemicolon,tkbegin,tkend,tkDot],
  1567. 'program Project1;'+LineEnding
  1568. +'begin'+LineEnding
  1569. +'{$if sizeof(integer) <> 4} {$error wrong sizeof(integer)} {$endif}'+LineEnding
  1570. +'end.',True,False);
  1571. end;
  1572. procedure TTestScanner.TestIFCDefined;
  1573. begin
  1574. FScanner.SkipWhiteSpace:=True;
  1575. FScanner.SkipComments:=True;
  1576. FScanner.AddDefine('cpu32');
  1577. TestTokens([tkconst,tkIdentifier,tkEqual,tkString,tkSemicolon,tkbegin,tkend,tkDot],
  1578. 'const platform = '+LineEnding
  1579. +'{$ifc defined cpu32} ''x86'''+LineEnding
  1580. +'{$elseif defined(cpu64)} 1 '+LineEnding
  1581. +'{$else} {$error unknown platform} {$endc};'+LineEnding
  1582. +'begin end.',True,False);
  1583. end;
  1584. procedure TTestScanner.TestIFCNotDefined;
  1585. begin
  1586. FScanner.SkipWhiteSpace:=True;
  1587. FScanner.SkipComments:=True;
  1588. FScanner.AddDefine('cpu32');
  1589. TestTokens([tkconst,tkIdentifier,tkEqual,tkNumber,tkSemicolon,tkbegin,tkend,tkDot],
  1590. 'const platform = '+LineEnding
  1591. +'{$ifc not defined cpu32} ''x86'''+LineEnding
  1592. +'{$else} 1 '+LineEnding
  1593. +'{$endc};'+LineEnding
  1594. +'begin end.',True,False);
  1595. end;
  1596. procedure TTestScanner.TestIFCAndDefined;
  1597. begin
  1598. FScanner.SkipWhiteSpace:=True;
  1599. FScanner.SkipComments:=True;
  1600. FScanner.AddDefine('cpu32');
  1601. FScanner.AddDefine('alpha');
  1602. TestTokens([tkconst,tkIdentifier,tkEqual,tkstring,tkSemicolon,tkbegin,tkend,tkDot],
  1603. 'const platform = '+LineEnding
  1604. +'{$ifc defined cpu32 and defined alpha} ''x86'''+LineEnding
  1605. +'{$else} 1 '+LineEnding
  1606. +'{$endc};'+LineEnding
  1607. +'begin end.',True,False);
  1608. end;
  1609. procedure TTestScanner.TestIFCFalse;
  1610. begin
  1611. FScanner.SkipWhiteSpace:=True;
  1612. FScanner.SkipComments:=True;
  1613. FScanner.AddDefine('cpu32');
  1614. FScanner.AddDefine('alpha');
  1615. FScanner.AddMacro('MY','FALSE');
  1616. TestTokens([tkconst,tkIdentifier,tkEqual,tkNumber,tkSemicolon,tkbegin,tkend,tkDot],
  1617. 'const platform = '+LineEnding
  1618. +'{$IFC MY} ''x86'''+LineEnding
  1619. +'{$else} 1 '+LineEnding
  1620. +'{$endc};'+LineEnding
  1621. +'begin end.',True,False);
  1622. end;
  1623. procedure TTestScanner.TestModeSwitch;
  1624. Const
  1625. PlusMinus = [' ','+','-'];
  1626. Var
  1627. M : TModeSwitch;
  1628. C : Char;
  1629. begin
  1630. For M in TModeSwitch do
  1631. for C in PlusMinus do
  1632. if SModeSwitchNames[M]<>'' then
  1633. begin
  1634. Scanner.CurrentModeSwitches:=[];
  1635. NewSource('{$MODESWITCH '+SModeSwitchNames[M]+C+'}');
  1636. While not (Scanner.FetchToken=tkEOF) do;
  1637. if C in [' ','+'] then
  1638. AssertTrue(SModeSwitchNames[M]+C+' sets '+GetEnumName(TypeInfo(TModeSwitch),Ord(M)),M in Scanner.CurrentModeSwitches)
  1639. else
  1640. AssertFalse(SModeSwitchNames[M]+C+' removes '+GetEnumName(TypeInfo(TModeSwitch),Ord(M)),M in Scanner.CurrentModeSwitches);
  1641. end;
  1642. end;
  1643. procedure TTestScanner.TestOperatorIdentifier;
  1644. begin
  1645. Scanner.SetNonToken(tkoperator);
  1646. TestToken(tkidentifier,'operator',True);
  1647. end;
  1648. procedure TTestScanner.TestUTF8BOM;
  1649. begin
  1650. DoTestToken(tkLineEnding,#$EF+#$BB+#$BF);
  1651. end;
  1652. procedure TTestScanner.TestBooleanSwitch;
  1653. begin
  1654. Scanner.CurrentBoolSwitches:=[bsHints];
  1655. // end space intentional.
  1656. NewSource('{$HINTS OFF }');
  1657. While not (Scanner.FetchToken=tkEOF) do;
  1658. AssertFalse('Hints off',bshints in Scanner.CurrentBoolSwitches);
  1659. end;
  1660. procedure TTestScanner.TestLinkLibSimple;
  1661. begin
  1662. FScanner.OnLinkLib:=@DoLinkLib;
  1663. // DoTestToken because we don't want to change casing
  1664. DoTestToken(tkComment,'{$LINKLIB myfile.js}');
  1665. AssertEquals('Library name','myfile.js',LibName);
  1666. AssertEquals('Library alias','myfile',LibAlias);
  1667. AssertEquals('Library options','',LibOptions);
  1668. end;
  1669. procedure TTestScanner.TestLinkLibAlias;
  1670. begin
  1671. FScanner.OnLinkLib:=@DoLinkLib;
  1672. // DoTestToken because we don't want to change casing
  1673. DoTestToken(tkComment,'{$LINKLIB myfile.js MyLib}');
  1674. AssertEquals('Library name','myfile.js',LibName);
  1675. AssertEquals('Library alias','MyLib',LibAlias);
  1676. AssertEquals('Library options','',LibOptions);
  1677. end;
  1678. procedure TTestScanner.TestLinkLibDefaultAlias;
  1679. begin
  1680. FScanner.OnLinkLib:=@DoLinkLib;
  1681. // DoTestToken because we don't want to change casing
  1682. DoTestToken(tkComment,'{$LINKLIB my-file.min.js}');
  1683. AssertEquals('Library name','my-file.min.js',LibName);
  1684. AssertEquals('Library alias','my_file_min',LibAlias);
  1685. AssertEquals('Library options','',LibOptions);
  1686. end;
  1687. procedure TTestScanner.TestLinkLibDefaultAliasStrip;
  1688. begin
  1689. FScanner.OnLinkLib:=@DoLinkLib;
  1690. // DoTestToken because we don't want to change casing
  1691. DoTestToken(tkComment,'{$LINKLIB ../solong/my-file.min.js}');
  1692. AssertEquals('Library name','../solong/my-file.min.js',LibName);
  1693. AssertEquals('Library alias','my_file_min',LibAlias);
  1694. AssertEquals('Library options','',LibOptions);
  1695. end;
  1696. procedure TTestScanner.TestLinkLibOptions;
  1697. begin
  1698. FScanner.OnLinkLib:=@DoLinkLib;
  1699. // DoTestToken because we don't want to change casing
  1700. DoTestToken(tkComment,'{$LINKLIB ../solong/my-file.min.js MyFile opt1, opt2 }');
  1701. AssertEquals('Library name','../solong/my-file.min.js',LibName);
  1702. AssertEquals('Library alias','MyFile',LibAlias);
  1703. AssertEquals('Library options','opt1, opt2',LibOptions);
  1704. end;
  1705. initialization
  1706. RegisterTests([TTestTokenFinder,TTestStreamLineReader,TTestScanner]);
  1707. end.