dotest.pp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774
  1. {
  2. $Id$
  3. This file is part of the Free Pascal test suite.
  4. Copyright (c) 1999-2002 by the Free Pascal development team.
  5. This program makes the compilation and
  6. execution of individual test sources.
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. program dotest;
  14. uses
  15. dos,
  16. teststr,
  17. redir;
  18. const
  19. {$ifdef UNIX}
  20. ExeExt='';
  21. {$else UNIX}
  22. ExeExt='exe';
  23. {$endif UNIX}
  24. type
  25. TVerboseLevel=(V_Abort,V_Error,V_Warning,V_Normal,V_Debug);
  26. TConfig = record
  27. NeedOptions,
  28. NeedCPU,
  29. NeedVersion : string;
  30. ResultCode : longint;
  31. NeedRecompile : boolean;
  32. IsInteractive : boolean;
  33. IsKnown : boolean;
  34. NoRun : boolean;
  35. UsesGraph : boolean;
  36. ShouldFail : boolean;
  37. Category : string;
  38. end;
  39. var
  40. Config : TConfig;
  41. CompilerBin : string;
  42. CompilerCPU : string;
  43. CompilerVersion : string;
  44. PPFile : string;
  45. PPFileInfo : string;
  46. TestName : string;
  47. Note : string;
  48. const
  49. LongLogfile : string[32] = 'longlog';
  50. FailLogfile : string[32] = 'faillist';
  51. DoVerbose : boolean = false;
  52. DoGraph : boolean = false;
  53. DoInteractive : boolean = false;
  54. DoExecute : boolean = false;
  55. DoKnown : boolean = false;
  56. procedure Verbose(lvl:TVerboseLevel;const s:string);
  57. begin
  58. case lvl of
  59. V_Normal :
  60. writeln(s);
  61. V_Debug :
  62. if DoVerbose then
  63. writeln('Debug: ',s);
  64. V_Warning :
  65. writeln('Warning: ',s);
  66. V_Error :
  67. begin
  68. writeln('Error: ',s);
  69. halt(1);
  70. end;
  71. V_Abort :
  72. begin
  73. writeln('Abort: ',s);
  74. halt(0);
  75. end;
  76. end;
  77. end;
  78. Function FileExists (Const F : String) : Boolean;
  79. {
  80. Returns True if the file exists, False if not.
  81. }
  82. Var
  83. info : searchrec;
  84. begin
  85. FindFirst (F,anyfile,Info);
  86. FileExists:=DosError=0;
  87. FindClose (Info);
  88. end;
  89. function ToStr(l:longint):string;
  90. var
  91. s : string;
  92. begin
  93. Str(l,s);
  94. ToStr:=s;
  95. end;
  96. function ToStrZero(l:longint;nbzero : byte):string;
  97. var
  98. s : string;
  99. begin
  100. Str(l,s);
  101. while length(s)<nbzero do
  102. s:='0'+s;
  103. ToStrZero:=s;
  104. end;
  105. procedure SetPPFileInfo;
  106. Var
  107. info : searchrec;
  108. dt : DateTime;
  109. begin
  110. FindFirst (PPFile,anyfile,Info);
  111. If DosError=0 then
  112. begin
  113. UnpackTime(info.time,dt);
  114. PPFileInfo:=PPFile+' '+ToStr(dt.year)+'/'+ToStrZero(dt.month,2)+'/'+
  115. ToStrZero(dt.day,2)+' '+ToStrZero(dt.Hour,2)+':'+ToStrZero(dt.min,2)+':'+ToStrZero(dt.sec,2);
  116. end
  117. else
  118. PPFileInfo:=PPfile;
  119. FindClose (Info);
  120. end;
  121. procedure TrimB(var s:string);
  122. begin
  123. while (s<>'') and (s[1] in [' ',#9]) do
  124. delete(s,1,1);
  125. end;
  126. procedure TrimE(var s:string);
  127. begin
  128. while (s<>'') and (s[length(s)] in [' ',#9]) do
  129. delete(s,length(s),1);
  130. end;
  131. function upper(const s : string) : string;
  132. var
  133. i : longint;
  134. begin
  135. for i:=1 to length(s) do
  136. if s[i] in ['a'..'z'] then
  137. upper[i]:=char(byte(s[i])-32)
  138. else
  139. upper[i]:=s[i];
  140. upper[0]:=s[0];
  141. end;
  142. function SplitPath(const s:string):string;
  143. var
  144. i : longint;
  145. begin
  146. i:=Length(s);
  147. while (i>0) and not(s[i] in ['/','\']) do
  148. dec(i);
  149. SplitPath:=Copy(s,1,i);
  150. end;
  151. function ForceExtension(Const HStr,ext:String):String;
  152. {
  153. Return a filename which certainly has the extension ext
  154. }
  155. var
  156. j : longint;
  157. begin
  158. j:=length(Hstr);
  159. while (j>0) and (Hstr[j]<>'.') do
  160. dec(j);
  161. if j=0 then
  162. j:=255;
  163. if Ext<>'' then
  164. ForceExtension:=Copy(Hstr,1,j-1)+'.'+Ext
  165. else
  166. ForceExtension:=Copy(Hstr,1,j-1);
  167. end;
  168. procedure Copyfile(const fn1,fn2:string;append:boolean);
  169. const
  170. bufsize = 16384;
  171. var
  172. f,g : file;
  173. i : longint;
  174. buf : pointer;
  175. begin
  176. if Append then
  177. Verbose(V_Debug,'Appending '+fn1+' to '+fn2)
  178. else
  179. Verbose(V_Debug,'Copying '+fn1+' to '+fn2);
  180. assign(f,fn1);
  181. assign(g,fn2);
  182. {$I-}
  183. reset(f,1);
  184. {$I+}
  185. if ioresult<>0 then
  186. Verbose(V_Error,'Can''t open '+fn1);
  187. if append then
  188. begin
  189. {$I-}
  190. reset(g,1);
  191. {$I+}
  192. if ioresult<>0 then
  193. append:=false
  194. else
  195. seek(g,filesize(g));
  196. end;
  197. if not append then
  198. begin
  199. {$I-}
  200. rewrite(g,1);
  201. {$I+}
  202. if ioresult<>0 then
  203. Verbose(V_Error,'Can''t open '+fn2+' for output');
  204. end;
  205. getmem(buf,bufsize);
  206. repeat
  207. blockread(f,buf^,bufsize,i);
  208. blockwrite(g,buf^,i);
  209. until i<bufsize;
  210. freemem(buf,bufsize);
  211. close(f);
  212. close(g);
  213. end;
  214. procedure AddLog(const logfile,s:string);
  215. var
  216. t : text;
  217. begin
  218. assign(t,logfile);
  219. {$I-}
  220. append(t);
  221. {$I+}
  222. if ioresult<>0 then
  223. begin
  224. {$I-}
  225. rewrite(t);
  226. {$I+}
  227. if ioresult<>0 then
  228. Verbose(V_Abort,'Can''t append to '+logfile);
  229. end;
  230. writeln(t,s);
  231. close(t);
  232. end;
  233. function GetConfig(const fn:string;var r:TConfig):boolean;
  234. var
  235. t : text;
  236. code : integer;
  237. s,res : string;
  238. function GetEntry(const entry:string):boolean;
  239. var
  240. i : longint;
  241. begin
  242. Getentry:=false;
  243. Res:='';
  244. if Upper(Copy(s,1,length(entry)))=Upper(entry) then
  245. begin
  246. Delete(s,1,length(entry));
  247. TrimB(s);
  248. if (s<>'') then
  249. begin
  250. if (s[1]='=') then
  251. begin
  252. delete(s,1,1);
  253. i:=pos('}',s);
  254. if i=0 then
  255. i:=255
  256. else
  257. dec(i);
  258. res:=Copy(s,1,i);
  259. TrimB(res);
  260. TrimE(res);
  261. end;
  262. Verbose(V_Debug,'Config: '+Entry+' = "'+Res+'"');
  263. GetEntry:=true;
  264. end;
  265. end;
  266. end;
  267. begin
  268. FillChar(r,sizeof(r),0);
  269. GetConfig:=false;
  270. Verbose(V_Debug,'Reading '+fn);
  271. assign(t,fn);
  272. {$I-}
  273. reset(t);
  274. {$I+}
  275. if ioresult<>0 then
  276. begin
  277. Verbose(V_Error,'Can''t open '+fn);
  278. exit;
  279. end;
  280. Note:='';
  281. while not eof(t) do
  282. begin
  283. readln(t,s);
  284. if s<>'' then
  285. begin
  286. if s[1]='{' then
  287. begin
  288. delete(s,1,1);
  289. TrimB(s);
  290. if (s<>'') and (s[1]='%') then
  291. begin
  292. delete(s,1,1);
  293. if GetEntry('OPT') then
  294. r.NeedOptions:=res
  295. else
  296. if GetEntry('CPU') then
  297. r.NeedCPU:=res
  298. else
  299. if GetEntry('VERSION') then
  300. r.NeedVersion:=res
  301. else
  302. if GetEntry('RESULT') then
  303. Val(res,r.ResultCode,code)
  304. else
  305. if GetEntry('GRAPH') then
  306. r.UsesGraph:=true
  307. else
  308. if GetEntry('FAIL') then
  309. r.ShouldFail:=true
  310. else
  311. if GetEntry('RECOMPILE') then
  312. r.NeedRecompile:=true
  313. else
  314. if GetEntry('NORUN') then
  315. r.NoRun:=true
  316. else
  317. if GetEntry('KNOWN') then
  318. r.IsKnown:=true
  319. else
  320. if GetEntry('INTERACTIVE') then
  321. r.IsInteractive:=true
  322. else
  323. if GetEntry('NOTE') then
  324. begin
  325. Note:='Note: '+res;
  326. Verbose(V_Normal,Note);
  327. end
  328. else
  329. Verbose(V_Error,'Unknown entry: '+s);
  330. end;
  331. end
  332. else
  333. break;
  334. end;
  335. end;
  336. close(t);
  337. GetConfig:=true;
  338. end;
  339. function GetCompilerVersion:boolean;
  340. var
  341. t : text;
  342. begin
  343. GetCompilerVersion:=false;
  344. ExecuteRedir(CompilerBin,'-iV','','out','');
  345. assign(t,'out');
  346. {$I-}
  347. reset(t);
  348. readln(t,CompilerVersion);
  349. close(t);
  350. erase(t);
  351. {$I+}
  352. if ioresult<>0 then
  353. Verbose(V_Error,'Can''t get Compiler Version')
  354. else
  355. begin
  356. Verbose(V_Debug,'Current Compiler Version: '+CompilerVersion);
  357. GetCompilerVersion:=true;
  358. end;
  359. end;
  360. function GetCompilerCPU:boolean;
  361. var
  362. t : text;
  363. begin
  364. GetCompilerCPU:=false;
  365. ExecuteRedir(CompilerBin,'-iTP','','out','');
  366. assign(t,'out');
  367. {$I-}
  368. reset(t);
  369. readln(t,CompilerCPU);
  370. close(t);
  371. erase(t);
  372. {$I+}
  373. if ioresult<>0 then
  374. Verbose(V_Error,'Can''t get Compiler CPU Target')
  375. else
  376. begin
  377. Verbose(V_Debug,'Current Compiler CPU Target: '+CompilerCPU);
  378. GetCompilerCPU:=true;
  379. end;
  380. end;
  381. function ExitWithInternalError(const OutName:string):boolean;
  382. var
  383. t : text;
  384. s : string;
  385. begin
  386. ExitWithInternalError:=false;
  387. { open logfile }
  388. assign(t,Outname);
  389. {$I-}
  390. reset(t);
  391. {$I+}
  392. if ioresult<>0 then
  393. exit;
  394. while not eof(t) do
  395. begin
  396. readln(t,s);
  397. if pos('Fatal: Internal error ',s)>0 then
  398. begin
  399. ExitWithInternalError:=true;
  400. break;
  401. end;
  402. end;
  403. close(t);
  404. end;
  405. function RunCompiler:boolean;
  406. var
  407. outname,
  408. args : string;
  409. begin
  410. RunCompiler:=false;
  411. OutName:=ForceExtension(PPFile,'log');
  412. args:='-Fuunits';
  413. if Config.NeedOptions<>'' then
  414. args:=args+' '+Config.NeedOptions;
  415. args:=args+' '+ppfile;
  416. Verbose(V_Debug,'Executing '+compilerbin+' '+args);
  417. { also get the output from as and ld that writes to stderr sometimes }
  418. ExecuteRedir(CompilerBin,args,'',OutName,OutName);
  419. Verbose(V_Debug,'Exitcode '+ToStr(ExecuteResult));
  420. { Check for internal error }
  421. if ExitWithInternalError(OutName) then
  422. begin
  423. AddLog(FailLogFile,TestName);
  424. if Note<>'' then
  425. AddLog(FailLogFile,Note);
  426. AddLog(ResLogFile,failed_to_compile+PPFileInfo+' internalerror generated');
  427. AddLog(LongLogFile,line_separation);
  428. AddLog(LongLogFile,failed_to_compile+PPFileInfo);
  429. if Note<>'' then
  430. AddLog(LongLogFile,Note);
  431. CopyFile(OutName,LongLogFile,true);
  432. { avoid to try again }
  433. AddLog(ForceExtension(PPFile,'elg'),'Failed to compile '++PPFileInfo);
  434. Verbose(V_Abort,'Internal error in compiler');
  435. exit;
  436. end;
  437. { Shoud the compile fail ? }
  438. if Config.ShouldFail then
  439. begin
  440. if ExecuteResult<>0 then
  441. begin
  442. AddLog(ResLogFile,success_compilation_failed+PPFileInfo);
  443. { avoid to try again }
  444. AddLog(ForceExtension(PPFile,'elg'),success_compilation_failed+PPFileInfo);
  445. RunCompiler:=true;
  446. end
  447. else
  448. begin
  449. AddLog(FailLogFile,TestName);
  450. if Note<>'' then
  451. AddLog(FailLogFile,Note);
  452. AddLog(ResLogFile,failed_compilation_successful+PPFileInfo);
  453. AddLog(LongLogFile,line_separation);
  454. AddLog(LongLogFile,failed_compilation_successful+PPFileInfo);
  455. { avoid to try again }
  456. AddLog(ForceExtension(PPFile,'elg'),failed_compilation_successful+PPFileInfo);
  457. if Note<>'' then
  458. AddLog(LongLogFile,Note);
  459. CopyFile(OutName,LongLogFile,true);
  460. end;
  461. end
  462. else
  463. begin
  464. if ExecuteResult<>0 then
  465. begin
  466. AddLog(FailLogFile,TestName);
  467. if Note<>'' then
  468. AddLog(FailLogFile,Note);
  469. AddLog(ResLogFile,failed_to_compile+PPFileInfo);
  470. AddLog(LongLogFile,line_separation);
  471. AddLog(LongLogFile,failed_to_compile+PPFileInfo);
  472. if Note<>'' then
  473. AddLog(LongLogFile,Note);
  474. CopyFile(OutName,LongLogFile,true);
  475. { avoid to try again }
  476. AddLog(ForceExtension(PPFile,'elg'),failed_to_compile+PPFileInfo);
  477. Verbose(V_Abort,'Exitcode: '+ToStr(ExecuteResult)+' (expected 0)');
  478. end
  479. else
  480. begin
  481. AddLog(ResLogFile,successfully_compiled+PPFileInfo);
  482. RunCompiler:=true;
  483. end;
  484. end;
  485. end;
  486. function RunExecutable:boolean;
  487. var
  488. outname,
  489. TestExe : string;
  490. begin
  491. RunExecutable:=false;
  492. TestExe:=ForceExtension(PPFile,ExeExt);
  493. OutName:=ForceExtension(PPFile,'elg');
  494. Verbose(V_Debug,'Executing '+TestExe);
  495. ExecuteRedir(TestExe,'','',OutName,'');
  496. Verbose(V_Debug,'Exitcode '+ToStr(ExecuteResult));
  497. if ExecuteResult<>Config.ResultCode then
  498. begin
  499. AddLog(FailLogFile,TestName);
  500. AddLog(ResLogFile,failed_to_run+PPFileInfo);
  501. AddLog(LongLogFile,line_separation);
  502. AddLog(LongLogFile,failed_to_run+PPFileInfo+' ('+ToStr(ExecuteResult)+')');
  503. Copyfile(OutName,LongLogFile,true);
  504. Verbose(V_Abort,'Exitcode: '+ToStr(ExecuteResult)+' (expected '+ToStr(Config.ResultCode)+')');
  505. end
  506. else
  507. begin
  508. AddLog(ResLogFile,successfully_run+PPFileInfo);
  509. RunExecutable:=true;
  510. end;
  511. end;
  512. procedure getargs;
  513. var
  514. ch : char;
  515. para : string;
  516. i : longint;
  517. procedure helpscreen;
  518. begin
  519. writeln('dotest [Options] <File>');
  520. writeln;
  521. writeln('Options can be:');
  522. writeln(' -C<compiler> set compiler to use');
  523. writeln(' -V verbose');
  524. writeln(' -E execute test also');
  525. writeln(' -A include ALL tests');
  526. writeln(' -G include graph tests');
  527. writeln(' -K include known bug tests');
  528. writeln(' -I include interactive tests');
  529. halt(1);
  530. end;
  531. begin
  532. PPFile:='';
  533. if exeext<>'' then
  534. CompilerBin:='ppc386.'+exeext
  535. else
  536. CompilerBin:='ppc386';
  537. for i:=1 to paramcount do
  538. begin
  539. para:=Paramstr(i);
  540. if (para[1]='-') then
  541. begin
  542. ch:=Upcase(para[2]);
  543. delete(para,1,2);
  544. case ch of
  545. 'A' :
  546. begin
  547. DoGraph:=true;
  548. DoInteractive:=true;
  549. DoKnown:=true;
  550. end;
  551. 'C' : CompilerBin:=Para;
  552. 'E' : DoExecute:=true;
  553. 'G' : DoGraph:=true;
  554. 'I' : DoInteractive:=true;
  555. 'V' : DoVerbose:=true;
  556. 'K' : DoKnown:=true;
  557. end;
  558. end
  559. else
  560. begin
  561. If PPFile<>'' then
  562. HelpScreen;
  563. PPFile:=ForceExtension(Para,'pp');
  564. end;
  565. end;
  566. if (PPFile='') then
  567. HelpScreen;
  568. SetPPFileInfo;
  569. TestName:=Copy(PPFile,1,Pos('.pp',PPFile)-1);
  570. Verbose(V_Debug,'Running test '+TestName+', file '+PPFile);
  571. end;
  572. procedure RunTest;
  573. var
  574. Res : boolean;
  575. OutName : string;
  576. begin
  577. Res:=GetConfig(ppfile,Config);
  578. OutName:=ForceExtension(PPFile,'elg');
  579. if Res then
  580. begin
  581. if Config.UsesGraph and (not DoGraph) then
  582. begin
  583. AddLog(ResLogFile,skipping_graph_test+PPFileInfo);
  584. { avoid a second attempt by writing to elg file }
  585. AddLog(OutName,skipping_graph_test+PPFileInfo);
  586. Verbose(V_Abort,skipping_graph_test);
  587. Res:=false;
  588. end;
  589. end;
  590. if Res then
  591. begin
  592. if Config.IsInteractive and (not DoInteractive) then
  593. begin
  594. { avoid a second attempt by writing to elg file }
  595. AddLog(OutName,skipping_interactive_test+PPFileInfo);
  596. AddLog(ResLogFile,skipping_interactive_test+PPFileInfo);
  597. Verbose(V_Abort,skipping_interactive_test);
  598. Res:=false;
  599. end;
  600. end;
  601. if Res then
  602. begin
  603. if Config.IsKnown and (not DoKnown) then
  604. begin
  605. { avoid a second attempt by writing to elg file }
  606. AddLog(OutName,skipping_known_bug+PPFileInfo);
  607. AddLog(ResLogFile,skipping_known_bug+PPFileInfo);
  608. Verbose(V_Abort,skipping_known_bug);
  609. Res:=false;
  610. end;
  611. end;
  612. if Res then
  613. begin
  614. if Config.NeedVersion<>'' then
  615. begin
  616. Verbose(V_Debug,'Required compiler version: '+Config.NeedVersion);
  617. Res:=GetCompilerVersion;
  618. if CompilerVersion<Config.NeedVersion then
  619. begin
  620. { avoid a second attempt by writing to elg file }
  621. AddLog(OutName,skipping_compiler_version_too_low+PPFileInfo);
  622. AddLog(ResLogFile,skipping_compiler_version_too_low+PPFileInfo);
  623. Verbose(V_Abort,'Compiler version too low '+CompilerVersion+' < '+Config.NeedVersion);
  624. Res:=false;
  625. end;
  626. end;
  627. end;
  628. if Res then
  629. begin
  630. if Config.NeedCPU<>'' then
  631. begin
  632. Verbose(V_Debug,'Required compiler cpu: '+Config.NeedCPU);
  633. Res:=GetCompilerCPU;
  634. if Upper(Config.NeedCPU)<>Upper(CompilerCPU) then
  635. begin
  636. { avoid a second attempt by writing to elg file }
  637. AddLog(OutName,skipping_other_cpu+PPFileInfo);
  638. AddLog(ResLogFile,skipping_other_cpu+PPFileInfo);
  639. Verbose(V_Abort,'Compiler cpu wrong '+CompilerCPU+' <> '+Config.NeedCPU);
  640. Res:=false;
  641. end;
  642. end;
  643. end;
  644. if Res then
  645. begin
  646. Res:=RunCompiler;
  647. if Res and Config.NeedRecompile then
  648. Res:=RunCompiler;
  649. end;
  650. if Res then
  651. begin
  652. if (Config.NoRun) then
  653. begin
  654. { avoid a second attempt by writing to elg file }
  655. AddLog(OutName,skipping_run_test+PPFileInfo);
  656. AddLog(ResLogFile,skipping_run_test+PPFileInfo);
  657. Verbose(V_Debug,skipping_run_test);
  658. end
  659. else
  660. begin
  661. if (not Config.ShouldFail) and DoExecute then
  662. begin
  663. if FileExists(ForceExtension(PPFile,'ppu')) or
  664. FileExists(ForceExtension(PPFile,'ppo')) or
  665. FileExists(ForceExtension(PPFile,'ppw')) then
  666. begin
  667. AddLog(ForceExtension(PPFile,'elg'),skipping_run_unit+PPFileInfo);
  668. AddLog(ResLogFile,skipping_run_unit+PPFileInfo);
  669. Verbose(V_Debug,'Unit found, skipping run test')
  670. end
  671. else
  672. Res:=RunExecutable;
  673. end;
  674. end;
  675. end;
  676. end;
  677. begin
  678. GetArgs;
  679. RunTest;
  680. end.
  681. {
  682. $Log$
  683. Revision 1.18 2002-11-14 10:36:12 pierre
  684. * add internalerror info to log file
  685. Revision 1.17 2002/11/13 15:26:24 pierre
  686. + digest program added
  687. Revision 1.16 2002/11/13 15:19:44 pierre
  688. log strings moved to teststr unit
  689. Revision 1.15 2002/09/07 15:40:56 peter
  690. * old logs removed and tabs fixed
  691. Revision 1.14 2002/04/21 18:15:32 peter
  692. * Check for internal errors
  693. Revision 1.13 2002/03/03 13:27:28 hajny
  694. + added support for OS/2 units (.ppo)
  695. Revision 1.12 2002/01/29 13:24:16 pierre
  696. + also generate .elg file for units
  697. Revision 1.11 2002/01/29 12:51:08 pierre
  698. + PPFileInfo to also display time stamp of test file
  699. * generate .elg file in several cases
  700. to avoid trying to recompute the same test
  701. over and over again.
  702. }