redir.pp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Test Suite
  4. Copyright (c) 1999-2000 by Pierre Muller
  5. Unit to redirect output and error to files
  6. Adapted from code donated to public domain by Schwartz Gabriel 20/03/1993
  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. Unit Redir;
  14. Interface
  15. {$R-}
  16. {$ifndef Linux}
  17. {$ifndef Unix}
  18. {$S-}
  19. {$endif}
  20. {$endif}
  21. {$ifdef TP}
  22. {$define implemented}
  23. {$endif TP}
  24. {$ifdef Go32v2}
  25. {$define implemented}
  26. {$endif}
  27. {$ifdef Win32}
  28. {$define implemented}
  29. {$endif}
  30. {$ifdef linux}
  31. {$define implemented}
  32. {$endif}
  33. { be sure msdos is not set for FPC compiler }
  34. {$ifdef FPC}
  35. {$UnDef MsDos}
  36. {$endif FPC}
  37. Var
  38. IOStatus : Integer;
  39. RedirErrorOut,RedirErrorIn,
  40. RedirErrorError : Integer;
  41. ExecuteResult : Word;
  42. {------------------------------------------------------------------------------}
  43. procedure InitRedir;
  44. function ExecuteRedir (Const ProgName, ComLine, RedirStdIn, RedirStdOut, RedirStdErr : String) : boolean;
  45. procedure DosExecute(ProgName, ComLine : String);
  46. function ChangeRedirOut(Const Redir : String; AppendToFile : Boolean) : Boolean;
  47. procedure RestoreRedirOut;
  48. procedure DisableRedirOut;
  49. procedure EnableRedirOut;
  50. function ChangeRedirIn(Const Redir : String) : Boolean;
  51. procedure RestoreRedirIn;
  52. procedure DisableRedirIn;
  53. procedure EnableRedirIn;
  54. function ChangeRedirError(Const Redir : String; AppendToFile : Boolean) : Boolean;
  55. procedure RestoreRedirError;
  56. procedure DisableRedirError;
  57. procedure EnableRedirError;
  58. procedure RedirDisableAll;
  59. procedure RedirEnableAll;
  60. Implementation
  61. Uses
  62. {$ifdef go32v2}
  63. go32,
  64. {$endif go32v2}
  65. {$ifdef win32}
  66. windows,
  67. {$endif win32}
  68. {$ifdef unix}
  69. {$ifdef ver1_0}
  70. linux,
  71. {$else}
  72. unix,
  73. {$endif}
  74. {$endif unix}
  75. dos;
  76. var
  77. FIN,FOUT,FERR : ^File;
  78. RedirChangedOut,
  79. RedirChangedIn : Boolean;
  80. RedirChangedError : Boolean;
  81. InRedirDisabled,OutRedirDisabled,ErrorRedirDisabled : Boolean;
  82. {*****************************************************************************
  83. Dos
  84. *****************************************************************************}
  85. {$ifdef implemented}
  86. {$ifdef TP}
  87. {$ifndef win32}
  88. const
  89. UnusedHandle = -1;
  90. StdInputHandle = 0;
  91. StdOutputHandle = 1;
  92. StdErrorHandle = 2;
  93. {$endif win32}
  94. Type
  95. PtrRec = packed record
  96. Ofs, Seg : Word;
  97. end;
  98. PHandles = ^THandles;
  99. THandles = Array [Byte] of Byte;
  100. PWord = ^Word;
  101. Var
  102. MinBlockSize : Word;
  103. MyBlockSize : Word;
  104. Handles : PHandles;
  105. PrefSeg : Word;
  106. OldHandleOut,OldHandleIn,OldHandleError : Byte;
  107. {$endif TP}
  108. var
  109. TempHOut, TempHIn,TempHError : longint;
  110. { For linux the following functions exist
  111. Function Dup(oldfile:longint;var newfile:longint):Boolean;
  112. Function Dup2(oldfile,newfile:longint):Boolean;
  113. Function fdClose(fd:longint):boolean;
  114. }
  115. {$ifdef go32v2}
  116. function dup(fh : longint;var nh : longint) : boolean;
  117. var
  118. Regs : Registers;
  119. begin
  120. Regs.ah:=$45;
  121. Regs.bx:=fh;
  122. MsDos (Regs);
  123. Dup:=true;
  124. If (Regs.Flags and fCarry)=0 then
  125. nh:=Regs.Ax
  126. else
  127. Dup:=false;
  128. end;
  129. function dup2(fh,nh : longint) : boolean;
  130. var
  131. Regs : Registers;
  132. begin
  133. Dup2:=true;
  134. If fh=nh then
  135. exit;
  136. Regs.ah:=$46;
  137. Regs.bx:=fh;
  138. Regs.cx:=nh;
  139. MsDos (Regs);
  140. If (Regs.Flags and fCarry)<>0 then
  141. Dup2:=false;
  142. end;
  143. Function FdClose (Handle : Longint) : boolean;
  144. var Regs: registers;
  145. begin
  146. Regs.Eax := $3e00;
  147. Regs.Ebx := Handle;
  148. MsDos(Regs);
  149. FdClose:=(Regs.Flags and fCarry)=0;
  150. end;
  151. {$endif def go32v2}
  152. {$ifdef win32}
  153. Function FdClose (Handle : Longint) : boolean;
  154. begin
  155. { Do we need this ?? }
  156. FdClose:=true;
  157. end;
  158. {$endif}
  159. {$ifdef TP}
  160. Function FdClose (Handle : Longint) : boolean;
  161. begin
  162. { if executed as under GO32 this hangs the DOS-prompt }
  163. FdClose:=true;
  164. end;
  165. {$endif}
  166. {$I-}
  167. function FileExist(const FileName : PathStr) : Boolean;
  168. var
  169. f : file;
  170. Attr : word;
  171. begin
  172. Assign(f, FileName);
  173. GetFAttr(f, Attr);
  174. FileExist := DosError = 0;
  175. end;
  176. {............................................................................}
  177. function ChangeRedirOut(Const Redir : String; AppendToFile : Boolean) : Boolean;
  178. begin
  179. ChangeRedirOut:=False;
  180. If Redir = '' then Exit;
  181. Assign (FOUT^, Redir);
  182. If AppendToFile and FileExist(Redir) then
  183. Begin
  184. Reset(FOUT^,1);
  185. Seek(FOUT^,FileSize(FOUT^));
  186. End else Rewrite (FOUT^);
  187. RedirErrorOut:=IOResult;
  188. IOStatus:=RedirErrorOut;
  189. If IOStatus <> 0 then Exit;
  190. {$ifndef FPC}
  191. Handles:=Ptr (prefseg, PWord (Ptr (prefseg, $34))^);
  192. OldHandleOut:=Handles^[StdOutputHandle];
  193. Handles^[StdOutputHandle]:=Handles^[FileRec (FOUT^).Handle];
  194. ChangeRedirOut:=True;
  195. OutRedirDisabled:=False;
  196. {$else}
  197. {$ifdef win32}
  198. if SetStdHandle(Std_Output_Handle,FileRec(FOUT^).Handle) then
  199. {$else not win32}
  200. if dup(StdOutputHandle,TempHOut) and
  201. dup2(FileRec(FOUT^).Handle,StdOutputHandle) then
  202. {$endif not win32}
  203. begin
  204. ChangeRedirOut:=True;
  205. OutRedirDisabled:=False;
  206. end;
  207. {$endif def FPC}
  208. RedirChangedOut:=True;
  209. end;
  210. function ChangeRedirIn(Const Redir : String) : Boolean;
  211. begin
  212. ChangeRedirIn:=False;
  213. If Redir = '' then Exit;
  214. Assign (FIN^, Redir);
  215. Reset(FIN^,1);
  216. RedirErrorIn:=IOResult;
  217. IOStatus:=RedirErrorIn;
  218. If IOStatus <> 0 then Exit;
  219. {$ifndef FPC}
  220. Handles:=Ptr (prefseg, PWord (Ptr (prefseg, $34))^);
  221. OldHandleIn:=Handles^[StdInputHandle];
  222. Handles^[StdInputHandle]:=Handles^[FileRec (FIN^).Handle];
  223. ChangeRedirIn:=True;
  224. InRedirDisabled:=False;
  225. {$else}
  226. {$ifdef win32}
  227. if SetStdHandle(Std_Input_Handle,FileRec(FIN^).Handle) then
  228. {$else not win32}
  229. if dup(StdInputHandle,TempHIn) and
  230. dup2(FileRec(FIN^).Handle,StdInputHandle) then
  231. {$endif not win32}
  232. begin
  233. ChangeRedirIn:=True;
  234. InRedirDisabled:=False;
  235. end;
  236. {$endif def FPC}
  237. RedirChangedIn:=True;
  238. end;
  239. function ChangeRedirError(Const Redir : String; AppendToFile : Boolean) : Boolean;
  240. begin
  241. ChangeRedirError:=False;
  242. If Redir = '' then Exit;
  243. Assign (FERR^, Redir);
  244. If AppendToFile and FileExist(Redir) then
  245. Begin
  246. Reset(FERR^,1);
  247. Seek(FERR^,FileSize(FERR^));
  248. End else Rewrite (FERR^);
  249. RedirErrorError:=IOResult;
  250. IOStatus:=RedirErrorError;
  251. If IOStatus <> 0 then Exit;
  252. {$ifndef FPC}
  253. Handles:=Ptr (prefseg, PWord (Ptr (prefseg, $34))^);
  254. OldHandleError:=Handles^[StdErrorHandle];
  255. Handles^[StdErrorHandle]:=Handles^[FileRec (FERR^).Handle];
  256. ChangeRedirError:=True;
  257. ErrorRedirDisabled:=False;
  258. {$else}
  259. {$ifdef win32}
  260. if SetStdHandle(Std_Error_Handle,FileRec(FERR^).Handle) then
  261. {$else not win32}
  262. if dup(StdErrorHandle,TempHError) and
  263. dup2(FileRec(FERR^).Handle,StdErrorHandle) then
  264. {$endif not win32}
  265. begin
  266. ChangeRedirError:=True;
  267. ErrorRedirDisabled:=False;
  268. end;
  269. {$endif}
  270. RedirChangedError:=True;
  271. end;
  272. {$IfDef MsDos}
  273. {Set HeapEnd Pointer to Current Used Heapsize}
  274. Procedure SmallHeap;assembler;
  275. asm
  276. mov bx,word ptr HeapPtr
  277. shr bx,4
  278. inc bx
  279. add bx,word ptr HeapPtr+2
  280. mov ax,PrefixSeg
  281. sub bx,ax
  282. mov es,ax
  283. mov ah,4ah
  284. int 21h
  285. end;
  286. {Set HeapEnd Pointer to Full Heapsize}
  287. Procedure FullHeap;assembler;
  288. asm
  289. mov bx,word ptr HeapEnd
  290. shr bx,4
  291. inc bx
  292. add bx,word ptr HeapEnd+2
  293. mov ax,PrefixSeg
  294. sub bx,ax
  295. mov es,ax
  296. mov ah,4ah
  297. int 21h
  298. end;
  299. {$EndIf MsDos}
  300. procedure RestoreRedirOut;
  301. begin
  302. If not RedirChangedOut then Exit;
  303. {$ifndef FPC}
  304. Handles^[StdOutputHandle]:=OldHandleOut;
  305. OldHandleOut:=StdOutputHandle;
  306. {$else}
  307. {$ifdef win32}
  308. SetStdHandle(Std_Output_Handle,StdOutputHandle);
  309. {$else not win32}
  310. dup2(TempHOut,StdOutputHandle);
  311. {$endif not win32}
  312. {$endif FPC}
  313. Close (FOUT^);
  314. fdClose(TempHOut);
  315. RedirChangedOut:=false;
  316. end;
  317. {............................................................................}
  318. procedure RestoreRedirIn;
  319. begin
  320. If not RedirChangedIn then Exit;
  321. {$ifndef FPC}
  322. Handles^[StdInputHandle]:=OldHandleIn;
  323. OldHandleIn:=StdInputHandle;
  324. {$else}
  325. {$ifdef win32}
  326. SetStdHandle(Std_Input_Handle,StdInputHandle);
  327. {$else not win32}
  328. dup2(TempHIn,StdInputHandle);
  329. {$endif not win32}
  330. {$endif}
  331. Close (FIn^);
  332. fdClose(TempHIn);
  333. RedirChangedIn:=false;
  334. end;
  335. {............................................................................}
  336. procedure DisableRedirIn;
  337. begin
  338. If not RedirChangedIn then Exit;
  339. If InRedirDisabled then Exit;
  340. {$ifndef FPC}
  341. Handles^[StdInputHandle]:=OldHandleIn;
  342. {$else}
  343. {$ifdef win32}
  344. SetStdHandle(Std_Input_Handle,StdInputHandle);
  345. {$else not win32}
  346. dup2(TempHIn,StdInputHandle);
  347. {$endif not win32}
  348. {$endif}
  349. InRedirDisabled:=True;
  350. end;
  351. {............................................................................}
  352. procedure EnableRedirIn;
  353. begin
  354. If not RedirChangedIn then Exit;
  355. If not InRedirDisabled then Exit;
  356. {$ifndef FPC}
  357. Handles:=Ptr (prefseg, PWord (Ptr (prefseg, $34))^);
  358. Handles^[StdInputHandle]:=Handles^[FileRec (FIn^).Handle];
  359. {$else}
  360. {$ifdef win32}
  361. SetStdHandle(Std_Input_Handle,FileRec(FIn^).Handle);
  362. {$else not win32}
  363. dup2(FileRec(FIn^).Handle,StdInputHandle);
  364. {$endif not win32}
  365. {$endif}
  366. InRedirDisabled:=False;
  367. end;
  368. {............................................................................}
  369. procedure DisableRedirOut;
  370. begin
  371. If not RedirChangedOut then Exit;
  372. If OutRedirDisabled then Exit;
  373. {$ifndef FPC}
  374. Handles^[StdOutputHandle]:=OldHandleOut;
  375. {$else}
  376. {$ifdef win32}
  377. SetStdHandle(Std_Output_Handle,StdOutputHandle);
  378. {$else not win32}
  379. dup2(TempHOut,StdOutputHandle);
  380. {$endif not win32}
  381. {$endif}
  382. OutRedirDisabled:=True;
  383. end;
  384. {............................................................................}
  385. procedure EnableRedirOut;
  386. begin
  387. If not RedirChangedOut then Exit;
  388. If not OutRedirDisabled then Exit;
  389. {$ifndef FPC}
  390. Handles:=Ptr (prefseg, PWord (Ptr (prefseg, $34))^);
  391. Handles^[StdOutputHandle]:=Handles^[FileRec (FOut^).Handle];
  392. {$else}
  393. {$ifdef win32}
  394. SetStdHandle(Std_Output_Handle,FileRec(FOut^).Handle);
  395. {$else not win32}
  396. dup2(FileRec(FOut^).Handle,StdOutputHandle);
  397. {$endif not win32}
  398. {$endif}
  399. OutRedirDisabled:=False;
  400. end;
  401. {............................................................................}
  402. procedure RestoreRedirError;
  403. begin
  404. If not RedirChangedError then Exit;
  405. {$ifndef FPC}
  406. Handles^[StdErrorHandle]:=OldHandleError;
  407. OldHandleError:=StdErrorHandle;
  408. {$else}
  409. {$ifdef win32}
  410. SetStdHandle(Std_Error_Handle,StdErrorHandle);
  411. {$else not win32}
  412. dup2(TempHError,StdErrorHandle);
  413. {$endif not win32}
  414. {$endif}
  415. Close (FERR^);
  416. fdClose(TempHError);
  417. RedirChangedError:=false;
  418. end;
  419. {............................................................................}
  420. procedure DisableRedirError;
  421. begin
  422. If not RedirChangedError then Exit;
  423. If ErrorRedirDisabled then Exit;
  424. {$ifndef FPC}
  425. Handles^[StdErrorHandle]:=OldHandleError;
  426. {$else}
  427. {$ifdef win32}
  428. SetStdHandle(Std_Error_Handle,StdErrorHandle);
  429. {$else not win32}
  430. dup2(TempHError,StdErrorHandle);
  431. {$endif not win32}
  432. {$endif}
  433. ErrorRedirDisabled:=True;
  434. end;
  435. {............................................................................}
  436. procedure EnableRedirError;
  437. begin
  438. If not RedirChangedError then Exit;
  439. If not ErrorRedirDisabled then Exit;
  440. {$ifndef FPC}
  441. Handles:=Ptr (prefseg, PWord (Ptr (prefseg, $34))^);
  442. Handles^[StdErrorHandle]:=Handles^[FileRec (FErr^).Handle];
  443. {$else}
  444. {$ifdef win32}
  445. SetStdHandle(Std_Error_Handle,FileRec(FErr^).Handle);
  446. {$else not win32}
  447. dup2(FileRec(FERR^).Handle,StdErrorHandle);
  448. {$endif not win32}
  449. {$endif}
  450. ErrorRedirDisabled:=False;
  451. end;
  452. {............................................................................}
  453. function ExecuteRedir (Const ProgName, ComLine, RedirStdIn, RedirStdOut, RedirStdErr : String) : boolean;
  454. Begin
  455. RedirErrorOut:=0; RedirErrorIn:=0; RedirErrorError:=0;
  456. ExecuteResult:=0;
  457. IOStatus:=0;
  458. if RedirStdIn<>'' then
  459. ChangeRedirIn(RedirStdIn);
  460. if RedirStdOut<>'' then
  461. ChangeRedirOut(RedirStdOut,false);
  462. if RedirStdErr<>'stderr' then
  463. ChangeRedirError(RedirStdErr,false);
  464. DosExecute(ProgName,ComLine);
  465. RestoreRedirOut;
  466. RestoreRedirIn;
  467. RestoreRedirError;
  468. ExecuteRedir:=(IOStatus=0) and (RedirErrorOut=0) and
  469. (RedirErrorIn=0) and (RedirErrorError=0) and
  470. (ExecuteResult=0);
  471. End;
  472. {............................................................................}
  473. procedure RedirDisableAll;
  474. begin
  475. If RedirChangedIn and not InRedirDisabled then
  476. DisableRedirIn;
  477. If RedirChangedOut and not OutRedirDisabled then
  478. DisableRedirOut;
  479. If RedirChangedError and not ErrorRedirDisabled then
  480. DisableRedirError;
  481. end;
  482. {............................................................................}
  483. procedure RedirEnableAll;
  484. begin
  485. If RedirChangedIn and InRedirDisabled then
  486. EnableRedirIn;
  487. If RedirChangedOut and OutRedirDisabled then
  488. EnableRedirOut;
  489. If RedirChangedError and ErrorRedirDisabled then
  490. EnableRedirError;
  491. end;
  492. procedure InitRedir;
  493. begin
  494. {$ifndef FPC}
  495. PrefSeg:=PrefixSeg;
  496. {$endif FPC}
  497. end;
  498. {$else not implemented}
  499. {*****************************************************************************
  500. Fake
  501. *****************************************************************************}
  502. function ExecuteRedir (Const ProgName, ComLine, RedirStdIn, RedirStdOut, RedirStdErr : String) : boolean;
  503. begin
  504. ExecuteRedir:=false;
  505. end;
  506. function ChangeRedirOut(Const Redir : String; AppendToFile : Boolean) : Boolean;
  507. begin
  508. ChangeRedirOut:=false;
  509. end;
  510. procedure RestoreRedirOut;
  511. begin
  512. end;
  513. procedure DisableRedirOut;
  514. begin
  515. end;
  516. procedure EnableRedirOut;
  517. begin
  518. end;
  519. function ChangeRedirIn(Const Redir : String) : Boolean;
  520. begin
  521. ChangeRedirIn:=false;
  522. end;
  523. procedure RestoreRedirIn;
  524. begin
  525. end;
  526. procedure DisableRedirIn;
  527. begin
  528. end;
  529. procedure EnableRedirIn;
  530. begin
  531. end;
  532. function ChangeRedirError(Const Redir : String; AppendToFile : Boolean) : Boolean;
  533. begin
  534. ChangeRedirError:=false;
  535. end;
  536. procedure RestoreRedirError;
  537. begin
  538. end;
  539. procedure DisableRedirError;
  540. begin
  541. end;
  542. procedure EnableRedirError;
  543. begin
  544. end;
  545. procedure RedirDisableAll;
  546. begin
  547. end;
  548. procedure RedirEnableAll;
  549. begin
  550. end;
  551. procedure InitRedir;
  552. begin
  553. end;
  554. {$endif not implemented}
  555. {............................................................................}
  556. procedure DosExecute(ProgName, ComLine : String);
  557. {$ifdef win32}
  558. var
  559. StoreInherit : BOOL;
  560. {$endif win32}
  561. Begin
  562. {$IfDef MsDos}
  563. SmallHeap;
  564. {$EndIf MsDos}
  565. SwapVectors;
  566. { Must use shell() for linux for the wildcard expansion (PFV) }
  567. {$ifdef UNIX}
  568. IOStatus:=0;
  569. ExecuteResult:=Shell(Progname+' '+Comline);
  570. { Signal that causes the stop of the shell }
  571. IOStatus:=ExecuteResult and $7F;
  572. { Exit Code seems to be in the second byte,
  573. is this also true for BSD ??
  574. $80 bit is a CoreFlag apparently }
  575. ExecuteResult:=(ExecuteResult and $ff00) shr 8;
  576. {$else}
  577. {$ifdef win32}
  578. StoreInherit:=ExecInheritsHandles;
  579. ExecInheritsHandles:=true;
  580. {$endif win32}
  581. DosError:=0;
  582. Dos.Exec (Getenv('COMSPEC'),'/C '+progname+' '+Comline);
  583. {$ifdef win32}
  584. ExecInheritsHandles:=StoreInherit;
  585. {$endif win32}
  586. IOStatus:=DosError;
  587. ExecuteResult:=DosExitCode;
  588. {$endif}
  589. SwapVectors;
  590. {$ifdef CPU86}
  591. { reset the FPU }
  592. {$asmmode att}
  593. asm
  594. fninit
  595. end;
  596. {$endif CPU86}
  597. {$IfDef MsDos}
  598. Fullheap;
  599. {$EndIf MsDos}
  600. End;
  601. {*****************************************************************************
  602. Initialize
  603. *****************************************************************************}
  604. initialization
  605. New(FIn); New(FOut); New(FErr);
  606. finalization
  607. Dispose(FIn); Dispose(FOut); Dispose(FErr);
  608. End.
  609. {
  610. $Log$
  611. Revision 1.5 2001-02-03 00:13:34 peter
  612. * linux -> unix for not 1.0.x compilers
  613. Revision 1.4 2000/12/10 12:08:11 peter
  614. * win32 and go32v2 updates
  615. Revision 1.3 2000/11/30 22:38:22 peter
  616. * renamed test suite
  617. Revision 1.1 2000/11/29 23:14:20 peter
  618. * new testsuite setup
  619. }