dotest.pp 41 KB

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