dotest.pp 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452
  1. {
  2. This file is part of the Free Pascal test suite.
  3. Copyright (c) 1999-2002 by the Free Pascal development team.
  4. This program makes the compilation and
  5. execution of individual test sources.
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {$H+}
  13. {$goto on}
  14. program dotest;
  15. uses
  16. dos,
  17. {$ifdef macos}
  18. macutils,
  19. {$endif}
  20. teststr,
  21. testu,
  22. redir,
  23. bench,
  24. classes;
  25. {$ifdef go32v2}
  26. {$define LIMIT83FS}
  27. {$endif}
  28. {$ifdef os2}
  29. {$define LIMIT83FS}
  30. {$endif}
  31. type
  32. tcompinfo = (compver,comptarget,compcpu);
  33. tdelexecutable = (deBefore, deAfter);
  34. tdelexecutables = set of tdelexecutable;
  35. const
  36. ObjExt='o';
  37. PPUExt='ppu';
  38. {$ifdef UNIX}
  39. ExeExt='';
  40. {$else UNIX}
  41. {$ifdef MACOS}
  42. ExeExt='';
  43. {$else MACOS}
  44. ExeExt='exe';
  45. {$endif MACOS}
  46. {$endif UNIX}
  47. DefaultTimeout=60;
  48. var
  49. Config : TConfig;
  50. CompilerLogFile,
  51. ExeLogFile,
  52. LongLogfile,
  53. FailLogfile,
  54. RTLUnitsDir,
  55. TestOutputDir,
  56. OutputDir : string;
  57. CompilerBin,
  58. CompilerCPU,
  59. CompilerTarget,
  60. CompilerVersion,
  61. DefaultCompilerCPU,
  62. DefaultCompilerTarget,
  63. DefaultCompilerVersion : string;
  64. PPFile : TStringList;
  65. PPFileInfo : TStringList;
  66. TestName : string;
  67. Current : longint;
  68. const
  69. DoGraph : boolean = false;
  70. DoInteractive : boolean = false;
  71. DoExecute : boolean = false;
  72. DoKnown : boolean = false;
  73. DoAll : boolean = false;
  74. DoUsual : boolean = true;
  75. TargetDir : string = '';
  76. BenchmarkInfo : boolean = false;
  77. ExtraCompilerOpts : string = '';
  78. DelExecutable : TDelExecutables = [];
  79. RemoteAddr : string = '';
  80. RemotePath : string = '/tmp';
  81. RemotePara : string = '';
  82. rshprog : string = 'rsh';
  83. rcpprog : string = 'rcp';
  84. rquote : char = '''';
  85. UseTimeout : boolean = false;
  86. emulatorname : string = '';
  87. { Constants used in IsAbsolute function }
  88. TargetHasDosStyleDirectories : boolean = false;
  89. TargetAmigaLike : boolean = false;
  90. TargetIsMacOS : boolean = false;
  91. { Set the three constants above according to
  92. the current target }
  93. procedure SetTargetDirectoriesStyle;
  94. var
  95. LTarget : string;
  96. begin
  97. LTarget := lowercase(CompilerTarget);
  98. TargetHasDosStyleDirectories :=
  99. (LTarget='go32v2') or
  100. (LTarget='win32') or
  101. (LTarget='win64') or
  102. (LTarget='watcom') or
  103. (LTarget='os2');
  104. TargetAmigaLike:=
  105. (LTarget='amiga') or
  106. (LTarget='morphos');
  107. TargetIsMacOS:=
  108. (LTarget='macos');
  109. end;
  110. { extracted from rtl/macos/macutils.inc }
  111. function IsMacFullPath (const path: string): Boolean;
  112. begin
  113. if Pos(':', path) = 0 then {its partial}
  114. IsMacFullPath := false
  115. else if path[1] = ':' then
  116. IsMacFullPath := false
  117. else
  118. IsMacFullPath := true
  119. end;
  120. Function IsAbsolute (Const F : String) : boolean;
  121. {
  122. Returns True if the name F is a absolute file name
  123. }
  124. begin
  125. IsAbsolute:=false;
  126. if TargetHasDosStyleDirectories then
  127. begin
  128. if (F[1]='/') or (F[1]='\') then
  129. IsAbsolute:=true;
  130. if (Length(F)>2) and (F[2]=':') and ((F[3]='\') or (F[3]='/')) then
  131. IsAbsolute:=true;
  132. end
  133. else if TargetAmigaLike then
  134. begin
  135. if (length(F)>0) and (Pos(':',F) <> 0) then
  136. IsAbsolute:=true;
  137. end
  138. else if TargetIsMacOS then
  139. begin
  140. IsAbsolute:=IsMacFullPath(F);
  141. end
  142. { generic case }
  143. else if (F[1]='/') then
  144. IsAbsolute:=true;
  145. end;
  146. Function FileExists (Const F : String) : Boolean;
  147. {
  148. Returns True if the file exists, False if not.
  149. }
  150. Var
  151. info : searchrec;
  152. begin
  153. FindFirst (F,anyfile,Info);
  154. FileExists:=DosError=0;
  155. FindClose (Info);
  156. end;
  157. Function PathExists (Const F : String) : Boolean;
  158. {
  159. Returns True if the file exists, False if not.
  160. }
  161. Var
  162. info : searchrec;
  163. begin
  164. FindFirst (F,anyfile,Info);
  165. PathExists:=(DosError=0) and (Info.Attr and Directory=Directory);
  166. FindClose (Info);
  167. end;
  168. function ToStr(l:longint):string;
  169. var
  170. s : string;
  171. begin
  172. Str(l,s);
  173. ToStr:=s;
  174. end;
  175. function ToStrZero(l:longint;nbzero : byte):string;
  176. var
  177. s : string;
  178. begin
  179. Str(l,s);
  180. while length(s)<nbzero do
  181. s:='0'+s;
  182. ToStrZero:=s;
  183. end;
  184. function trimspace(const s:string):string;
  185. var
  186. i,j : longint;
  187. begin
  188. i:=length(s);
  189. while (i>0) and (s[i] in [#9,' ']) do
  190. dec(i);
  191. j:=1;
  192. while (j<i) and (s[j] in [#9,' ']) do
  193. inc(j);
  194. trimspace:=Copy(s,j,i-j+1);
  195. end;
  196. function IsInList(const entry,list:string):boolean;
  197. var
  198. i,istart : longint;
  199. begin
  200. IsInList:=false;
  201. i:=0;
  202. while (i<length(list)) do
  203. begin
  204. { Find list item }
  205. istart:=i+1;
  206. while (i<length(list)) and
  207. (list[i+1]<>',') do
  208. inc(i);
  209. if Upcase(entry)=Upcase(TrimSpace(Copy(list,istart,i-istart+1))) then
  210. begin
  211. IsInList:=true;
  212. exit;
  213. end;
  214. { skip , }
  215. inc(i);
  216. end;
  217. end;
  218. procedure SetPPFileInfo;
  219. Var
  220. info : searchrec;
  221. dt : DateTime;
  222. begin
  223. FindFirst (PPFile[current],anyfile,Info);
  224. If DosError=0 then
  225. begin
  226. UnpackTime(info.time,dt);
  227. PPFileInfo.Insert(current,PPFile[current]+' '+ToStr(dt.year)+'/'+ToStrZero(dt.month,2)+'/'+
  228. ToStrZero(dt.day,2)+' '+ToStrZero(dt.Hour,2)+':'+ToStrZero(dt.min,2)+':'+ToStrZero(dt.sec,2));
  229. end
  230. else
  231. PPFileInfo.Insert(current,PPFile[current]);
  232. FindClose (Info);
  233. end;
  234. function SplitPath(const s:string):string;
  235. var
  236. i : longint;
  237. begin
  238. i:=Length(s);
  239. while (i>0) and not(s[i] in ['/','\'{$IFDEF MACOS},':'{$ENDIF}]) do
  240. dec(i);
  241. SplitPath:=Copy(s,1,i);
  242. end;
  243. Function SplitFileName(const s:string):string;
  244. var
  245. p : dirstr;
  246. n : namestr;
  247. e : extstr;
  248. begin
  249. FSplit(s,p,n,e);
  250. SplitFileName:=n+e;
  251. end;
  252. function ForceExtension(Const HStr,ext:String):String;
  253. {
  254. Return a filename which certainly has the extension ext
  255. }
  256. var
  257. j : longint;
  258. begin
  259. j:=length(Hstr);
  260. while (j>0) and (Hstr[j]<>'.') do
  261. dec(j);
  262. if j=0 then
  263. j:=length(Hstr)+1;
  264. if Ext<>'' then
  265. ForceExtension:=Copy(Hstr,1,j-1)+'.'+Ext
  266. else
  267. ForceExtension:=Copy(Hstr,1,j-1);
  268. end;
  269. procedure mkdirtree(const s:string);
  270. var
  271. hs : string;
  272. begin
  273. if s='' then
  274. exit;
  275. if s[length(s)] in ['\','/'{$IFDEF MACOS},':'{$ENDIF}] then
  276. hs:=Copy(s,1,length(s)-1)
  277. else
  278. hs:=s;
  279. if not PathExists(hs) then
  280. begin
  281. { Try parent first }
  282. mkdirtree(SplitPath(hs));
  283. { make this dir }
  284. Verbose(V_Debug,'Making Directory '+s);
  285. {$I-}
  286. mkdir(s);
  287. {$I+}
  288. ioresult;
  289. end;
  290. end;
  291. Function RemoveFile(const f:string):boolean;
  292. var
  293. g : file;
  294. begin
  295. assign(g,f);
  296. {$I-}
  297. erase(g);
  298. {$I+}
  299. RemoveFile:=(ioresult=0);
  300. end;
  301. function Copyfile(const fn1,fn2:string;append:boolean) : longint;
  302. const
  303. bufsize = 16384;
  304. var
  305. f,g : file;
  306. addsize,
  307. i : longint;
  308. buf : pointer;
  309. begin
  310. if Append then
  311. Verbose(V_Debug,'Appending '+fn1+' to '+fn2)
  312. else
  313. Verbose(V_Debug,'Copying '+fn1+' to '+fn2);
  314. assign(f,fn1);
  315. assign(g,fn2);
  316. {$I-}
  317. reset(f,1);
  318. {$I+}
  319. addsize:=0;
  320. if ioresult<>0 then
  321. Verbose(V_Error,'Can''t open '+fn1);
  322. if append then
  323. begin
  324. {$I-}
  325. reset(g,1);
  326. {$I+}
  327. if ioresult<>0 then
  328. append:=false
  329. else
  330. seek(g,filesize(g));
  331. end;
  332. if not append then
  333. begin
  334. {$I-}
  335. rewrite(g,1);
  336. {$I+}
  337. if ioresult<>0 then
  338. Verbose(V_Error,'Can''t open '+fn2+' for output');
  339. end;
  340. getmem(buf,bufsize);
  341. repeat
  342. blockread(f,buf^,bufsize,i);
  343. blockwrite(g,buf^,i);
  344. addsize:=addsize+i;
  345. until i<bufsize;
  346. freemem(buf,bufsize);
  347. close(f);
  348. close(g);
  349. CopyFile:=addsize;
  350. end;
  351. procedure AddLog(const logfile,s:string);
  352. var
  353. t : text;
  354. begin
  355. assign(t,logfile);
  356. {$I-}
  357. append(t);
  358. {$I+}
  359. if ioresult<>0 then
  360. begin
  361. {$I-}
  362. rewrite(t);
  363. {$I+}
  364. if ioresult<>0 then
  365. Verbose(V_Abort,'Can''t append to '+logfile);
  366. end;
  367. writeln(t,s);
  368. close(t);
  369. end;
  370. function GetCompilerInfo(c:tcompinfo):boolean;
  371. function GetToken(var s:string):string;
  372. var
  373. i : longint;
  374. begin
  375. i:=pos(' ',s);
  376. if i=0 then
  377. i:=length(s)+1;
  378. GetToken:=Copy(s,1,i-1);
  379. Delete(s,1,i);
  380. end;
  381. var
  382. t : text;
  383. hs : string;
  384. begin
  385. GetCompilerInfo:=false;
  386. { Try to get all information in one call, this is
  387. supported in 1.1. Older compilers 1.0.x will only
  388. return the first info }
  389. case c of
  390. compver :
  391. begin
  392. if DefaultCompilerVersion<>'' then
  393. begin
  394. GetCompilerInfo:=true;
  395. exit;
  396. end;
  397. hs:='-iVTPTO';
  398. end;
  399. compcpu :
  400. begin
  401. if DefaultCompilerCPU<>'' then
  402. begin
  403. GetCompilerInfo:=true;
  404. exit;
  405. end;
  406. hs:='-iTPTOV';
  407. end;
  408. comptarget :
  409. begin
  410. if DefaultCompilerTarget<>'' then
  411. begin
  412. GetCompilerInfo:=true;
  413. exit;
  414. end;
  415. hs:='-iTOTPV';
  416. end;
  417. end;
  418. ExecuteRedir(CompilerBin,hs,'','out','');
  419. assign(t,'out');
  420. {$I-}
  421. reset(t);
  422. readln(t,hs);
  423. close(t);
  424. erase(t);
  425. {$I+}
  426. if ioresult<>0 then
  427. Verbose(V_Error,'Can''t get Compiler Info')
  428. else
  429. begin
  430. Verbose(V_Debug,'Retrieved Compiler Info: "'+hs+'"');
  431. case c of
  432. compver :
  433. begin
  434. DefaultCompilerVersion:=GetToken(hs);
  435. DefaultCompilerCPU:=GetToken(hs);
  436. DefaultCompilerTarget:=GetToken(hs);
  437. end;
  438. compcpu :
  439. begin
  440. DefaultCompilerCPU:=GetToken(hs);
  441. DefaultCompilerTarget:=GetToken(hs);
  442. DefaultCompilerVersion:=GetToken(hs);
  443. end;
  444. comptarget :
  445. begin
  446. DefaultCompilerTarget:=GetToken(hs);
  447. DefaultCompilerCPU:=GetToken(hs);
  448. DefaultCompilerVersion:=GetToken(hs);
  449. end;
  450. end;
  451. GetCompilerInfo:=true;
  452. end;
  453. end;
  454. function GetCompilerVersion:boolean;
  455. begin
  456. if CompilerVersion='' then
  457. begin
  458. GetCompilerVersion:=GetCompilerInfo(compver);
  459. CompilerVersion:=DefaultCompilerVersion;
  460. end
  461. else
  462. GetCompilerVersion:=true;
  463. if GetCompilerVersion then
  464. Verbose(V_Debug,'Compiler Version: "'+CompilerVersion+'"');
  465. end;
  466. function GetCompilerCPU:boolean;
  467. begin
  468. if CompilerCPU='' then
  469. begin
  470. GetCompilerCPU:=GetCompilerInfo(compcpu);
  471. CompilerCPU:=DefaultCompilerCPU;
  472. end
  473. else
  474. GetCompilerCPU:=true;
  475. if GetCompilerCPU then
  476. Verbose(V_Debug,'Compiler CPU: "'+CompilerCPU+'"');
  477. end;
  478. function GetCompilerTarget:boolean;
  479. begin
  480. if CompilerTarget='' then
  481. begin
  482. GetCompilerTarget:=GetCompilerInfo(comptarget);
  483. CompilerTarget:=DefaultCompilerTarget;
  484. end
  485. else
  486. GetCompilerTarget:=true;
  487. if GetCompilerTarget then
  488. Verbose(V_Debug,'Compiler Target: "'+CompilerTarget+'"');
  489. end;
  490. function CompilerFullTarget:string;
  491. begin
  492. CompilerFullTarget:=CompilerCPU+'-'+CompilerTarget;
  493. end;
  494. function OutputFileName(Const s,ext:String):String;
  495. begin
  496. {$ifndef macos}
  497. OutputFileName:=OutputDir+'/'+ForceExtension(s,ext);
  498. {$else macos}
  499. OutputFileName:=ConcatMacPath(OutputDir,ForceExtension(s,ext));
  500. {$endif macos}
  501. end;
  502. function TestOutputFileName(Const s,ext:String):String;
  503. begin
  504. {$ifndef macos}
  505. TestOutputFileName:=TestOutputDir+'/'+ForceExtension(SplitFileName(s),ext);
  506. {$else macos}
  507. TestOutputFileName:=ConcatMacPath(TestOutputDir,ForceExtension(SplitFileName(s),ext));
  508. {$endif macos}
  509. end;
  510. function ExitWithInternalError(const OutName:string):boolean;
  511. var
  512. t : text;
  513. s : string;
  514. begin
  515. ExitWithInternalError:=false;
  516. { open logfile }
  517. assign(t,Outname);
  518. {$I-}
  519. reset(t);
  520. {$I+}
  521. if ioresult<>0 then
  522. exit;
  523. while not eof(t) do
  524. begin
  525. readln(t,s);
  526. if pos('Fatal: Internal error ',s)>0 then
  527. begin
  528. ExitWithInternalError:=true;
  529. break;
  530. end;
  531. end;
  532. close(t);
  533. end;
  534. function RunCompiler:boolean;
  535. var
  536. args,
  537. wpoargs : string;
  538. passnr,
  539. passes : longint;
  540. execres : boolean;
  541. EndTicks,
  542. StartTicks : int64;
  543. begin
  544. RunCompiler:=false;
  545. args:='-n -T'+CompilerTarget+' -Fu'+RTLUnitsDir;
  546. args:=args+' -FE'+TestOutputDir;
  547. {$ifdef macos}
  548. args:=args+' -WT '; {tests should be compiled as MPWTool}
  549. {$endif macos}
  550. if ExtraCompilerOpts<>'' then
  551. args:=args+ExtraCompilerOpts;
  552. {$ifdef unix}
  553. { Add runtime library path to current dir to find .so files }
  554. if Config.NeedLibrary then
  555. {$ifndef darwin}
  556. args:=args+' -Fl'+TestOutputDir+' ''-k-rpath .''';
  557. {$else darwin}
  558. args:=args+' -Fl'+TestOutputDir;
  559. {$endif darwin}
  560. {$endif unix}
  561. if Config.NeedOptions<>'' then
  562. args:=args+' '+Config.NeedOptions;
  563. wpoargs:='';
  564. if (Config.WpoPasses=0) or
  565. (Config.WpoParas='') then
  566. passes:=1
  567. else
  568. passes:=config.wpopasses+1;
  569. args:=args+' '+PPFile[current];
  570. for passnr:=1 to passes do
  571. begin
  572. if (passes>1) then
  573. begin
  574. wpoargs:=' -OW'+config.wpoparas+' -FW'+TestOutputFileName(PPFile[current],'wp'+tostr(passnr));
  575. if (passnr>1) then
  576. wpoargs:=wpoargs+' -Ow'+config.wpoparas+' -Fw'+TestOutputFileName(PPFile[current],'wp'+tostr(passnr-1));
  577. end;
  578. Verbose(V_Debug,'Executing '+compilerbin+' '+args+wpoargs);
  579. { also get the output from as and ld that writes to stderr sometimes }
  580. StartTicks:=GetMicroSTicks;
  581. {$ifndef macos}
  582. execres:=ExecuteRedir(CompilerBin,args+wpoargs,'',CompilerLogFile,'stdout');
  583. {$else macos}
  584. {Due to that Toolserver is not reentrant, we have to asm and link via script.}
  585. execres:=ExecuteRedir(CompilerBin,'-s '+args+wpoargs,'',CompilerLogFile,'stdout');
  586. if execres then
  587. execres:=ExecuteRedir(TestOutputDir + ':ppas','','',CompilerLogFile,'stdout');
  588. {$endif macos}
  589. EndTicks:=GetMicroSTicks;
  590. Verbose(V_Debug,'Exitcode '+ToStr(ExecuteResult));
  591. if BenchmarkInfo then
  592. begin
  593. Verbose(V_Normal,'Compilation took '+ToStr(EndTicks-StartTicks)+' us');
  594. end;
  595. { Error during execution? }
  596. if (not execres) and (ExecuteResult=0) then
  597. begin
  598. AddLog(FailLogFile,TestName);
  599. AddLog(ResLogFile,failed_to_compile+PPFileInfo[current]);
  600. AddLog(LongLogFile,line_separation);
  601. AddLog(LongLogFile,failed_to_compile+PPFileInfo[current]);
  602. if CopyFile(CompilerLogFile,LongLogFile,true)=0 then
  603. AddLog(LongLogFile,'IOStatus'+ToStr(IOStatus));
  604. { avoid to try again }
  605. AddLog(ExeLogFile,failed_to_compile+PPFileInfo[current]);
  606. Verbose(V_Warning,'IOStatus: '+ToStr(IOStatus));
  607. exit;
  608. end;
  609. { Check for internal error }
  610. if ExitWithInternalError(CompilerLogFile) then
  611. begin
  612. AddLog(FailLogFile,TestName);
  613. if Config.Note<>'' then
  614. AddLog(FailLogFile,Config.Note);
  615. AddLog(ResLogFile,failed_to_compile+PPFileInfo[current]+' internalerror generated');
  616. AddLog(LongLogFile,line_separation);
  617. AddLog(LongLogFile,failed_to_compile+PPFileInfo[current]);
  618. if Config.Note<>'' then
  619. AddLog(LongLogFile,Config.Note);
  620. if CopyFile(CompilerLogFile,LongLogFile,true)=0 then
  621. AddLog(LongLogFile,'Internal error in compiler');
  622. { avoid to try again }
  623. AddLog(ExeLogFile,'Failed to compile '+PPFileInfo[current]);
  624. Verbose(V_Warning,'Internal error in compiler');
  625. exit;
  626. end;
  627. end;
  628. { Should the compile fail ? }
  629. if Config.ShouldFail then
  630. begin
  631. if ExecuteResult<>0 then
  632. begin
  633. AddLog(ResLogFile,success_compilation_failed+PPFileInfo[current]);
  634. { avoid to try again }
  635. AddLog(ExeLogFile,success_compilation_failed+PPFileInfo[current]);
  636. RunCompiler:=true;
  637. end
  638. else
  639. begin
  640. AddLog(FailLogFile,TestName);
  641. if Config.Note<>'' then
  642. AddLog(FailLogFile,Config.Note);
  643. AddLog(ResLogFile,failed_compilation_successful+PPFileInfo[current]);
  644. AddLog(LongLogFile,line_separation);
  645. AddLog(LongLogFile,failed_compilation_successful+PPFileInfo[current]);
  646. { avoid to try again }
  647. AddLog(ExeLogFile,failed_compilation_successful+PPFileInfo[current]);
  648. if Config.Note<>'' then
  649. AddLog(LongLogFile,Config.Note);
  650. CopyFile(CompilerLogFile,LongLogFile,true);
  651. end;
  652. end
  653. else
  654. begin
  655. if (ExecuteResult<>0) and
  656. (((Config.KnownCompileNote<>'') and (Config.KnownCompileError=0)) or
  657. ((Config.KnownCompileError<>0) and (ExecuteResult=Config.KnownCompileError))) then
  658. begin
  659. AddLog(FailLogFile,TestName+known_problem+Config.KnownCompileNote);
  660. AddLog(ResLogFile,failed_to_run+PPFileInfo[current]+known_problem+Config.KnownCompileNote);
  661. AddLog(LongLogFile,line_separation);
  662. AddLog(LongLogFile,known_problem+Config.KnownCompileNote);
  663. AddLog(LongLogFile,failed_to_compile+PPFileInfo[current]+' ('+ToStr(ExecuteResult)+')');
  664. if Copyfile(CompilerLogFile,LongLogFile,true)=0 then
  665. AddLog(LongLogFile,known_problem+'exitcode: '+ToStr(ExecuteResult));
  666. Verbose(V_Warning,known_problem+'exitcode: '+ToStr(ExecuteResult));
  667. end
  668. else if ExecuteResult<>0 then
  669. begin
  670. AddLog(FailLogFile,TestName);
  671. if Config.Note<>'' then
  672. AddLog(FailLogFile,Config.Note);
  673. AddLog(ResLogFile,failed_to_compile+PPFileInfo[current]);
  674. AddLog(LongLogFile,line_separation);
  675. AddLog(LongLogFile,failed_to_compile+PPFileInfo[current]);
  676. if Config.Note<>'' then
  677. AddLog(LongLogFile,Config.Note);
  678. if CopyFile(CompilerLogFile,LongLogFile,true)=0 then
  679. AddLog(LongLogFile,'Exitcode: '+ToStr(ExecuteResult)+' (expected 0)');
  680. { avoid to try again }
  681. AddLog(ExeLogFile,failed_to_compile+PPFileInfo[current]);
  682. Verbose(V_Warning,'Exitcode: '+ToStr(ExecuteResult)+' (expected 0)');
  683. end
  684. else
  685. begin
  686. AddLog(ResLogFile,successfully_compiled+PPFileInfo[current]);
  687. RunCompiler:=true;
  688. end;
  689. end;
  690. end;
  691. function CheckTestExitCode(const OutName:string):boolean;
  692. var
  693. t : text;
  694. s : string;
  695. i,code : integer;
  696. begin
  697. CheckTestExitCode:=false;
  698. { open logfile }
  699. assign(t,Outname);
  700. {$I-}
  701. reset(t);
  702. {$I+}
  703. if ioresult<>0 then
  704. exit;
  705. while not eof(t) do
  706. begin
  707. readln(t,s);
  708. i:=pos('TestExitCode: ',s);
  709. if i>0 then
  710. begin
  711. delete(s,1,i+14-1);
  712. val(s,ExecuteResult,code);
  713. if code=0 then;
  714. CheckTestExitCode:=true;
  715. break;
  716. end;
  717. end;
  718. close(t);
  719. end;
  720. function RunExecutable:boolean;
  721. const
  722. MaxTrials = 5;
  723. {$ifdef unix}
  724. CurrDir = './';
  725. {$else}
  726. CurrDir = '';
  727. {$endif}
  728. var
  729. s,
  730. OldDir,
  731. FullExeLogFile,
  732. TestRemoteExe,
  733. TestExe : string;
  734. LocalFile, RemoteFile: string;
  735. LocalPath, LTarget : string;
  736. execcmd,
  737. pref : string;
  738. execres : boolean;
  739. index : integer;
  740. EndTicks,
  741. StartTicks : int64;
  742. function ExecuteRemote(const prog,args:string):boolean;
  743. var
  744. Trials : longint;
  745. begin
  746. Verbose(V_Debug,'RemoteExecuting '+Prog+' '+args);
  747. StartTicks:=GetMicroSTicks;
  748. ExecuteRemote:=false;
  749. Trials:=0;
  750. While (Trials<MaxTrials) and not ExecuteRemote do
  751. begin
  752. inc(Trials);
  753. ExecuteRemote:=ExecuteRedir(prog,args,'',EXELogFile,'stdout');
  754. end;
  755. if Trials>1 then
  756. Verbose(V_Debug,'Done in '+tostr(trials)+' trials');
  757. EndTicks:=GetMicroSTicks;
  758. end;
  759. function ExecuteEmulated(const prog,args:string):boolean;
  760. begin
  761. Verbose(V_Debug,'EmulatorExecuting '+Prog+' '+args);
  762. StartTicks:=GetMicroSTicks;
  763. ExecuteEmulated:=ExecuteRedir(prog,args,'',FullExeLogFile,'stdout');
  764. EndTicks:=GetMicroSTicks;
  765. end;
  766. label
  767. done;
  768. begin
  769. RunExecutable:=false;
  770. execres:=true;
  771. { when remote testing, leave extension away,
  772. but not for go32v2, win32 or win64 as cygwin ssh
  773. will remove the .exe in that case }
  774. LTarget := lowercase(CompilerTarget);
  775. if (RemoteAddr='') or
  776. (rcpprog='pscp') or
  777. (LTarget='go32v2') or
  778. (LTarget='win32') or
  779. (LTarget='win64') then
  780. TestExe:=OutputFileName(PPFile[current],ExeExt)
  781. else
  782. TestExe:=OutputFileName(PPFile[current],'');
  783. if EmulatorName<>'' then
  784. begin
  785. { Get full name out log file, because we change the directory during
  786. execution }
  787. FullExeLogFile:=FExpand(EXELogFile);
  788. {$I-}
  789. GetDir(0,OldDir);
  790. ChDir(TestOutputDir);
  791. {$I+}
  792. ioresult;
  793. s:=CurrDir+SplitFileName(TestExe);
  794. execres:=ExecuteEmulated(EmulatorName,s);
  795. {$I-}
  796. ChDir(OldDir);
  797. {$I+}
  798. end
  799. else if RemoteAddr<>'' then
  800. begin
  801. { We don't want to create subdirs, remove paths from the test }
  802. TestRemoteExe:=RemotePath+'/'+SplitFileName(TestExe);
  803. if deBefore in DelExecutable then
  804. ExecuteRemote(rshprog,RemotePara+' '+RemoteAddr+' rm -f '+TestRemoteExe);
  805. execres:=ExecuteRemote(rcpprog,RemotePara+' '+TestExe+' '+RemoteAddr+':'+TestRemoteExe);
  806. if not execres then
  807. begin
  808. Verbose(V_normal, 'Could not copy executable '+TestExe);
  809. goto done;
  810. end;
  811. s:=Config.Files;
  812. if length(s) > 0 then
  813. begin
  814. LocalPath:=SplitPath(PPFile[current]);
  815. if Length(LocalPath) > 0 then
  816. LocalPath:=LocalPath+'/';
  817. repeat
  818. index:=pos(' ',s);
  819. if index=0 then
  820. LocalFile:=s
  821. else
  822. LocalFile:=copy(s,1,index-1);
  823. RemoteFile:=RemotePath+'/'+SplitFileName(LocalFile);
  824. LocalFile:=LocalPath+LocalFile;
  825. if DoVerbose and (rcpprog='pscp') then
  826. pref:='-v '
  827. else
  828. pref:='';
  829. execres:=ExecuteRemote(rcpprog,pref+RemotePara+' '+LocalFile+' '+RemoteAddr+':'+RemoteFile);
  830. if not execres then
  831. begin
  832. Verbose(V_normal, 'Could not copy required file '+LocalFile);
  833. goto done;
  834. end;
  835. if index=0 then
  836. break;
  837. s:=copy(s,index+1,length(s)-index);
  838. until false;
  839. end;
  840. { rsh doesn't pass the exitcode, use a second command to print the exitcode
  841. on the remoteshell to stdout }
  842. if DoVerbose and (rshprog='plink') then
  843. execcmd:='-v '
  844. else
  845. execcmd:='';
  846. execcmd:=execcmd+RemotePara+' '+RemoteAddr+' '+rquote+
  847. 'chmod 755 '+TestRemoteExe+
  848. ' ; cd '+RemotePath+' ; ';
  849. if UseTimeout then
  850. begin
  851. execcmd:=execcmd+'timeout -9 ';
  852. if Config.Timeout=0 then
  853. Config.Timeout:=DefaultTimeout;
  854. str(Config.Timeout,s);
  855. execcmd:=execcmd+s;
  856. end;
  857. { as we moved to RemotePath, if path is not absolute
  858. we need to use ./execfilename only }
  859. if not isabsolute(TestRemoteExe) then
  860. execcmd:=execcmd+' ./'+SplitFileName(TestRemoteExe)
  861. else
  862. execcmd:=execcmd+' '+TestRemoteExe;
  863. execcmd:=execcmd+' ; echo "TestExitCode: $?"';
  864. if (deAfter in DelExecutable) and
  865. not Config.NeededAfter then
  866. execcmd:=execcmd+' ; rm -f '+TestRemoteExe;
  867. execcmd:=execcmd+rquote;
  868. execres:=ExecuteRemote(rshprog,execcmd);
  869. { Check for TestExitCode error in output, sets ExecuteResult }
  870. CheckTestExitCode(EXELogFile);
  871. end
  872. else
  873. begin
  874. { Get full name out log file, because we change the directory during
  875. execution }
  876. FullExeLogFile:=FExpand(EXELogFile);
  877. Verbose(V_Debug,'Executing '+TestExe);
  878. {$I-}
  879. GetDir(0,OldDir);
  880. ChDir(TestOutputDir);
  881. {$I+}
  882. ioresult;
  883. { don't redirect interactive and graph programs }
  884. StartTicks:=GetMicroSTicks;
  885. if Config.IsInteractive or Config.UsesGraph then
  886. execres:=ExecuteRedir(CurrDir+SplitFileName(TestExe),'','','','')
  887. else
  888. execres:=ExecuteRedir(CurrDir+SplitFileName(TestExe),'','',FullExeLogFile,'stdout');
  889. EndTicks:=GetMicroSTicks;
  890. {$I-}
  891. ChDir(OldDir);
  892. {$I+}
  893. ioresult;
  894. end;
  895. { Error during execution? }
  896. Verbose(V_Debug,'Exitcode '+ToStr(ExecuteResult));
  897. if BenchmarkInfo then
  898. begin
  899. Verbose(V_Normal,'Execution took '+ToStr(EndTicks-StartTicks)+' us');
  900. end;
  901. done:
  902. if (not execres) and (ExecuteResult=0) then
  903. begin
  904. AddLog(FailLogFile,TestName);
  905. AddLog(ResLogFile,failed_to_run+PPFileInfo[current]);
  906. AddLog(LongLogFile,line_separation);
  907. AddLog(LongLogFile,failed_to_run+PPFileInfo[current]);
  908. if CopyFile(EXELogFile,LongLogFile,true)=0 then
  909. AddLog(LongLogFile,'IOStatus: '+ToStr(IOStatus));
  910. { avoid to try again }
  911. AddLog(ExeLogFile,failed_to_run+PPFileInfo[current]);
  912. Verbose(V_Warning,'IOStatus: '+ToStr(IOStatus));
  913. exit;
  914. end;
  915. if ExecuteResult<>Config.ResultCode then
  916. begin
  917. if (ExecuteResult<>0) and
  918. (ExecuteResult=Config.KnownRunError) then
  919. begin
  920. AddLog(FailLogFile,TestName+known_problem+Config.KnownRunNote);
  921. AddLog(ResLogFile,failed_to_run+PPFileInfo[current]+known_problem+Config.KnownRunNote);
  922. AddLog(LongLogFile,line_separation);
  923. AddLog(LongLogFile,known_problem+Config.KnownRunNote);
  924. AddLog(LongLogFile,failed_to_run+PPFileInfo[current]+' ('+ToStr(ExecuteResult)+')');
  925. if Copyfile(EXELogFile,LongLogFile,true)=0 then
  926. begin
  927. AddLog(LongLogFile,known_problem+'exitcode: '+ToStr(ExecuteResult)+' (expected '+ToStr(Config.ResultCode)+')');
  928. AddLog(ExeLogFile,known_problem+'exitcode: '+ToStr(ExecuteResult)+' (expected '+ToStr(Config.ResultCode)+')');
  929. end;
  930. Verbose(V_Warning,known_problem+'exitcode: '+ToStr(ExecuteResult)+' (expected '+ToStr(Config.ResultCode)+')');
  931. end
  932. else
  933. begin
  934. AddLog(FailLogFile,TestName);
  935. AddLog(ResLogFile,failed_to_run+PPFileInfo[current]);
  936. AddLog(LongLogFile,line_separation);
  937. AddLog(LongLogFile,failed_to_run+PPFileInfo[current]+' ('+ToStr(ExecuteResult)+')');
  938. if Copyfile(EXELogFile,LongLogFile,true)=0 then
  939. begin
  940. AddLog(LongLogFile,'Exitcode: '+ToStr(ExecuteResult)+' (expected '+ToStr(Config.ResultCode)+')');
  941. AddLog(ExeLogFile,'Exitcode: '+ToStr(ExecuteResult)+' (expected '+ToStr(Config.ResultCode)+')');
  942. end;
  943. Verbose(V_Warning,'Exitcode: '+ToStr(ExecuteResult)+' (expected '+ToStr(Config.ResultCode)+')');
  944. end
  945. end
  946. else
  947. begin
  948. AddLog(ResLogFile,successfully_run+PPFileInfo[current]);
  949. RunExecutable:=true;
  950. end;
  951. if (deAfter in DelExecutable) and not Config.NeededAfter then
  952. begin
  953. Verbose(V_Debug,'Deleting executable '+TestExe);
  954. RemoveFile(TestExe);
  955. RemoveFile(ForceExtension(TestExe,ObjExt));
  956. RemoveFile(ForceExtension(TestExe,PPUExt));
  957. end;
  958. end;
  959. procedure getargs;
  960. var
  961. ch : char;
  962. para : string;
  963. i,j : longint;
  964. procedure helpscreen;
  965. begin
  966. writeln('dotest [Options] <File>');
  967. writeln;
  968. writeln('Options can be:');
  969. writeln(' -A include ALL tests');
  970. writeln(' -B delete executable before remote upload');
  971. writeln(' -C<compiler> set compiler to use');
  972. writeln(' -D display execution time');
  973. writeln(' -E execute test also');
  974. writeln(' -G include graph tests');
  975. writeln(' -I include interactive tests');
  976. writeln(' -K include known bug tests');
  977. writeln(' -M<emulator> run the tests using the given emulator');
  978. writeln(' -O use timeout wrapper for (remote) execution');
  979. writeln(' -P<path> path to the tests tree on the remote machine');
  980. writeln(' -R<remote> run the tests remotely with the given rsh/ssh address');
  981. writeln(' -S use ssh instead of rsh');
  982. writeln(' -T[cpu-]<os> run tests for target cpu and os');
  983. writeln(' -U<remotepara>');
  984. writeln(' pass additional parameter to remote program. Multiple -U can be used');
  985. writeln(' -V be verbose');
  986. writeln(' -W use putty compatible file names when testing (plink and pscp)');
  987. writeln(' -X don''t use COMSPEC');
  988. writeln(' -Y<opts> extra options passed to the compiler. Several -Y<opt> can be given.');
  989. writeln(' -Z remove temporary files (executable,ppu,o)');
  990. halt(1);
  991. end;
  992. begin
  993. if exeext<>'' then
  994. CompilerBin:='ppc386.'+exeext
  995. else
  996. CompilerBin:='ppc386';
  997. for i:=1 to paramcount do
  998. begin
  999. para:=Paramstr(i);
  1000. if (para[1]='-') then
  1001. begin
  1002. ch:=Upcase(para[2]);
  1003. delete(para,1,2);
  1004. case ch of
  1005. 'A' :
  1006. begin
  1007. DoGraph:=true;
  1008. DoInteractive:=true;
  1009. DoKnown:=true;
  1010. DoAll:=true;
  1011. end;
  1012. 'B' : Include(DelExecutable,deBefore);
  1013. 'C' : CompilerBin:=Para;
  1014. 'D' : BenchMarkInfo:=true;
  1015. 'E' : DoExecute:=true;
  1016. 'G' : begin
  1017. DoGraph:=true;
  1018. if para='-' then
  1019. DoUsual:=false;
  1020. end;
  1021. 'I' : begin
  1022. DoInteractive:=true;
  1023. if para='-' then
  1024. DoUsual:=false;
  1025. end;
  1026. 'K' : begin
  1027. DoKnown:=true;
  1028. if para='-' then
  1029. DoUsual:=false;
  1030. end;
  1031. 'M' : EmulatorName:=Para;
  1032. 'O' : UseTimeout:=true;
  1033. 'P' : RemotePath:=Para;
  1034. 'R' : RemoteAddr:=Para;
  1035. 'S' :
  1036. begin
  1037. rshprog:='ssh';
  1038. rcpprog:='scp';
  1039. end;
  1040. 'T' :
  1041. begin
  1042. j:=Pos('-',Para);
  1043. if j>0 then
  1044. begin
  1045. CompilerCPU:=Copy(Para,1,j-1);
  1046. CompilerTarget:=Copy(Para,j+1,length(para));
  1047. end
  1048. else
  1049. CompilerTarget:=Para
  1050. end;
  1051. 'U' :
  1052. RemotePara:=RemotePara+' '+Para;
  1053. 'V' : DoVerbose:=true;
  1054. 'W' :
  1055. begin
  1056. rshprog:='plink';
  1057. rcpprog:='pscp';
  1058. rquote:='"';
  1059. end;
  1060. 'X' : UseComSpec:=false;
  1061. 'Y' : ExtraCompilerOpts:= ExtraCompilerOpts +' '+ Para;
  1062. 'Z' : Include(DelExecutable,deAfter);
  1063. end;
  1064. end
  1065. else
  1066. begin
  1067. PPFile.Insert(current,ForceExtension(Para,'pp'));
  1068. inc(current);
  1069. end;
  1070. end;
  1071. if current=0 then
  1072. HelpScreen;
  1073. { disable graph,interactive when running remote }
  1074. if RemoteAddr<>'' then
  1075. begin
  1076. DoGraph:=false;
  1077. DoInteractive:=false;
  1078. end;
  1079. end;
  1080. procedure RunTest;
  1081. var
  1082. PPDir : string;
  1083. Res : boolean;
  1084. begin
  1085. Res:=GetConfig(PPFile[current],Config);
  1086. if Res then
  1087. begin
  1088. Res:=GetCompilerCPU;
  1089. Res:=GetCompilerTarget;
  1090. {$ifndef MACOS}
  1091. RTLUnitsDir:='units/'+{$ifdef LIMIT83FS}CompilerTarget{$else}CompilerFullTarget{$endif};
  1092. {$else MACOS}
  1093. RTLUnitsDir:=':units:'+CompilerFullTarget;
  1094. {$endif MACOS}
  1095. if not PathExists(RTLUnitsDir) then
  1096. Verbose(V_Abort,'Unit path "'+RTLUnitsDir+'" does not exists');
  1097. {$ifndef MACOS}
  1098. OutputDir:='output/'+{$ifdef LIMIT83FS}CompilerTarget{$else}CompilerFullTarget{$endif};
  1099. {$else MACOS}
  1100. OutputDir:=':output:'+CompilerFullTarget;
  1101. {$endif MACOS}
  1102. if not PathExists(OutputDir) then
  1103. Verbose(V_Abort,'Output path "'+OutputDir+'" does not exists');
  1104. { Global log files }
  1105. ResLogFile:=OutputFileName('log','');
  1106. LongLogFile:=OutputFileName('longlog','');
  1107. FailLogFile:=OutputFileName('faillist','');
  1108. { Make subdir in output if needed }
  1109. PPDir:=SplitPath(PPFile[current]);
  1110. if PPDir[length(PPDir)] in ['/','\'{$ifdef MACOS},':'{$endif MACOS}] then
  1111. Delete(PPDir,length(PPDir),1);
  1112. if PPDir<>'' then
  1113. begin
  1114. {$ifndef MACOS}
  1115. TestOutputDir:=OutputDir+'/'+PPDir;
  1116. {$else MACOS}
  1117. TestOutputDir:=OutputDir+PPDir;
  1118. {$endif MACOS}
  1119. mkdirtree(TestOutputDir);
  1120. end
  1121. else
  1122. TestOutputDir:=OutputDir;
  1123. { Per test logfiles }
  1124. CompilerLogFile:=TestOutputFileName(SplitFileName(PPFile[current]),'log');
  1125. ExeLogFile:=TestOutputFileName(SplitFileName(PPFile[current]),'elg');
  1126. Verbose(V_Debug,'Using Compiler logfile: '+CompilerLogFile);
  1127. Verbose(V_Debug,'Using Execution logfile: '+ExeLogFile);
  1128. end;
  1129. if Res then
  1130. begin
  1131. if Config.UsesGraph and (not DoGraph) then
  1132. begin
  1133. AddLog(ResLogFile,skipping_graph_test+PPFileInfo[current]);
  1134. { avoid a second attempt by writing to elg file }
  1135. AddLog(EXELogFile,skipping_graph_test+PPFileInfo[current]);
  1136. Verbose(V_Warning,skipping_graph_test);
  1137. Res:=false;
  1138. end;
  1139. end;
  1140. if Res then
  1141. begin
  1142. if Config.IsInteractive and (not DoInteractive) then
  1143. begin
  1144. { avoid a second attempt by writing to elg file }
  1145. AddLog(EXELogFile,skipping_interactive_test+PPFileInfo[current]);
  1146. AddLog(ResLogFile,skipping_interactive_test+PPFileInfo[current]);
  1147. Verbose(V_Warning,skipping_interactive_test);
  1148. Res:=false;
  1149. end;
  1150. end;
  1151. if Res then
  1152. begin
  1153. if Config.IsKnownCompileError and (not DoKnown) then
  1154. begin
  1155. { avoid a second attempt by writing to elg file }
  1156. AddLog(EXELogFile,skipping_known_bug+PPFileInfo[current]);
  1157. AddLog(ResLogFile,skipping_known_bug+PPFileInfo[current]);
  1158. Verbose(V_Warning,skipping_known_bug);
  1159. Res:=false;
  1160. end;
  1161. end;
  1162. if Res and not DoUsual then
  1163. res:=(Config.IsInteractive and DoInteractive) or
  1164. (Config.IsKnownRunError and DoKnown) or
  1165. (Config.UsesGraph and DoGraph);
  1166. if Res then
  1167. begin
  1168. if (Config.MinVersion<>'') and not DoAll then
  1169. begin
  1170. Verbose(V_Debug,'Required compiler version: '+Config.MinVersion);
  1171. Res:=GetCompilerVersion;
  1172. if CompilerVersion<Config.MinVersion then
  1173. begin
  1174. { avoid a second attempt by writing to elg file }
  1175. AddLog(EXELogFile,skipping_compiler_version_too_low+PPFileInfo[current]);
  1176. AddLog(ResLogFile,skipping_compiler_version_too_low+PPFileInfo[current]);
  1177. Verbose(V_Warning,'Compiler version too low '+CompilerVersion+' < '+Config.MinVersion);
  1178. Res:=false;
  1179. end;
  1180. end;
  1181. end;
  1182. if Res then
  1183. begin
  1184. if (Config.MaxVersion<>'') and not DoAll then
  1185. begin
  1186. Verbose(V_Debug,'Highest compiler version: '+Config.MaxVersion);
  1187. Res:=GetCompilerVersion;
  1188. if CompilerVersion>Config.MaxVersion then
  1189. begin
  1190. { avoid a second attempt by writing to elg file }
  1191. AddLog(EXELogFile,skipping_compiler_version_too_high+PPFileInfo[current]);
  1192. AddLog(ResLogFile,skipping_compiler_version_too_high+PPFileInfo[current]);
  1193. Verbose(V_Warning,'Compiler version too high '+CompilerVersion+' > '+Config.MaxVersion);
  1194. Res:=false;
  1195. end;
  1196. end;
  1197. end;
  1198. if Res then
  1199. begin
  1200. if Config.NeedCPU<>'' then
  1201. begin
  1202. Verbose(V_Debug,'Required compiler cpu: '+Config.NeedCPU);
  1203. if not IsInList(CompilerCPU,Config.NeedCPU) then
  1204. begin
  1205. { avoid a second attempt by writing to elg file }
  1206. AddLog(EXELogFile,skipping_other_cpu+PPFileInfo[current]);
  1207. AddLog(ResLogFile,skipping_other_cpu+PPFileInfo[current]);
  1208. Verbose(V_Warning,'Compiler cpu "'+CompilerCPU+'" is not in list "'+Config.NeedCPU+'"');
  1209. Res:=false;
  1210. end;
  1211. end;
  1212. end;
  1213. if Res then
  1214. begin
  1215. if Config.SkipCPU<>'' then
  1216. begin
  1217. Verbose(V_Debug,'Skip compiler cpu: '+Config.SkipCPU);
  1218. if IsInList(CompilerCPU,Config.SkipCPU) then
  1219. begin
  1220. { avoid a second attempt by writing to elg file }
  1221. AddLog(EXELogFile,skipping_other_cpu+PPFileInfo[current]);
  1222. AddLog(ResLogFile,skipping_other_cpu+PPFileInfo[current]);
  1223. Verbose(V_Warning,'Compiler cpu "'+CompilerCPU+'" is in list "'+Config.SkipCPU+'"');
  1224. Res:=false;
  1225. end;
  1226. end;
  1227. end;
  1228. if Res then
  1229. begin
  1230. if Config.SkipEmu<>'' then
  1231. begin
  1232. Verbose(V_Debug,'Skip emulator: '+emulatorname);
  1233. if IsInList(emulatorname,Config.SkipEmu) then
  1234. begin
  1235. { avoid a second attempt by writing to elg file }
  1236. AddLog(EXELogFile,skipping_other_cpu+PPFileInfo[current]);
  1237. AddLog(ResLogFile,skipping_other_cpu+PPFileInfo[current]);
  1238. Verbose(V_Warning,'Emulator "'+emulatorname+'" is in list "'+Config.SkipEmu+'"');
  1239. Res:=false;
  1240. end;
  1241. end;
  1242. end;
  1243. if Res then
  1244. begin
  1245. if Config.NeedTarget<>'' then
  1246. begin
  1247. Verbose(V_Debug,'Required compiler target: '+Config.NeedTarget);
  1248. if not IsInList(CompilerTarget,Config.NeedTarget) then
  1249. begin
  1250. { avoid a second attempt by writing to elg file }
  1251. AddLog(EXELogFile,skipping_other_target+PPFileInfo[current]);
  1252. AddLog(ResLogFile,skipping_other_target+PPFileInfo[current]);
  1253. Verbose(V_Warning,'Compiler target "'+CompilerTarget+'" is not in list "'+Config.NeedTarget+'"');
  1254. Res:=false;
  1255. end;
  1256. end;
  1257. end;
  1258. if Res then
  1259. begin
  1260. if Config.SkipTarget<>'' then
  1261. begin
  1262. Verbose(V_Debug,'Skip compiler target: '+Config.NeedTarget);
  1263. if IsInList(CompilerTarget,Config.SkipTarget) then
  1264. begin
  1265. { avoid a second attempt by writing to elg file }
  1266. AddLog(EXELogFile,skipping_other_target+PPFileInfo[current]);
  1267. AddLog(ResLogFile,skipping_other_target+PPFileInfo[current]);
  1268. Verbose(V_Warning,'Compiler target "'+CompilerTarget+'" is in list "'+Config.SkipTarget+'"');
  1269. Res:=false;
  1270. end;
  1271. end;
  1272. end;
  1273. if Res then
  1274. begin
  1275. Res:=RunCompiler;
  1276. if Res and Config.NeedRecompile then
  1277. Res:=RunCompiler;
  1278. end;
  1279. if Res and (not Config.ShouldFail) then
  1280. begin
  1281. if (Config.NoRun) then
  1282. begin
  1283. { avoid a second attempt by writing to elg file }
  1284. AddLog(EXELogFile,skipping_run_test+PPFileInfo[current]);
  1285. AddLog(ResLogFile,skipping_run_test+PPFileInfo[current]);
  1286. Verbose(V_Debug,skipping_run_test);
  1287. end
  1288. else if Config.IsKnownRunError and (not DoKnown) then
  1289. begin
  1290. { avoid a second attempt by writing to elg file }
  1291. AddLog(EXELogFile,skipping_known_bug+PPFileInfo[current]);
  1292. AddLog(ResLogFile,skipping_known_bug+PPFileInfo[current]);
  1293. Verbose(V_Warning,skipping_known_bug);
  1294. end
  1295. else
  1296. begin
  1297. if DoExecute then
  1298. begin
  1299. if FileExists(TestOutputFilename(PPFile[current],'ppu')) or
  1300. FileExists(TestOutputFilename(PPFile[current],'ppo')) or
  1301. FileExists(TestOutputFilename(PPFile[current],'ppw')) then
  1302. begin
  1303. AddLog(ExeLogFile,skipping_run_unit+PPFileInfo[current]);
  1304. AddLog(ResLogFile,skipping_run_unit+PPFileInfo[current]);
  1305. Verbose(V_Debug,'Unit found, skipping run test')
  1306. end
  1307. else
  1308. Res:=RunExecutable;
  1309. end;
  1310. end;
  1311. end;
  1312. end;
  1313. begin
  1314. Current:=0;
  1315. PPFile:=TStringList.Create;
  1316. PPFile.Capacity:=10;
  1317. PPFileInfo:=TStringList.Create;
  1318. PPFileInfo.Capacity:=10;
  1319. GetArgs;
  1320. SetTargetDirectoriesStyle;
  1321. Verbose(V_Debug,'Found '+ToStr(PPFile.Count)+' tests to run');
  1322. if current>0 then
  1323. for current:=0 to PPFile.Count-1 do
  1324. begin
  1325. SetPPFileInfo;
  1326. TestName:=Copy(PPFile[current],1,Pos('.pp',PPFile[current])-1);
  1327. Verbose(V_Normal,'Running test '+TestName+', file '+PPFile[current]);
  1328. RunTest;
  1329. end;
  1330. PPFile.Free;
  1331. PPFileInfo.Free;
  1332. end.