dotest.pp 42 KB

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