dotest.pp 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031
  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. {$mode objfpc}
  13. {$goto on}
  14. {$H+}
  15. program dotest;
  16. uses
  17. sysutils,
  18. dos,
  19. {$ifdef macos}
  20. macutils,
  21. {$endif}
  22. strutils,
  23. teststr,
  24. testu,
  25. redir,
  26. bench,
  27. classes;
  28. {$ifdef go32v2}
  29. {$define LIMIT83FS}
  30. {$endif}
  31. {$ifdef os2}
  32. {$define LIMIT83FS}
  33. {$endif}
  34. {$ifdef msdos}
  35. {$define LIMIT83FS}
  36. {$endif}
  37. type
  38. tcompinfo = (compver,comptarget,compcpu);
  39. tdelexecutable = (deBefore, deAfter);
  40. tdelexecutables = set of tdelexecutable;
  41. const
  42. ObjExt='o';
  43. PPUExt='ppu';
  44. {$ifdef UNIX}
  45. SrcExeExt='';
  46. {$else UNIX}
  47. {$ifdef MACOS}
  48. SrcExeExt='';
  49. {$else MACOS}
  50. SrcExeExt='.exe';
  51. {$endif MACOS}
  52. {$endif UNIX}
  53. ExeExt : string = '';
  54. DllExt : string = '.so';
  55. DllPrefix: string = 'lib';
  56. DefaultTimeout=60;
  57. READ_ONLY = 0;
  58. var
  59. Config : TConfig;
  60. CompilerLogFile,
  61. ExeLogFile,
  62. LongLogfile,
  63. FailLogfile,
  64. RTLUnitsDir,
  65. TestOutputDir,
  66. OutputDir : string;
  67. CompilerBin,
  68. { CompilerCPU and CompilerTarget are lowercased at start
  69. to avoid need to call lowercase again and again ... }
  70. CompilerCPU,
  71. CompilerTarget,
  72. CompilerVersion,
  73. DefaultCompilerCPU,
  74. DefaultCompilerTarget,
  75. DefaultCompilerVersion : string;
  76. PPFile : TStringList;
  77. PPFileInfo : TStringList;
  78. TestName : string;
  79. Current : longint;
  80. const
  81. DoGraph : boolean = false;
  82. UseOSOnly : boolean = false;
  83. DoInteractive : boolean = false;
  84. DoExecute : boolean = false;
  85. DoKnown : boolean = false;
  86. DoAll : boolean = false;
  87. DoUsual : boolean = true;
  88. { TargetDir : string = ''; unused }
  89. BenchmarkInfo : boolean = false;
  90. ExtraCompilerOpts : string = '';
  91. DelExecutable : TDelExecutables = [];
  92. RemoteAddr : string = '';
  93. RemotePathPrefix : string = '';
  94. RemotePath : string = '/tmp';
  95. RemotePara : string = '';
  96. RemoteRshParas : string = '';
  97. RemoteShell : string = '';
  98. RemoteShellBase : string = '';
  99. RemoteShellNeedsExport : boolean = false;
  100. rshprog : string = 'rsh';
  101. rcpprog : string = 'rcp';
  102. rquote : string = '''';
  103. UseTimeout : boolean = false;
  104. emulatorname : string = '';
  105. TargetCanCompileLibraries : boolean = true;
  106. UniqueSuffix: string = '';
  107. const
  108. NoSharedLibSupportPattern='$nosharedlib';
  109. TargetHasNoSharedLibSupport = 'msdos,go32v2';
  110. NoWorkingUnicodeSupport='$nounicode';
  111. TargetHasNoWorkingUnicodeSupport = 'msdos';
  112. NoWorkingThread='$nothread';
  113. TargetHasNoWorkingThreadSupport = 'go32v2,msdos';
  114. procedure TranslateConfig(var AConfig: TConfig);
  115. begin
  116. AConfig.SkipTarget:=ReplaceText(AConfig.SkipTarget, NoSharedLibSupportPattern, TargetHasNoSharedLibSupport);
  117. AConfig.SkipTarget:=ReplaceText(AConfig.SkipTarget, NoWorkingUnicodeSupport, TargetHasNoWorkingUnicodeSupport);
  118. AConfig.SkipTarget:=ReplaceText(AConfig.SkipTarget, NoWorkingThread, TargetHasNoWorkingThreadSupport);
  119. end;
  120. function ToStr(l:longint):string;
  121. var
  122. s : string;
  123. begin
  124. Str(l,s);
  125. ToStr:=s;
  126. end;
  127. function ToStrZero(l:longint;nbzero : byte):string;
  128. var
  129. s : string;
  130. begin
  131. Str(l,s);
  132. while length(s)<nbzero do
  133. s:='0'+s;
  134. ToStrZero:=s;
  135. end;
  136. function trimspace(const s:string):string;
  137. var
  138. i,j : longint;
  139. begin
  140. i:=length(s);
  141. while (i>0) and (s[i] in [#9,' ']) do
  142. dec(i);
  143. j:=1;
  144. while (j<i) and (s[j] in [#9,' ']) do
  145. inc(j);
  146. trimspace:=Copy(s,j,i-j+1);
  147. end;
  148. function IsInList(const entry,list:string):boolean;
  149. var
  150. i,istart : longint;
  151. begin
  152. IsInList:=false;
  153. i:=0;
  154. while (i<length(list)) do
  155. begin
  156. { Find list item }
  157. istart:=i+1;
  158. while (i<length(list)) and
  159. (list[i+1]<>',') do
  160. inc(i);
  161. if Upcase(entry)=Upcase(TrimSpace(Copy(list,istart,i-istart+1))) then
  162. begin
  163. IsInList:=true;
  164. exit;
  165. end;
  166. { skip , }
  167. inc(i);
  168. end;
  169. end;
  170. procedure SetPPFileInfo;
  171. Var
  172. info : searchrec;
  173. dt : DateTime;
  174. begin
  175. FindFirst (PPFile[current],anyfile,Info);
  176. If DosError=0 then
  177. begin
  178. UnpackTime(info.time,dt);
  179. PPFileInfo.Insert(current,PPFile[current]+' '+ToStr(dt.year)+'/'+ToStrZero(dt.month,2)+'/'+
  180. ToStrZero(dt.day,2)+' '+ToStrZero(dt.Hour,2)+':'+ToStrZero(dt.min,2)+':'+ToStrZero(dt.sec,2));
  181. end
  182. else
  183. PPFileInfo.Insert(current,PPFile[current]);
  184. FindClose (Info);
  185. end;
  186. function ForceExtension(Const HStr,ext:String):String;
  187. {
  188. Return a filename which certainly has the extension ext
  189. }
  190. var
  191. j : longint;
  192. begin
  193. j:=length(Hstr);
  194. while (j>0) and (Hstr[j]<>'.') do
  195. dec(j);
  196. if j=0 then
  197. j:=length(Hstr)+1;
  198. if Ext<>'' then
  199. begin
  200. if Ext[1]='.' then
  201. ForceExtension:=Copy(Hstr,1,j-1)+Ext
  202. else
  203. ForceExtension:=Copy(Hstr,1,j-1)+'.'+Ext
  204. end
  205. else
  206. ForceExtension:=Copy(Hstr,1,j-1);
  207. end;
  208. procedure mkdirtree(const s:string);
  209. var
  210. SErr, hs : string;
  211. Err: longint;
  212. begin
  213. if s='' then
  214. exit;
  215. if s[length(s)] in ['\','/'{$IFDEF MACOS},':'{$ENDIF}] then
  216. hs:=Copy(s,1,length(s)-1)
  217. else
  218. hs:=s;
  219. if not PathExists(hs) then
  220. begin
  221. { Try parent first }
  222. mkdirtree(SplitPath(hs));
  223. { make this dir }
  224. Verbose(V_Debug,'Making directory '+s);
  225. {$I-}
  226. MkDir (HS);
  227. {$I+}
  228. Err := IOResult;
  229. if Err <> 0 then
  230. begin
  231. { did another parallel instance create it in the mean time? }
  232. if not PathExists(hs) then
  233. begin
  234. { no -> error }
  235. Str (Err, SErr);
  236. Verbose (V_Error, 'Directory creation of "'+HS+'" failed ' + SErr);
  237. end;
  238. end;
  239. end;
  240. end;
  241. Function RemoveFile(const f:string):boolean;
  242. var
  243. g : file;
  244. begin
  245. assign(g,f);
  246. {$I-}
  247. erase(g);
  248. {$I+}
  249. RemoveFile:=(ioresult=0);
  250. end;
  251. function Copyfile(const fn1,fn2:string;append:boolean) : longint;
  252. const
  253. bufsize = 16384;
  254. var
  255. f,g : file;
  256. oldfilemode : byte;
  257. st : string;
  258. addsize,
  259. i : longint;
  260. buf : pointer;
  261. begin
  262. if Append then
  263. Verbose(V_Debug,'Appending '+fn1+' to '+fn2)
  264. else
  265. Verbose(V_Debug,'Copying '+fn1+' to '+fn2);
  266. assign(g,fn2);
  267. if append then
  268. begin
  269. {$I-}
  270. reset(g,1);
  271. {$I+}
  272. if ioresult<>0 then
  273. append:=false
  274. else
  275. seek(g,filesize(g));
  276. end;
  277. if not append then
  278. begin
  279. {$I-}
  280. rewrite(g,1);
  281. {$I+}
  282. if ioresult<>0 then
  283. Verbose(V_Error,'Can''t open '+fn2+' for output');
  284. end;
  285. assign(f,fn1);
  286. {$I-}
  287. { Try using read only file mode }
  288. oldfilemode:=filemode;
  289. filemode:=READ_ONLY;
  290. reset(f,1);
  291. {$I+}
  292. addsize:=0;
  293. getmem(buf,bufsize);
  294. if ioresult<>0 then
  295. begin
  296. sleep(1000);
  297. {$I-}
  298. reset(f,1);
  299. {$I+}
  300. if ioresult<>0 then
  301. begin
  302. Verbose(V_Warning,'Can''t open '+fn1);
  303. st:='Can''t open '+fn1;
  304. i:=length(st);
  305. // blocksize is larger than 255, so no check is needed
  306. move(st[1],buf^,i);
  307. blockwrite(g,buf^,i);
  308. freemem(buf,bufsize);
  309. close(g);
  310. filemode:=oldfilemode;
  311. exit;
  312. end;
  313. end;
  314. filemode:=oldfilemode;
  315. repeat
  316. blockread(f,buf^,bufsize,i);
  317. blockwrite(g,buf^,i);
  318. addsize:=addsize+i;
  319. until i<bufsize;
  320. freemem(buf,bufsize);
  321. close(f);
  322. close(g);
  323. CopyFile:=addsize;
  324. end;
  325. procedure AddLog(const logfile,s:string);
  326. var
  327. t : text;
  328. begin
  329. assign(t,logfile);
  330. {$I-}
  331. append(t);
  332. {$I+}
  333. if ioresult<>0 then
  334. begin
  335. {$I-}
  336. rewrite(t);
  337. {$I+}
  338. if ioresult<>0 then
  339. Verbose(V_Abort,'Can''t append to '+logfile);
  340. end;
  341. writeln(t,s);
  342. close(t);
  343. end;
  344. procedure ForceLog(const logfile:string);
  345. var
  346. t : text;
  347. begin
  348. assign(t,logfile);
  349. {$I-}
  350. append(t);
  351. {$I+}
  352. if ioresult<>0 then
  353. begin
  354. {$I-}
  355. rewrite(t);
  356. {$I+}
  357. if ioresult<>0 then
  358. Verbose(V_Abort,'Can''t Create '+logfile);
  359. end;
  360. close(t);
  361. end;
  362. function GetCompilerInfo(c:tcompinfo):boolean;
  363. var
  364. t : text;
  365. hs : string;
  366. begin
  367. GetCompilerInfo:=false;
  368. { Try to get all information in one call, this is
  369. supported in 1.1. Older compilers 1.0.x will only
  370. return the first info }
  371. case c of
  372. compver :
  373. begin
  374. if DefaultCompilerVersion<>'' then
  375. begin
  376. GetCompilerInfo:=true;
  377. exit;
  378. end;
  379. hs:='-iVTPTO';
  380. end;
  381. compcpu :
  382. begin
  383. if DefaultCompilerCPU<>'' then
  384. begin
  385. GetCompilerInfo:=true;
  386. exit;
  387. end;
  388. hs:='-iTPTOV';
  389. end;
  390. comptarget :
  391. begin
  392. if DefaultCompilerTarget<>'' then
  393. begin
  394. GetCompilerInfo:=true;
  395. exit;
  396. end;
  397. hs:='-iTOTPV';
  398. end;
  399. end;
  400. ExecuteRedir(CompilerBin,hs,'','out.'+UniqueSuffix,'');
  401. assign(t,'out.'+UniqueSuffix);
  402. {$I-}
  403. reset(t);
  404. readln(t,hs);
  405. close(t);
  406. erase(t);
  407. {$I+}
  408. if ioresult<>0 then
  409. Verbose(V_Error,'Can''t get Compiler Info')
  410. else
  411. begin
  412. Verbose(V_Debug,'Retrieved Compiler Info: "'+hs+'"');
  413. case c of
  414. compver :
  415. begin
  416. DefaultCompilerVersion:=GetToken(hs);
  417. DefaultCompilerCPU:=GetToken(hs);
  418. DefaultCompilerTarget:=GetToken(hs);
  419. end;
  420. compcpu :
  421. begin
  422. DefaultCompilerCPU:=GetToken(hs);
  423. DefaultCompilerTarget:=GetToken(hs);
  424. DefaultCompilerVersion:=GetToken(hs);
  425. end;
  426. comptarget :
  427. begin
  428. DefaultCompilerTarget:=GetToken(hs);
  429. DefaultCompilerCPU:=GetToken(hs);
  430. DefaultCompilerVersion:=GetToken(hs);
  431. end;
  432. end;
  433. GetCompilerInfo:=true;
  434. end;
  435. end;
  436. function GetCompilerVersion:boolean;
  437. const
  438. CompilerVersionDebugWritten : boolean = false;
  439. begin
  440. if CompilerVersion='' then
  441. begin
  442. GetCompilerVersion:=GetCompilerInfo(compver);
  443. CompilerVersion:=DefaultCompilerVersion;
  444. end
  445. else
  446. GetCompilerVersion:=true;
  447. if GetCompilerVersion and not CompilerVersionDebugWritten then
  448. begin
  449. Verbose(V_Debug,'Compiler Version: "'+CompilerVersion+'"');
  450. CompilerVersionDebugWritten:=true;
  451. end;
  452. end;
  453. function GetCompilerCPU:boolean;
  454. const
  455. CompilerCPUDebugWritten : boolean = false;
  456. begin
  457. if CompilerCPU='' then
  458. begin
  459. GetCompilerCPU:=GetCompilerInfo(compcpu);
  460. CompilerCPU:=lowercase(DefaultCompilerCPU);
  461. end
  462. else
  463. GetCompilerCPU:=true;
  464. if GetCompilerCPU and not CompilerCPUDebugWritten then
  465. begin
  466. Verbose(V_Debug,'Compiler CPU: "'+CompilerCPU+'"');
  467. CompilerCPUDebugWritten:=true;
  468. end;
  469. end;
  470. function GetCompilerTarget:boolean;
  471. const
  472. CompilerTargetDebugWritten : boolean = false;
  473. begin
  474. if CompilerTarget='' then
  475. begin
  476. GetCompilerTarget:=GetCompilerInfo(comptarget);
  477. CompilerTarget:=lowercase(DefaultCompilerTarget);
  478. end
  479. else
  480. GetCompilerTarget:=true;
  481. if GetCompilerTarget and not CompilerTargetDebugWritten then
  482. begin
  483. Verbose(V_Debug,'Compiler Target: "'+CompilerTarget+'"');
  484. CompilerTargetDebugWritten:=true;
  485. end;
  486. end;
  487. function CompilerFullTarget:string;
  488. begin
  489. if UseOSOnly then
  490. CompilerFullTarget:=CompilerTarget
  491. else
  492. CompilerFullTarget:=CompilerCPU+'-'+CompilerTarget;
  493. end;
  494. { Set the three constants above according to
  495. the current target }
  496. procedure SetTargetDirectoriesStyle;
  497. var
  498. LTarget : string;
  499. begin
  500. { Call this first to ensure that CompilerTarget is not empty }
  501. GetCompilerTarget;
  502. LTarget := CompilerTarget;
  503. TargetHasDosStyleDirectories :=
  504. (LTarget='emx') or
  505. (LTarget='go32v2') or
  506. (LTarget='nativent') or
  507. (LTarget='os2') or
  508. (LTarget='symbian') or
  509. (LTarget='watcom') or
  510. (LTarget='wdosx') or
  511. (LTarget='win32') or
  512. (LTarget='win64');
  513. TargetAmigaLike:=
  514. (LTarget='amiga') or
  515. (LTarget='morphos');
  516. TargetIsMacOS:=
  517. (LTarget='macos');
  518. { Base on whether UNIX is defined as default macro
  519. in extradefines in systesms/i_XXX.pas units }
  520. TargetIsUnix:=
  521. (LTarget='linux') or
  522. (LTarget='linux6432') or
  523. (LTarget='freebsd') or
  524. (LTarget='openbsd') or
  525. (LTarget='netbsd') or
  526. (LTarget='beos') or
  527. (LTarget='haiku') or
  528. (LTarget='solaris') or
  529. (LTarget='iphonesim') or
  530. (LTarget='darwin') or
  531. (LTarget='aix') or
  532. (LTarget='android');
  533. { Set ExeExt for CompilerTarget.
  534. This list has been set up 2013-01 using the information in
  535. compiler/system/i_XXX.pas units.
  536. We should update this list when adding new targets PM }
  537. if (TargetHasDosStyleDirectories) or (LTarget='wince') then
  538. begin
  539. ExeExt:='.exe';
  540. DllExt:='.dll';
  541. DllPrefix:='';
  542. end
  543. else if LTarget='atari' then
  544. begin
  545. ExeExt:='.tpp';
  546. DllExt:='.dll';
  547. DllPrefix:='';
  548. end
  549. else if LTarget='gba' then
  550. ExeExt:='.gba'
  551. else if LTarget='nds' then
  552. ExeExt:='.bin'
  553. else if (LTarget='netware') or (LTarget='netwlibc') then
  554. begin
  555. ExeExt:='.nlm';
  556. DllExt:='.nlm';
  557. DllPrefix:='';
  558. end
  559. else if LTarget='wii' then
  560. ExeExt:='.dol';
  561. end;
  562. {$ifndef LIMIT83FS}
  563. { Set the UseOSOnly constant above according to
  564. the current target }
  565. procedure SetUseOSOnly;
  566. var
  567. LTarget : string;
  568. begin
  569. { Call this first to ensure that CompilerTarget is not empty }
  570. GetCompilerTarget;
  571. LTarget := CompilerTarget;
  572. UseOSOnly:= (LTarget='emx') or
  573. (LTarget='go32v2') or
  574. (LTarget='msdos') or
  575. (LTarget='os2');
  576. end;
  577. {$endif not LIMIT83FS}
  578. procedure SetTargetCanCompileLibraries;
  579. var
  580. LTarget : string;
  581. begin
  582. { Call this first to ensure that CompilerTarget is not empty }
  583. GetCompilerTarget;
  584. LTarget := CompilerTarget;
  585. { Feel free to add other targets here }
  586. if (LTarget='go32v2') then
  587. TargetCanCompileLibraries:=false;
  588. end;
  589. function OutputFileName(Const s,ext:String):String;
  590. begin
  591. {$ifndef macos}
  592. OutputFileName:=OutputDir+'/'+ForceExtension(s,ext);
  593. {$else macos}
  594. OutputFileName:=ConcatMacPath(OutputDir,ForceExtension(s,ext));
  595. {$endif macos}
  596. end;
  597. function TestOutputFileName(Const pref,base,ext:String):String;
  598. begin
  599. {$ifndef macos}
  600. TestOutputFileName:=TestOutputDir+'/'+ForceExtension(pref+SplitFileName(base),ext);
  601. {$else macos}
  602. TestOutputFileName:=ConcatMacPath(TestOutputDir,ForceExtension(pref+SplitFileName(base),ext));
  603. {$endif macos}
  604. end;
  605. function TestLogFileName(Const pref,base,ext:String):String;
  606. var
  607. LogDir: String;
  608. begin
  609. LogDir:=TestOutputDir;
  610. {$ifndef macos}
  611. if UniqueSuffix<>'' then
  612. LogDir:=LogDir+'/..';
  613. TestLogFileName:=LogDir+'/'+ForceExtension(pref+SplitFileName(base),ext);
  614. {$else macos}
  615. if UniqueSuffix<>'' then
  616. LogDir:=LogDir+'::';
  617. TestLogFileName:=ConcatMacPath(LogDir,ForceExtension(pref+SplitFileName(base),ext));
  618. {$endif macos}
  619. end;
  620. function ExitWithInternalError(const OutName:string):boolean;
  621. var
  622. t : text;
  623. s : string;
  624. begin
  625. ExitWithInternalError:=false;
  626. { open logfile }
  627. assign(t,Outname);
  628. {$I-}
  629. reset(t);
  630. {$I+}
  631. if ioresult<>0 then
  632. exit;
  633. while not eof(t) do
  634. begin
  635. readln(t,s);
  636. if pos('Fatal: Internal error ',s)>0 then
  637. begin
  638. ExitWithInternalError:=true;
  639. break;
  640. end;
  641. end;
  642. close(t);
  643. end;
  644. { Takes each option from AddOptions list
  645. considered as a space separated list
  646. and adds the option to args
  647. unless option contains a percent sign,
  648. in that case, the option after % will be added
  649. to args only if CompilerTarget is listed in
  650. the string part before %.
  651. NOTE: this function does not check for
  652. quoted options...
  653. The list before % must of course contain no spaces. }
  654. procedure AppendOptions(AddOptions : string;var args : string);
  655. var
  656. endopt,percentpos : longint;
  657. opttarget, currentopt : string;
  658. begin
  659. Verbose(V_Debug,'AppendOptions called with AddOptions="'+AddOptions+'"');
  660. AddOptions:=trimspace(AddOptions);
  661. repeat
  662. endopt:=pos(' ',AddOptions);
  663. if endopt=0 then
  664. endopt:=length(AddOptions);
  665. currentopt:=trimspace(copy(AddOptions,1,endopt));
  666. AddOptions:=trimspace(copy(Addoptions,endopt+1,length(AddOptions)));
  667. if currentopt<>'' then
  668. begin
  669. percentpos:=pos('%',currentopt);
  670. if (percentpos=0) then
  671. begin
  672. Verbose(V_Debug,'Adding option="'+currentopt+'"');
  673. args:=args+' '+currentopt;
  674. end
  675. else
  676. begin
  677. opttarget:=lowercase(copy(currentopt,1,percentpos-1));
  678. if IsInList(CompilerTarget, opttarget) then
  679. begin
  680. Verbose(V_Debug,'Adding target specific option="'+currentopt+'" for '+opttarget);
  681. args:=args+' '+copy(currentopt,percentpos+1,length(currentopt))
  682. end
  683. else
  684. Verbose(V_Debug,'No matching target "'+currentopt+'"');
  685. end;
  686. end;
  687. until AddOptions='';
  688. end;
  689. { This function removes some incompatible
  690. options from TEST_OPT before adding them to
  691. the list of options passed to the compiler.
  692. %DELOPT=XYZ will remove XYZ exactly
  693. %DELOPT=XYZ* will remove all options starting with XYZ.
  694. NOTE: This fuinction does not handle quoted options. }
  695. function DelOptions(Pattern, opts : string) : string;
  696. var
  697. currentopt : string;
  698. optpos, endopt, startpos, endpos : longint;
  699. iswild : boolean;
  700. begin
  701. opts:=trimspace(opts);
  702. pattern:=trimspace(pattern);
  703. repeat
  704. endpos:=pos(' ',pattern);
  705. if endpos=0 then
  706. endpos:=length(pattern);
  707. currentopt:=trimspace(copy(pattern,1,endpos));
  708. pattern:=trimspace(copy(pattern,endpos+1,length(pattern)));
  709. if currentopt<>'' then
  710. begin
  711. if currentopt[length(currentopt)]='*' then
  712. begin
  713. iswild:=true;
  714. system.delete(currentopt,length(currentopt),1);
  715. end
  716. else
  717. iswild:=false;
  718. startpos:=1;
  719. repeat
  720. optpos:=pos(currentopt,copy(opts,startpos,length(opts)));
  721. if optpos>0 then
  722. begin
  723. { move to index in full opts string }
  724. optpos:=optpos+startpos-1;
  725. { compute position of end of opt }
  726. endopt:=optpos+length(currentopt);
  727. { use that end as start position for next round }
  728. startpos:=endopt;
  729. if iswild then
  730. begin
  731. while (opts[endopt]<>' ') and
  732. (endopt<length(opts)) do
  733. begin
  734. inc(endopt);
  735. inc(startpos);
  736. end;
  737. Verbose(V_Debug,'Pattern match found "'+currentopt+'*" in "'+opts+'"');
  738. system.delete(opts,optpos,endopt-optpos+1);
  739. Verbose(V_Debug,'After opts="'+opts+'"');
  740. end
  741. else
  742. begin
  743. if (endopt>length(opts)) or (opts[endopt]=' ') then
  744. begin
  745. Verbose(V_Debug,'Exact match found "'+currentopt+'" in "'+opts+'"');
  746. system.delete(opts,optpos,endopt-optpos+1);
  747. Verbose(V_Debug,'After opts="'+opts+'"');
  748. end
  749. else
  750. begin
  751. Verbose(V_Debug,'No exact match "'+currentopt+'" in "'+opts+'"');
  752. end;
  753. end;
  754. end;
  755. until optpos=0;
  756. end;
  757. until pattern='';
  758. DelOptions:=opts;
  759. end;
  760. function RunCompiler(const ExtraPara: string):boolean;
  761. var
  762. args,LocalExtraArgs,
  763. wpoargs : string;
  764. passnr,
  765. passes : longint;
  766. execres : boolean;
  767. EndTicks,
  768. StartTicks : int64;
  769. begin
  770. RunCompiler:=false;
  771. args:='-n -T'+CompilerTarget+' -Fu'+RTLUnitsDir;
  772. if ExtraPara<>'' then
  773. args:=args+' '+ExtraPara;
  774. { the helper object files have been copied to the common directory }
  775. if UniqueSuffix<>'' then
  776. args:=args+' -Fo'+TestOutputDir+'/..';
  777. args:=args+' -FE'+TestOutputDir;
  778. if TargetIsMacOS then
  779. args:=args+' -WT '; {tests should be compiled as MPWTool}
  780. if Config.DelOptions<>'' then
  781. LocalExtraArgs:=DelOptions(Config.DelOptions,ExtraCompilerOpts)
  782. else
  783. LocalExtraArgs:=ExtraCompilerOpts;
  784. if LocalExtraArgs<>'' then
  785. args:=args+' '+LocalExtraArgs;
  786. if TargetIsUnix then
  787. begin
  788. { Add runtime library path to current dir to find .so files }
  789. if Config.NeedLibrary then
  790. begin
  791. if (CompilerTarget='darwin') or
  792. (CompilerTarget='aix') then
  793. args:=args+' -Fl'+TestOutputDir
  794. else
  795. { do not use single quote for -k as they are mishandled on
  796. Windows Shells }
  797. args:=args+' -Fl'+TestOutputDir+' -k-rpath -k.'
  798. end;
  799. end;
  800. if Config.NeedOptions<>'' then
  801. AppendOptions(Config.NeedOptions,args);
  802. wpoargs:='';
  803. if (Config.WpoPasses=0) or
  804. (Config.WpoParas='') then
  805. passes:=1
  806. else
  807. passes:=config.wpopasses+1;
  808. args:=args+' '+PPFile[current];
  809. for passnr:=1 to passes do
  810. begin
  811. if (passes>1) then
  812. begin
  813. wpoargs:=' -OW'+config.wpoparas+' -FW'+TestOutputFileName('',PPFile[current],'wp'+tostr(passnr));
  814. if (passnr>1) then
  815. wpoargs:=wpoargs+' -Ow'+config.wpoparas+' -Fw'+TestOutputFileName('',PPFile[current],'wp'+tostr(passnr-1));
  816. end;
  817. Verbose(V_Debug,'Executing '+compilerbin+' '+args+wpoargs);
  818. { also get the output from as and ld that writes to stderr sometimes }
  819. StartTicks:=GetMicroSTicks;
  820. {$ifndef macos}
  821. execres:=ExecuteRedir(CompilerBin,args+wpoargs,'',CompilerLogFile,'stdout');
  822. {$else macos}
  823. {Due to that Toolserver is not reentrant, we have to asm and link via script.}
  824. execres:=ExecuteRedir(CompilerBin,'-s '+args+wpoargs,'',CompilerLogFile,'stdout');
  825. if execres then
  826. execres:=ExecuteRedir(TestOutputDir + ':ppas','','',CompilerLogFile,'stdout');
  827. {$endif macos}
  828. EndTicks:=GetMicroSTicks;
  829. Verbose(V_Debug,'Exitcode '+ToStr(ExecuteResult));
  830. if BenchmarkInfo then
  831. begin
  832. Verbose(V_Normal,'Compilation took '+ToStr(EndTicks-StartTicks)+' us');
  833. end;
  834. { Error during execution? }
  835. if (not execres) and (ExecuteResult=0) then
  836. begin
  837. AddLog(FailLogFile,TestName);
  838. AddLog(ResLogFile,failed_to_compile+PPFileInfo[current]);
  839. AddLog(LongLogFile,line_separation);
  840. AddLog(LongLogFile,failed_to_compile+PPFileInfo[current]);
  841. if CopyFile(CompilerLogFile,LongLogFile,true)=0 then
  842. AddLog(LongLogFile,'IOStatus'+ToStr(IOStatus));
  843. { avoid to try again }
  844. AddLog(ExeLogFile,failed_to_compile+PPFileInfo[current]);
  845. Verbose(V_Warning,'IOStatus: '+ToStr(IOStatus));
  846. exit;
  847. end;
  848. { Check for internal error }
  849. if ExitWithInternalError(CompilerLogFile) then
  850. begin
  851. AddLog(FailLogFile,TestName);
  852. if Config.Note<>'' then
  853. AddLog(FailLogFile,Config.Note);
  854. AddLog(ResLogFile,failed_to_compile+PPFileInfo[current]+' internalerror generated');
  855. AddLog(LongLogFile,line_separation);
  856. AddLog(LongLogFile,failed_to_compile+PPFileInfo[current]);
  857. if Config.Note<>'' then
  858. AddLog(LongLogFile,Config.Note);
  859. if CopyFile(CompilerLogFile,LongLogFile,true)=0 then
  860. AddLog(LongLogFile,'Internal error in compiler');
  861. { avoid to try again }
  862. AddLog(ExeLogFile,failed_to_compile+PPFileInfo[current]);
  863. Verbose(V_Warning,'Internal error in compiler');
  864. exit;
  865. end;
  866. end;
  867. { Should the compile fail ? }
  868. if Config.ShouldFail then
  869. begin
  870. if ExecuteResult<>0 then
  871. begin
  872. AddLog(ResLogFile,success_compilation_failed+PPFileInfo[current]);
  873. { avoid to try again }
  874. AddLog(ExeLogFile,success_compilation_failed+PPFileInfo[current]);
  875. RunCompiler:=true;
  876. end
  877. else
  878. begin
  879. AddLog(FailLogFile,TestName);
  880. if Config.Note<>'' then
  881. AddLog(FailLogFile,Config.Note);
  882. AddLog(ResLogFile,failed_compilation_successful+PPFileInfo[current]);
  883. AddLog(LongLogFile,line_separation);
  884. AddLog(LongLogFile,failed_compilation_successful+PPFileInfo[current]);
  885. { avoid to try again }
  886. AddLog(ExeLogFile,failed_compilation_successful+PPFileInfo[current]);
  887. if Config.Note<>'' then
  888. AddLog(LongLogFile,Config.Note);
  889. CopyFile(CompilerLogFile,LongLogFile,true);
  890. end;
  891. end
  892. else
  893. begin
  894. if (ExecuteResult<>0) and
  895. (((Config.KnownCompileNote<>'') and (Config.KnownCompileError=0)) or
  896. ((Config.KnownCompileError<>0) and (ExecuteResult=Config.KnownCompileError))) then
  897. begin
  898. AddLog(FailLogFile,TestName+known_problem+Config.KnownCompileNote);
  899. AddLog(ResLogFile,failed_to_compile+PPFileInfo[current]+known_problem+Config.KnownCompileNote);
  900. AddLog(LongLogFile,line_separation);
  901. AddLog(LongLogFile,known_problem+Config.KnownCompileNote);
  902. AddLog(LongLogFile,failed_to_compile+PPFileInfo[current]+' ('+ToStr(ExecuteResult)+')');
  903. if Copyfile(CompilerLogFile,LongLogFile,true)=0 then
  904. AddLog(LongLogFile,known_problem+'exitcode: '+ToStr(ExecuteResult));
  905. Verbose(V_Warning,known_problem+'exitcode: '+ToStr(ExecuteResult));
  906. end
  907. else if ExecuteResult<>0 then
  908. begin
  909. AddLog(FailLogFile,TestName);
  910. if Config.Note<>'' then
  911. AddLog(FailLogFile,Config.Note);
  912. AddLog(ResLogFile,failed_to_compile+PPFileInfo[current]);
  913. AddLog(LongLogFile,line_separation);
  914. AddLog(LongLogFile,failed_to_compile+PPFileInfo[current]);
  915. if Config.Note<>'' then
  916. AddLog(LongLogFile,Config.Note);
  917. if CopyFile(CompilerLogFile,LongLogFile,true)=0 then
  918. AddLog(LongLogFile,'Exitcode: '+ToStr(ExecuteResult)+' (expected 0)');
  919. { avoid to try again }
  920. AddLog(ExeLogFile,failed_to_compile+PPFileInfo[current]);
  921. Verbose(V_Warning,'Exitcode: '+ToStr(ExecuteResult)+' (expected 0)');
  922. end
  923. else
  924. begin
  925. AddLog(ResLogFile,successfully_compiled+PPFileInfo[current]);
  926. RunCompiler:=true;
  927. end;
  928. end;
  929. end;
  930. function CheckTestExitCode(const OutName:string):boolean;
  931. var
  932. t : text;
  933. s : string;
  934. i,code : integer;
  935. begin
  936. CheckTestExitCode:=false;
  937. { open logfile }
  938. assign(t,Outname);
  939. {$I-}
  940. reset(t);
  941. {$I+}
  942. if ioresult<>0 then
  943. exit;
  944. while not eof(t) do
  945. begin
  946. readln(t,s);
  947. i:=pos('TestExitCode: ',s);
  948. if i>0 then
  949. begin
  950. delete(s,1,i+14-1);
  951. val(s,ExecuteResult,code);
  952. if code=0 then
  953. CheckTestExitCode:=true;
  954. break;
  955. end;
  956. end;
  957. close(t);
  958. end;
  959. function LibraryExists(const PPFile : string; out FileName : string) : boolean;
  960. begin
  961. { Check if a dynamic library XXX was created }
  962. { Windows XXX.dll style }
  963. FileName:=TestOutputFilename('',PPFile,'dll');
  964. if FileExists(FileName) then
  965. begin
  966. LibraryExists:=true;
  967. exit;
  968. end;
  969. { Linux libXXX.so style }
  970. FileName:=TestOutputFilename('lib',PPFile,'so');
  971. if FileExists(FileName) then
  972. begin
  973. LibraryExists:=true;
  974. exit;
  975. end;
  976. { Darwin libXXX.dylib style }
  977. FileName:=TestOutputFilename('lib',PPFile,'dylib');
  978. if FileExists(FileName) then
  979. begin
  980. LibraryExists:=true;
  981. exit;
  982. end;
  983. { MacOS LibXXX style }
  984. FileName:=TestOutputFilename('Lib',PPFile,'');
  985. if FileExists(FileName) then
  986. begin
  987. LibraryExists:=true;
  988. exit;
  989. end;
  990. { Netware wlic XXX.nlm style }
  991. FileName:=TestOutputFilename('',PPFile,'nlm');
  992. if FileExists(FileName) then
  993. begin
  994. LibraryExists:=true;
  995. exit;
  996. end;
  997. { Amiga XXX.library style }
  998. FileName:=TestOutputFilename('',PPFile,'library');
  999. if FileExists(FileName) then
  1000. begin
  1001. LibraryExists:=true;
  1002. exit;
  1003. end;
  1004. LibraryExists:=false;
  1005. end;
  1006. function ExecuteRemote(prog,args:string;out StartTicks,EndTicks : int64):boolean;
  1007. const
  1008. MaxTrials = 5;
  1009. var
  1010. Trials : longint;
  1011. Res : boolean;
  1012. begin
  1013. if SplitFileExt(prog)='' then
  1014. prog:=prog+SrcExeExt;
  1015. Verbose(V_Debug,'RemoteExecuting '+Prog+' '+args);
  1016. StartTicks:=GetMicroSTicks;
  1017. Res:=false;
  1018. Trials:=0;
  1019. While (Trials<MaxTrials) and not Res do
  1020. begin
  1021. inc(Trials);
  1022. Res:=ExecuteRedir(prog,args,'',EXELogFile,'stdout');
  1023. if not Res then
  1024. Verbose(V_Debug,'Call to '+prog+' failed: '+
  1025. 'IOStatus='+ToStr(IOStatus)+
  1026. ' RedirErrorOut='+ToStr(RedirErrorOut)+
  1027. ' RedirErrorIn='+ToStr(RedirErrorIn)+
  1028. ' RedirErrorError='+ToStr(RedirErrorError)+
  1029. ' ExecuteResult='+ToStr(ExecuteResult));
  1030. end;
  1031. if Trials>1 then
  1032. Verbose(V_Debug,'Done in '+tostr(trials)+' trials');
  1033. EndTicks:=GetMicroSTicks;
  1034. ExecuteRemote:=res;
  1035. end;
  1036. function ExecuteEmulated(const prog,args,FullExeLogFile:string;out StartTicks,EndTicks : int64):boolean;
  1037. begin
  1038. Verbose(V_Debug,'EmulatorExecuting '+Prog+' '+args);
  1039. StartTicks:=GetMicroSTicks;
  1040. ExecuteEmulated:=ExecuteRedir(prog,args,'',FullExeLogFile,'stdout');
  1041. EndTicks:=GetMicroSTicks;
  1042. end;
  1043. function MaybeCopyFiles(const FileToCopy : string) : boolean;
  1044. var
  1045. TestRemoteExe,
  1046. pref : string;
  1047. LocalFile, RemoteFile, s: string;
  1048. LocalPath: string;
  1049. i : integer;
  1050. execres : boolean;
  1051. EndTicks,
  1052. StartTicks : int64;
  1053. FileList : TStringList;
  1054. RelativeToConfigMarker : TObject;
  1055. function BuildFileList: TStringList;
  1056. var
  1057. s : string;
  1058. index : longint;
  1059. begin
  1060. s:=Config.Files;
  1061. if (length(s) = 0) and (Config.ConfigFileSrc='') then
  1062. begin
  1063. Result:=nil;
  1064. exit;
  1065. end;
  1066. Result:=TStringList.Create;
  1067. if s<>'' then
  1068. repeat
  1069. index:=pos(' ',s);
  1070. if index=0 then
  1071. LocalFile:=s
  1072. else
  1073. LocalFile:=copy(s,1,index-1);
  1074. Result.Add(LocalFile);
  1075. if index=0 then
  1076. break;
  1077. s:=copy(s,index+1,length(s)-index);
  1078. until false;
  1079. if Config.ConfigFileSrc<>'' then
  1080. begin
  1081. if Config.ConfigFileSrc=Config.ConfigFileDst then
  1082. Result.AddObject(Config.ConfigFileSrc,RelativeToConfigMarker)
  1083. else
  1084. Result.AddObject(Config.ConfigFileSrc+'='+Config.ConfigFileDst,RelativeToConfigMarker);
  1085. end;
  1086. end;
  1087. begin
  1088. RelativeToConfigMarker:=TObject.Create;
  1089. if RemoteAddr='' then
  1090. begin
  1091. If UniqueSuffix<>'' then
  1092. begin
  1093. FileList:=BuildFileList;
  1094. if assigned(FileList) then
  1095. for i:=0 to FileList.Count-1 do
  1096. begin
  1097. if FileList.Names[i]<>'' then
  1098. begin
  1099. LocalFile:=FileList.Names[i];
  1100. RemoteFile:=FileList.ValueFromIndex[i];
  1101. end
  1102. else
  1103. begin
  1104. LocalFile:=FileList[i];
  1105. RemoteFile:=LocalFile;
  1106. end;
  1107. if FileList.Objects[i]=RelativeToConfigMarker then
  1108. s:='config/'+LocalFile
  1109. else
  1110. s:=LocalPath+LocalFile;
  1111. CopyFile(s,TestOutputDir+'/'+RemoteFile,false);
  1112. end;
  1113. end;
  1114. RelativeToConfigMarker.Free;
  1115. exit(true);
  1116. end;
  1117. execres:=true;
  1118. { Check if library should be deleted. Do not copy to remote target in such case. }
  1119. if (deAfter in DelExecutable) and (Config.DelFiles <> '') then
  1120. if SplitFileName(FileToCopy) = DllPrefix + Trim(Config.DelFiles) + DllExt then
  1121. exit;
  1122. { We don't want to create subdirs, remove paths from the test }
  1123. TestRemoteExe:=RemotePath+'/'+SplitFileName(FileToCopy);
  1124. if deBefore in DelExecutable then
  1125. begin
  1126. s:=RemoteRshParas+' rm ';
  1127. if rshprog <> 'adb' then
  1128. s:=s+'-f ';
  1129. ExecuteRemote(rshprog,s+TestRemoteExe,
  1130. StartTicks,EndTicks);
  1131. end;
  1132. execres:=ExecuteRemote(rcpprog,RemotePara+' '+FileToCopy+' '+
  1133. RemotePathPrefix+TestRemoteExe,StartTicks,EndTicks);
  1134. if not execres then
  1135. begin
  1136. Verbose(V_normal, 'Could not copy executable '+FileToCopy);
  1137. RelativeToConfigMarker.Free;
  1138. exit(execres);
  1139. end;
  1140. FileList:=BuildFileList;
  1141. if assigned(FileList) then
  1142. begin
  1143. LocalPath:=SplitPath(PPFile[current]);
  1144. if Length(LocalPath) > 0 then
  1145. LocalPath:=LocalPath+'/';
  1146. for i:=0 to FileList.count-1 do
  1147. begin
  1148. if FileList.Names[i]<>'' then
  1149. begin
  1150. LocalFile:=FileList.Names[i];
  1151. RemoteFile:=FileList.ValueFromIndex[i];
  1152. end
  1153. else
  1154. begin
  1155. LocalFile:=FileList[i];
  1156. RemoteFile:=LocalFile;
  1157. end;
  1158. RemoteFile:=RemotePath+'/'+SplitFileName(RemoteFile);
  1159. if FileList.Objects[i]=RelativeToConfigMarker then
  1160. LocalFile:='config/'+LocalFile
  1161. else
  1162. LocalFile:=LocalPath+LocalFile;
  1163. if DoVerbose and (rcpprog='pscp') then
  1164. pref:='-v '
  1165. else
  1166. pref:='';
  1167. execres:=ExecuteRemote(rcpprog,pref+RemotePara+' '+LocalFile+' '+
  1168. RemotePathPrefix+RemoteFile,StartTicks,EndTicks);
  1169. if not execres then
  1170. begin
  1171. Verbose(V_normal, 'Could not copy required file '+LocalFile);
  1172. FileList.Free;
  1173. RelativeToConfigMarker.Free;
  1174. exit(false);
  1175. end;
  1176. end;
  1177. end;
  1178. FileList.Free;
  1179. MaybeCopyFiles:=execres;
  1180. RelativeToConfigMarker.Free;
  1181. end;
  1182. function RunExecutable:boolean;
  1183. const
  1184. {$ifdef unix}
  1185. CurrDir = './';
  1186. {$else}
  1187. CurrDir = '';
  1188. {$endif}
  1189. var
  1190. OldDir, s, ss,
  1191. execcmd,
  1192. FullExeLogFile,
  1193. TestRemoteExe,
  1194. TestExe : string;
  1195. execres : boolean;
  1196. EndTicks,
  1197. StartTicks : int64;
  1198. begin
  1199. RunExecutable:=false;
  1200. execres:=true;
  1201. TestExe:=TestOutputFilename('',PPFile[current],ExeExt);
  1202. execres:=MaybeCopyFiles(TestExe);
  1203. if EmulatorName<>'' then
  1204. begin
  1205. { Get full name out log file, because we change the directory during
  1206. execution }
  1207. FullExeLogFile:=FExpand(EXELogFile);
  1208. {$I-}
  1209. GetDir(0,OldDir);
  1210. ChDir(TestOutputDir);
  1211. {$I+}
  1212. ioresult;
  1213. s:=CurrDir+SplitFileName(TestExe);
  1214. { Add -Ssource_file_name for dosbox_wrapper }
  1215. if pos('dosbox_wrapper',EmulatorName)>0 then
  1216. s:=s+' -S'+PPFile[current];
  1217. execres:=ExecuteEmulated(EmulatorName,s,FullExeLogFile,StartTicks,EndTicks);
  1218. {$I-}
  1219. ChDir(OldDir);
  1220. {$I+}
  1221. end
  1222. else if RemoteAddr<>'' then
  1223. begin
  1224. TestRemoteExe:=RemotePath+'/'+SplitFileName(TestExe);
  1225. { rsh doesn't pass the exitcode, use a second command to print the exitcode
  1226. on the remoteshell to stdout }
  1227. if DoVerbose and (rshprog='plink') then
  1228. execcmd:='-v '+RemoteRshParas
  1229. else
  1230. execcmd:=RemoteRshParas;
  1231. execcmd:=execcmd+' '+rquote+
  1232. 'chmod 755 '+TestRemoteExe+
  1233. ' && cd '+RemotePath+' && { ';
  1234. { Using -rpath . at compile time does not seem
  1235. to work for programs copied over to remote machine,
  1236. at least not for FreeBSD.
  1237. Does this work for all shells? }
  1238. if Config.NeedLibrary then
  1239. begin
  1240. if RemoteShellNeedsExport then
  1241. if CompilerTarget='darwin' then
  1242. execcmd:=execcmd+' DYLD_LIBRARY_PATH=.; export DYLD_LIBRARY_PATH;'
  1243. else
  1244. execcmd:=execcmd+' LD_LIBRARY_PATH=.; export LD_LIBRARY_PATH;'
  1245. else
  1246. if CompilerTarget='darwin' then
  1247. execcmd:=execcmd+' setenv DYLD_LIBRARY_PATH=.; '
  1248. else
  1249. execcmd:=execcmd+' setenv LD_LIBRARY_PATH=.; '
  1250. end;
  1251. if UseTimeout then
  1252. begin
  1253. if Config.Timeout=0 then
  1254. Config.Timeout:=DefaultTimeout;
  1255. str(Config.Timeout,s);
  1256. if (RemoteShellBase='bash') then
  1257. execcmd:=execcmd+'ulimit -t '+s+'; '
  1258. else
  1259. execcmd:=execcmd+'timeout -9 '+s;
  1260. end;
  1261. { as we moved to RemotePath, if path is not absolute
  1262. we need to use ./execfilename only }
  1263. if not isabsolute(TestRemoteExe) then
  1264. execcmd:=execcmd+' ./'+SplitFileName(TestRemoteExe)
  1265. else
  1266. execcmd:=execcmd+' '+TestRemoteExe;
  1267. execcmd:=execcmd+' ; echo TestExitCode: $?';
  1268. if (deAfter in DelExecutable) and
  1269. not Config.NeededAfter then
  1270. begin
  1271. execcmd:=execcmd+' ; rm ';
  1272. if rshprog <> 'adb' then
  1273. execcmd:=execcmd+'-f ';
  1274. execcmd:=execcmd+SplitFileName(TestRemoteExe);
  1275. end;
  1276. execcmd:=execcmd+'; }'+rquote;
  1277. execres:=ExecuteRemote(rshprog,execcmd,StartTicks,EndTicks);
  1278. { Check for TestExitCode error in output, sets ExecuteResult }
  1279. if not CheckTestExitCode(EXELogFile) then
  1280. Verbose(V_Debug,'Failed to check exit code for '+execcmd);
  1281. if (deAfter in DelExecutable) and ( (Config.DelFiles <> '') or (Config.Files <> '')) then
  1282. begin
  1283. ss:=Trim(Config.DelFiles + ' ' + Config.Files);
  1284. execcmd:=RemoteRshParas+' ' + rquote + 'cd ' + RemotePath + ' && { ';
  1285. while ss <> '' do
  1286. begin
  1287. s:=Trim(GetToken(ss, [' ',',',';']));
  1288. if s = '' then
  1289. break;
  1290. if ExtractFileExt(s) = '' then
  1291. // If file has no extension, treat it as exe or shared lib
  1292. execcmd:=execcmd + 'rm ' + s + ExeExt + '; rm ' + DllPrefix + s + DllExt
  1293. else
  1294. execcmd:=execcmd + 'rm ' + s;
  1295. execcmd:=execcmd + '; ';
  1296. end;
  1297. ExecuteRemote(rshprog,execcmd+'}'+rquote,StartTicks,EndTicks);
  1298. end;
  1299. end
  1300. else
  1301. begin
  1302. { Get full name out log file, because we change the directory during
  1303. execution }
  1304. FullExeLogFile:=FExpand(EXELogFile);
  1305. Verbose(V_Debug,'Executing '+TestExe);
  1306. {$I-}
  1307. GetDir(0,OldDir);
  1308. ChDir(TestOutputDir);
  1309. {$I+}
  1310. ioresult;
  1311. { don't redirect interactive and graph programs }
  1312. StartTicks:=GetMicroSTicks;
  1313. if Config.IsInteractive or Config.UsesGraph then
  1314. execres:=ExecuteRedir(CurrDir+SplitFileName(TestExe),'','','','')
  1315. else
  1316. execres:=ExecuteRedir(CurrDir+SplitFileName(TestExe),'','',FullExeLogFile,'stdout');
  1317. EndTicks:=GetMicroSTicks;
  1318. {$I-}
  1319. ChDir(OldDir);
  1320. {$I+}
  1321. ioresult;
  1322. end;
  1323. { Error during execution? }
  1324. Verbose(V_Debug,'Exitcode '+ToStr(ExecuteResult));
  1325. if BenchmarkInfo then
  1326. begin
  1327. Verbose(V_Normal,'Execution took '+ToStr(EndTicks-StartTicks)+' us');
  1328. end;
  1329. if (not execres) and (ExecuteResult=0) then
  1330. begin
  1331. AddLog(FailLogFile,TestName);
  1332. AddLog(ResLogFile,failed_to_run+PPFileInfo[current]);
  1333. AddLog(LongLogFile,line_separation);
  1334. AddLog(LongLogFile,failed_to_run+PPFileInfo[current]);
  1335. if CopyFile(EXELogFile,LongLogFile,true)=0 then
  1336. AddLog(LongLogFile,'IOStatus: '+ToStr(IOStatus));
  1337. { avoid to try again }
  1338. AddLog(ExeLogFile,failed_to_run+PPFileInfo[current]);
  1339. Verbose(V_Warning,'IOStatus: '+ToStr(IOStatus));
  1340. exit;
  1341. end;
  1342. if ExecuteResult<>Config.ResultCode then
  1343. begin
  1344. if (ExecuteResult<>0) and
  1345. (ExecuteResult=Config.KnownRunError) then
  1346. begin
  1347. AddLog(FailLogFile,TestName+known_problem+Config.KnownRunNote);
  1348. AddLog(ResLogFile,failed_to_run+PPFileInfo[current]+known_problem+Config.KnownRunNote);
  1349. AddLog(LongLogFile,line_separation);
  1350. AddLog(LongLogFile,known_problem+Config.KnownRunNote);
  1351. AddLog(LongLogFile,failed_to_run+PPFileInfo[current]+' ('+ToStr(ExecuteResult)+')');
  1352. if Copyfile(EXELogFile,LongLogFile,true)=0 then
  1353. begin
  1354. AddLog(LongLogFile,known_problem+'exitcode: '+ToStr(ExecuteResult)+' (expected '+ToStr(Config.ResultCode)+')');
  1355. AddLog(ExeLogFile,known_problem+'exitcode: '+ToStr(ExecuteResult)+' (expected '+ToStr(Config.ResultCode)+')');
  1356. end;
  1357. Verbose(V_Warning,known_problem+'exitcode: '+ToStr(ExecuteResult)+' (expected '+ToStr(Config.ResultCode)+')');
  1358. end
  1359. else
  1360. begin
  1361. AddLog(FailLogFile,TestName);
  1362. AddLog(ResLogFile,failed_to_run+PPFileInfo[current]);
  1363. AddLog(LongLogFile,line_separation);
  1364. AddLog(LongLogFile,failed_to_run+PPFileInfo[current]+' ('+ToStr(ExecuteResult)+')');
  1365. if Copyfile(EXELogFile,LongLogFile,true)=0 then
  1366. begin
  1367. AddLog(LongLogFile,'Exitcode: '+ToStr(ExecuteResult)+' (expected '+ToStr(Config.ResultCode)+')');
  1368. AddLog(ExeLogFile,'Exitcode: '+ToStr(ExecuteResult)+' (expected '+ToStr(Config.ResultCode)+')');
  1369. end;
  1370. Verbose(V_Warning,'Exitcode: '+ToStr(ExecuteResult)+' (expected '+ToStr(Config.ResultCode)+')');
  1371. end
  1372. end
  1373. else
  1374. begin
  1375. AddLog(ResLogFile,successfully_run+PPFileInfo[current]);
  1376. RunExecutable:=true;
  1377. end;
  1378. if (deAfter in DelExecutable) and not Config.NeededAfter then
  1379. begin
  1380. Verbose(V_Debug,'Deleting executable '+TestExe);
  1381. RemoveFile(TestExe);
  1382. RemoveFile(ForceExtension(TestExe,ObjExt));
  1383. RemoveFile(ForceExtension(TestExe,PPUExt));
  1384. end;
  1385. end;
  1386. { Try to collect information concerning the remote configuration
  1387. Currently only records RemoteShell name and sets
  1388. RemoteShellNeedsExport boolean variable }
  1389. procedure SetRemoteConfiguration;
  1390. var
  1391. f : text;
  1392. StartTicks,EndTicks : int64;
  1393. begin
  1394. if RemoteAddr='' then
  1395. exit;
  1396. if rshprog = 'adb' then
  1397. begin
  1398. RemoteShellNeedsExport:=true;
  1399. exit;
  1400. end;
  1401. ExeLogFile:='__remote.tmp';
  1402. ExecuteRemote(rshprog,RemoteRshParas+
  1403. ' "echo SHELL=${SHELL}"',StartTicks,EndTicks);
  1404. Assign(f,ExeLogFile);
  1405. Reset(f);
  1406. While not eof(f) do
  1407. begin
  1408. Readln(f,RemoteShellBase);
  1409. if pos('SHELL=',RemoteShellBase)>0 then
  1410. begin
  1411. RemoteShell:=TrimSpace(Copy(RemoteShellBase,pos('SHELL=',RemoteShellBase)+6,
  1412. length(RemoteShellBase)));
  1413. Verbose(V_Debug,'Remote shell is "'+RemoteShell+'"');
  1414. RemoteShellBase:=SplitFileBase(RemoteShell);
  1415. if (RemoteShellBase='bash') or (RemoteShellBase='sh') then
  1416. RemoteShellNeedsExport:=true;
  1417. end;
  1418. end;
  1419. Close(f);
  1420. end;
  1421. procedure getargs;
  1422. procedure helpscreen;
  1423. begin
  1424. writeln('dotest [Options] <File>');
  1425. writeln;
  1426. writeln('Options can be:');
  1427. writeln(' !ENV_NAME parse environment variable ENV_NAME for options');
  1428. writeln(' -A include ALL tests');
  1429. writeln(' -ADB use ADB to run tests');
  1430. writeln(' -B delete executable before remote upload');
  1431. writeln(' -C<compiler> set compiler to use');
  1432. writeln(' -D display execution time');
  1433. writeln(' -E execute test also');
  1434. writeln(' -G include graph tests');
  1435. writeln(' -I include interactive tests');
  1436. writeln(' -K include known bug tests');
  1437. writeln(' -L<ext> set extension of temporary files (prevent conflicts with parallel invocations)');
  1438. writeln(' -M<emulator> run the tests using the given emulator');
  1439. writeln(' -O use timeout wrapper for (remote) execution');
  1440. writeln(' -P<path> path to the tests tree on the remote machine');
  1441. writeln(' -R<remote> run the tests remotely with the given rsh/ssh address');
  1442. writeln(' -S use ssh instead of rsh');
  1443. writeln(' -T[cpu-]<os> run tests for target cpu and os');
  1444. writeln(' -U<remotepara>');
  1445. writeln(' pass additional parameter to remote program. Multiple -U can be used');
  1446. writeln(' -V be verbose');
  1447. writeln(' -W use putty compatible file names when testing (plink and pscp)');
  1448. writeln(' -X don''t use COMSPEC');
  1449. writeln(' -Y<opts> extra options passed to the compiler. Several -Y<opt> can be given.');
  1450. writeln(' -Z remove temporary files (executable,ppu,o)');
  1451. halt(1);
  1452. end;
  1453. procedure interpret_option (para : string);
  1454. var
  1455. ch : char;
  1456. j : longint;
  1457. begin
  1458. Verbose(V_Debug,'Interpreting option"'+para+'"');
  1459. ch:=Upcase(para[2]);
  1460. delete(para,1,2);
  1461. case ch of
  1462. 'A' :
  1463. if UpperCase(para) = 'DB' then
  1464. begin
  1465. rshprog:='adb';
  1466. rcpprog:='adb';
  1467. rquote:='"';
  1468. if RemoteAddr = '' then
  1469. RemoteAddr:='1'; // fake remote addr (default device will be used)
  1470. end
  1471. else
  1472. begin
  1473. DoGraph:=true;
  1474. DoInteractive:=true;
  1475. DoKnown:=true;
  1476. DoAll:=true;
  1477. end;
  1478. 'B' : Include(DelExecutable,deBefore);
  1479. 'C' : CompilerBin:=Para;
  1480. 'D' : BenchMarkInfo:=true;
  1481. 'E' : DoExecute:=true;
  1482. 'G' : begin
  1483. DoGraph:=true;
  1484. if para='-' then
  1485. DoUsual:=false;
  1486. end;
  1487. 'I' : begin
  1488. DoInteractive:=true;
  1489. if para='-' then
  1490. DoUsual:=false;
  1491. end;
  1492. 'K' : begin
  1493. DoKnown:=true;
  1494. if para='-' then
  1495. DoUsual:=false;
  1496. end;
  1497. 'L' : begin
  1498. UniqueSuffix:=Para;
  1499. end;
  1500. 'M' : EmulatorName:=Para;
  1501. 'O' : UseTimeout:=true;
  1502. 'P' : RemotePath:=Para;
  1503. 'R' : RemoteAddr:=Para;
  1504. 'S' :
  1505. begin
  1506. rshprog:='ssh';
  1507. rcpprog:='scp';
  1508. end;
  1509. 'T' :
  1510. begin
  1511. j:=Pos('-',Para);
  1512. if j>0 then
  1513. begin
  1514. CompilerCPU:=Copy(Para,1,j-1);
  1515. CompilerTarget:=Copy(Para,j+1,length(para));
  1516. end
  1517. else
  1518. CompilerTarget:=Para
  1519. end;
  1520. 'U' :
  1521. RemotePara:=RemotePara+' '+Para;
  1522. 'V' : DoVerbose:=true;
  1523. 'W' :
  1524. begin
  1525. rshprog:='plink';
  1526. rcpprog:='pscp';
  1527. rquote:='"';
  1528. end;
  1529. 'X' : UseComSpec:=false;
  1530. 'Y' : ExtraCompilerOpts:= ExtraCompilerOpts +' '+ Para;
  1531. 'Z' : Include(DelExecutable,deAfter);
  1532. end;
  1533. end;
  1534. procedure interpret_env(arg : string);
  1535. var
  1536. para : string;
  1537. pspace : longint;
  1538. begin
  1539. Verbose(V_Debug,'Interpreting environment option"'+arg+'"');
  1540. { Get rid of leading '!' }
  1541. delete(arg,1,1);
  1542. arg:=getenv(arg);
  1543. Verbose(V_Debug,'Environment value is "'+arg+'"');
  1544. while (length(arg)>0) do
  1545. begin
  1546. while (length(arg)>0) and (arg[1]=' ') do
  1547. delete(arg,1,1);
  1548. pspace:=pos(' ',arg);
  1549. if pspace=0 then
  1550. pspace:=length(arg)+1;
  1551. para:=copy(arg,1,pspace-1);
  1552. if (length(para)>0) and (para[1]='-') then
  1553. interpret_option (para)
  1554. else
  1555. begin
  1556. PPFile.Insert(current,ForceExtension(Para,'pp'));
  1557. inc(current);
  1558. end;
  1559. delete(arg,1,pspace);
  1560. end;
  1561. end;
  1562. var
  1563. param : string;
  1564. i : longint;
  1565. begin
  1566. CompilerBin:='ppc386'+srcexeext;
  1567. for i:=1 to paramcount do
  1568. begin
  1569. param:=Paramstr(i);
  1570. if (param[1]='-') then
  1571. interpret_option(param)
  1572. else if (param[1]='!') then
  1573. interpret_env(param)
  1574. else
  1575. begin
  1576. PPFile.Insert(current,ForceExtension(Param,'pp'));
  1577. inc(current);
  1578. end;
  1579. end;
  1580. if current=0 then
  1581. HelpScreen;
  1582. { disable graph,interactive when running remote }
  1583. if RemoteAddr<>'' then
  1584. begin
  1585. DoGraph:=false;
  1586. DoInteractive:=false;
  1587. end;
  1588. { If we use PuTTY plink program with -load option,
  1589. the IP address or name should not be added to
  1590. the command line }
  1591. if (rshprog='plink') and (pos('-load',RemotePara)>0) then
  1592. RemoteRshParas:=RemotePara
  1593. else
  1594. if rshprog='adb' then
  1595. begin
  1596. if RemoteAddr <> '1' then
  1597. RemotePara:=Trim('-s ' + RemoteAddr + ' ' + RemotePara);
  1598. RemoteRshParas:=Trim(RemotePara + ' shell');
  1599. end
  1600. else
  1601. RemoteRshParas:=RemotePara+' '+RemoteAddr;
  1602. if rcpprog = 'adb' then
  1603. begin
  1604. RemotePathPrefix:='';
  1605. RemotePara:=Trim(RemotePara + ' push');
  1606. end
  1607. else
  1608. RemotePathPrefix:=RemoteAddr + ':';
  1609. end;
  1610. procedure RunTest;
  1611. var
  1612. PPDir,LibraryName,LogSuffix : string;
  1613. Res : boolean;
  1614. begin
  1615. Res:=GetConfig(PPFile[current],Config);
  1616. if Res then
  1617. begin
  1618. Res:=GetCompilerCPU;
  1619. Res:=GetCompilerTarget;
  1620. {$ifndef MACOS}
  1621. RTLUnitsDir:='tstunits/'+CompilerFullTarget;
  1622. {$else MACOS}
  1623. RTLUnitsDir:=':tstunits:'+CompilerFullTarget;
  1624. {$endif MACOS}
  1625. if not PathExists(RTLUnitsDir) then
  1626. Verbose(V_Abort,'Unit path "'+RTLUnitsDir+'" does not exists');
  1627. {$ifndef MACOS}
  1628. OutputDir:='output/'+CompilerFullTarget;
  1629. {$else MACOS}
  1630. OutputDir:=':output:'+CompilerFullTarget;
  1631. {$endif MACOS}
  1632. if not PathExists(OutputDir) then
  1633. Verbose(V_Abort,'Output path "'+OutputDir+'" does not exists');
  1634. { Make subdir in output if needed }
  1635. PPDir:=SplitPath(PPFile[current]);
  1636. if PPDir[length(PPDir)] in ['/','\'{$ifdef MACOS},':'{$endif MACOS}] then
  1637. Delete(PPDir,length(PPDir),1);
  1638. if PPDir<>'' then
  1639. begin
  1640. {$ifndef MACOS}
  1641. TestOutputDir:=OutputDir+'/'+PPDir;
  1642. if UniqueSuffix<>'' then
  1643. TestOutputDir:=TestOutputDir+'/'+UniqueSuffix;
  1644. {$else MACOS}
  1645. TestOutputDir:=OutputDir+PPDir;
  1646. if UniqueSuffix<>'' then
  1647. TestOutputDir:=TestOutputDir+':'+UniqueSuffix;
  1648. {$endif MACOS}
  1649. mkdirtree(TestOutputDir);
  1650. end
  1651. else
  1652. TestOutputDir:=OutputDir;
  1653. if UniqueSuffix<>'' then
  1654. LogSuffix:=UniqueSuffix
  1655. else
  1656. LogSuffix:=SplitBasePath(PPDir)+'log';
  1657. ResLogFile:=OutputFileName('log',LogSuffix);
  1658. LongLogFile:=OutputFileName('longlog',LogSuffix);
  1659. FailLogFile:=OutputFileName('faillist',LogSuffix);
  1660. ForceLog(ResLogFile);
  1661. ForceLog(LongLogFile);
  1662. ForceLog(FailLogFile);
  1663. { Per test logfiles }
  1664. CompilerLogFile:=TestLogFileName('',SplitFileName(PPFile[current]),'log');
  1665. ExeLogFile:=TestLogFileName('',SplitFileName(PPFile[current]),'elg');
  1666. Verbose(V_Debug,'Using Compiler logfile: '+CompilerLogFile);
  1667. Verbose(V_Debug,'Using Execution logfile: '+ExeLogFile);
  1668. end;
  1669. if Res then
  1670. begin
  1671. if Config.UsesGraph and (not DoGraph) then
  1672. begin
  1673. AddLog(ResLogFile,skipping_graph_test+PPFileInfo[current]);
  1674. { avoid a second attempt by writing to elg file }
  1675. AddLog(EXELogFile,skipping_graph_test+PPFileInfo[current]);
  1676. Verbose(V_Warning,skipping_graph_test);
  1677. Res:=false;
  1678. end;
  1679. end;
  1680. if Res then
  1681. begin
  1682. if Config.IsInteractive and (not DoInteractive) then
  1683. begin
  1684. { avoid a second attempt by writing to elg file }
  1685. AddLog(EXELogFile,skipping_interactive_test+PPFileInfo[current]);
  1686. AddLog(ResLogFile,skipping_interactive_test+PPFileInfo[current]);
  1687. Verbose(V_Warning,skipping_interactive_test);
  1688. Res:=false;
  1689. end;
  1690. end;
  1691. if Res then
  1692. begin
  1693. if Config.IsKnownCompileError and (not DoKnown) then
  1694. begin
  1695. { avoid a second attempt by writing to elg file }
  1696. AddLog(EXELogFile,skipping_known_bug+PPFileInfo[current]);
  1697. AddLog(ResLogFile,skipping_known_bug+PPFileInfo[current]);
  1698. Verbose(V_Warning,skipping_known_bug);
  1699. Res:=false;
  1700. end;
  1701. end;
  1702. if Res and not DoUsual then
  1703. res:=(Config.IsInteractive and DoInteractive) or
  1704. (Config.IsKnownRunError and DoKnown) or
  1705. (Config.UsesGraph and DoGraph);
  1706. if Res then
  1707. begin
  1708. if (Config.MinVersion<>'') and not DoAll then
  1709. begin
  1710. Verbose(V_Debug,'Required compiler version: '+Config.MinVersion);
  1711. Res:=GetCompilerVersion;
  1712. if CompilerVersion<Config.MinVersion then
  1713. begin
  1714. { avoid a second attempt by writing to elg file }
  1715. AddLog(EXELogFile,skipping_compiler_version_too_low+PPFileInfo[current]);
  1716. AddLog(ResLogFile,skipping_compiler_version_too_low+PPFileInfo[current]);
  1717. Verbose(V_Warning,'Compiler version too low '+CompilerVersion+' < '+Config.MinVersion);
  1718. Res:=false;
  1719. end;
  1720. end;
  1721. end;
  1722. if Res then
  1723. begin
  1724. if (Config.MaxVersion<>'') and not DoAll then
  1725. begin
  1726. Verbose(V_Debug,'Highest compiler version: '+Config.MaxVersion);
  1727. Res:=GetCompilerVersion;
  1728. if CompilerVersion>Config.MaxVersion then
  1729. begin
  1730. { avoid a second attempt by writing to elg file }
  1731. AddLog(EXELogFile,skipping_compiler_version_too_high+PPFileInfo[current]);
  1732. AddLog(ResLogFile,skipping_compiler_version_too_high+PPFileInfo[current]);
  1733. Verbose(V_Warning,'Compiler version too high '+CompilerVersion+' > '+Config.MaxVersion);
  1734. Res:=false;
  1735. end;
  1736. end;
  1737. end;
  1738. if Res then
  1739. begin
  1740. if Config.NeedCPU<>'' then
  1741. begin
  1742. Verbose(V_Debug,'Required compiler cpu: '+Config.NeedCPU);
  1743. if not IsInList(CompilerCPU,Config.NeedCPU) then
  1744. begin
  1745. { avoid a second attempt by writing to elg file }
  1746. AddLog(EXELogFile,skipping_other_cpu+PPFileInfo[current]);
  1747. AddLog(ResLogFile,skipping_other_cpu+PPFileInfo[current]);
  1748. Verbose(V_Warning,'Compiler cpu "'+CompilerCPU+'" is not in list "'+Config.NeedCPU+'"');
  1749. Res:=false;
  1750. end;
  1751. end;
  1752. end;
  1753. if Res then
  1754. begin
  1755. if Config.SkipCPU<>'' then
  1756. begin
  1757. Verbose(V_Debug,'Skip compiler cpu: '+Config.SkipCPU);
  1758. if IsInList(CompilerCPU,Config.SkipCPU) then
  1759. begin
  1760. { avoid a second attempt by writing to elg file }
  1761. AddLog(EXELogFile,skipping_other_cpu+PPFileInfo[current]);
  1762. AddLog(ResLogFile,skipping_other_cpu+PPFileInfo[current]);
  1763. Verbose(V_Warning,'Compiler cpu "'+CompilerCPU+'" is in list "'+Config.SkipCPU+'"');
  1764. Res:=false;
  1765. end;
  1766. end;
  1767. end;
  1768. if Res then
  1769. begin
  1770. if Config.SkipEmu<>'' then
  1771. begin
  1772. Verbose(V_Debug,'Skip emulator: '+emulatorname);
  1773. if IsInList(emulatorname,Config.SkipEmu) then
  1774. begin
  1775. { avoid a second attempt by writing to elg file }
  1776. AddLog(EXELogFile,skipping_other_cpu+PPFileInfo[current]);
  1777. AddLog(ResLogFile,skipping_other_cpu+PPFileInfo[current]);
  1778. Verbose(V_Warning,'Emulator "'+emulatorname+'" is in list "'+Config.SkipEmu+'"');
  1779. Res:=false;
  1780. end;
  1781. end;
  1782. end;
  1783. if Res then
  1784. begin
  1785. if Config.NeedTarget<>'' then
  1786. begin
  1787. Verbose(V_Debug,'Required compiler target: '+Config.NeedTarget);
  1788. if not IsInList(CompilerTarget,Config.NeedTarget) then
  1789. begin
  1790. { avoid a second attempt by writing to elg file }
  1791. AddLog(EXELogFile,skipping_other_target+PPFileInfo[current]);
  1792. AddLog(ResLogFile,skipping_other_target+PPFileInfo[current]);
  1793. Verbose(V_Warning,'Compiler target "'+CompilerTarget+'" is not in list "'+Config.NeedTarget+'"');
  1794. Res:=false;
  1795. end;
  1796. end;
  1797. end;
  1798. if Res then
  1799. begin
  1800. if Config.SkipTarget<>'' then
  1801. begin
  1802. Verbose(V_Debug,'Skip compiler target: '+Config.SkipTarget);
  1803. if IsInList(CompilerTarget,Config.SkipTarget) then
  1804. begin
  1805. { avoid a second attempt by writing to elg file }
  1806. AddLog(EXELogFile,skipping_other_target+PPFileInfo[current]);
  1807. AddLog(ResLogFile,skipping_other_target+PPFileInfo[current]);
  1808. Verbose(V_Warning,'Compiler target "'+CompilerTarget+'" is in list "'+Config.SkipTarget+'"');
  1809. Res:=false;
  1810. end;
  1811. end;
  1812. end;
  1813. if Res then
  1814. begin
  1815. { Use known bug, to avoid adding a new entry for this PM 2011-06-24 }
  1816. if Config.NeedLibrary and not TargetCanCompileLibraries then
  1817. begin
  1818. AddLog(EXELogFile,skipping_known_bug+PPFileInfo[current]);
  1819. AddLog(ResLogFile,skipping_known_bug+PPFileInfo[current]);
  1820. Verbose(V_Warning,'Compiler target "'+CompilerTarget+'" does not support library compilation');
  1821. Res:=false;
  1822. end;
  1823. end;
  1824. if Res then
  1825. begin
  1826. Res:=RunCompiler('');
  1827. if Res and Config.NeedRecompile then
  1828. Res:=RunCompiler(Config.RecompileOpt);
  1829. end;
  1830. if Res and (not Config.ShouldFail) then
  1831. begin
  1832. if (Config.NoRun) then
  1833. begin
  1834. { avoid a second attempt by writing to elg file }
  1835. AddLog(EXELogFile,skipping_run_test+PPFileInfo[current]);
  1836. AddLog(ResLogFile,skipping_run_test+PPFileInfo[current]);
  1837. Verbose(V_Debug,skipping_run_test);
  1838. if LibraryExists(PPFile[current],LibraryName) then
  1839. MaybeCopyFiles(LibraryName);
  1840. end
  1841. else if Config.IsKnownRunError and (not DoKnown) then
  1842. begin
  1843. { avoid a second attempt by writing to elg file }
  1844. AddLog(EXELogFile,skipping_known_bug+PPFileInfo[current]);
  1845. AddLog(ResLogFile,skipping_known_bug+PPFileInfo[current]);
  1846. Verbose(V_Warning,skipping_known_bug);
  1847. end
  1848. else
  1849. begin
  1850. if DoExecute then
  1851. begin
  1852. if FileExists(TestOutputFilename('',PPFile[current],'ppu')) or
  1853. FileExists(TestOutputFilename('',PPFile[current],'ppo')) or
  1854. FileExists(TestOutputFilename('',PPFile[current],'ppw')) then
  1855. begin
  1856. AddLog(ExeLogFile,skipping_run_unit+PPFileInfo[current]);
  1857. AddLog(ResLogFile,skipping_run_unit+PPFileInfo[current]);
  1858. Verbose(V_Debug,'Unit found, skipping run test')
  1859. end
  1860. else if LibraryExists(PPFile[current],LibraryName) then
  1861. begin
  1862. Verbose(V_Debug,'Library found, skipping run test');
  1863. MaybeCopyFiles(LibraryName);
  1864. end
  1865. else
  1866. Res:=RunExecutable;
  1867. end;
  1868. end;
  1869. end;
  1870. end;
  1871. begin
  1872. Current:=0;
  1873. PPFile:=TStringList.Create;
  1874. PPFile.Capacity:=10;
  1875. PPFileInfo:=TStringList.Create;
  1876. PPFileInfo.Capacity:=10;
  1877. GetArgs;
  1878. SetTargetDirectoriesStyle;
  1879. SetTargetCanCompileLibraries;
  1880. SetRemoteConfiguration;
  1881. {$ifdef LIMIT83fs}
  1882. UseOSOnly:=true;
  1883. {$else not LIMIT83fs}
  1884. SetUseOSOnly;
  1885. {$endif not LIMIT83fs}
  1886. Verbose(V_Debug,'Found '+ToStr(PPFile.Count)+' tests to run');
  1887. if current>0 then
  1888. for current:=0 to PPFile.Count-1 do
  1889. begin
  1890. SetPPFileInfo;
  1891. TestName:=Copy(PPFile[current],1,Pos('.pp',PPFile[current])-1);
  1892. Verbose(V_Normal,'Running test '+TestName+', file '+PPFile[current]);
  1893. RunTest;
  1894. end;
  1895. PPFile.Free;
  1896. PPFileInfo.Free;
  1897. end.