dotest.pp 35 KB

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