fpredir.pas 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Integrated Development Environment
  4. Copyright (c) 1998 by Berczi Gabor
  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 FPRedir;
  14. Interface
  15. {$R-}
  16. {$ifndef linux}
  17. {$S-}
  18. {$endif}
  19. {$ifdef TP}
  20. {$define implemented}
  21. {$endif TP}
  22. {$ifdef Go32v2}
  23. {$define implemented}
  24. {$endif}
  25. {$ifdef linux}
  26. {$define implemented}
  27. {$endif}
  28. { be sure msdos is not set for FPC compiler }
  29. {$ifdef FPC}
  30. {$UnDef MsDos}
  31. {$endif FPC}
  32. Var
  33. IOStatus : Integer;
  34. RedirError : Integer;
  35. ExecuteResult : Word;
  36. {------------------------------------------------------------------------------}
  37. function ExecuteRedir (Const ProgName, ComLine, RedirStdOut, RedirStdErr : String) : boolean;
  38. function ChangeRedir(Const Redir : String; AppendToFile : Boolean) : Boolean;
  39. procedure RestoreRedir;
  40. function ChangeErrorRedir(Const Redir : String; AppendToFile : Boolean) : Boolean;
  41. procedure RestoreErrorRedir;
  42. Implementation
  43. Uses
  44. {$ifdef go32v2}
  45. go32,
  46. {$endif go32v2}
  47. {$ifdef linux}
  48. linux,
  49. {$endif linux}
  50. dos;
  51. {*****************************************************************************
  52. Dos
  53. *****************************************************************************}
  54. {$ifdef implemented}
  55. {$ifdef TP}
  56. const
  57. UnusedHandle = -1;
  58. StdInputHandle = 0;
  59. StdOutputHandle = 1;
  60. StdErrorHandle = 2;
  61. Type
  62. PtrRec = packed record
  63. Ofs, Seg : Word;
  64. end;
  65. PHandles = ^THandles;
  66. THandles = Array [Byte] of Byte;
  67. PWord = ^Word;
  68. Var
  69. PrefSeg : Word;
  70. MinBlockSize : Word;
  71. MyBlockSize : Word;
  72. Handles : PHandles;
  73. OldHandle,OldErrorHandle : Byte;
  74. {$endif TP}
  75. Var
  76. F,FE : File;
  77. RedirChanged : Boolean;
  78. RedirErrorChanged : Boolean;
  79. TempH, TempErrorH : longint;
  80. { For linux the following functions exist
  81. Function Dup(oldfile:longint;var newfile:longint):Boolean;
  82. Function Dup2(oldfile,newfile:longint):Boolean; }
  83. {$ifdef go32v2}
  84. function dup(fh : longint;var nh : longint) : boolean;
  85. var
  86. Regs : Registers;
  87. begin
  88. Regs.ah:=$45;
  89. Regs.bx:=fh;
  90. MsDos (Regs);
  91. Dup:=true;
  92. If (Regs.Flags and fCarry)=0 then
  93. nh:=Regs.Ax
  94. else
  95. Dup:=false;
  96. end;
  97. function dup2(fh,nh : longint) : boolean;
  98. var
  99. Regs : Registers;
  100. begin
  101. Dup2:=true;
  102. If fh=nh then
  103. exit;
  104. Regs.ah:=$46;
  105. Regs.bx:=fh;
  106. Regs.cx:=nh;
  107. MsDos (Regs);
  108. If (Regs.Flags and fCarry)<>0 then
  109. Dup2:=false;
  110. end;
  111. {$endif def go32v2}
  112. {$I-}
  113. function FileExist(const FileName : PathStr) : Boolean;
  114. var
  115. f : file;
  116. Attr : word;
  117. begin
  118. Assign(f, FileName);
  119. GetFAttr(f, Attr);
  120. FileExist := DosError = 0;
  121. end;
  122. {............................................................................}
  123. function ChangeRedir(Const Redir : String; AppendToFile : Boolean) : Boolean;
  124. begin
  125. ChangeRedir:=False;
  126. If Redir = '' then Exit;
  127. Assign (F, Redir);
  128. If AppendToFile and FileExist(Redir) then
  129. Begin
  130. Reset(F,1);
  131. Seek(F,FileSize(F));
  132. End else Rewrite (F);
  133. RedirError:=IOResult;
  134. IOStatus:=RedirError;
  135. If IOStatus <> 0 then Exit;
  136. {$ifndef FPC}
  137. Handles:=Ptr (prefseg, PWord (Ptr (prefseg, $34))^);
  138. OldHandle:=Handles^[1];
  139. Handles^[1]:=Handles^[FileRec (F).Handle];
  140. ChangeRedir:=True;
  141. {$else}
  142. if dup(StdOutputHandle,TempH) and
  143. dup2(FileRec(F).Handle,StdOutputHandle) then
  144. ChangeRedir:=True;
  145. {$endif def FPC}
  146. RedirChanged:=True;
  147. end;
  148. function ChangeErrorRedir(Const Redir : String; AppendToFile : Boolean) : Boolean;
  149. begin
  150. ChangeErrorRedir:=False;
  151. If Redir = '' then Exit;
  152. Assign (FE, Redir);
  153. If AppendToFile and FileExist(Redir) then
  154. Begin
  155. Reset(FE,1);
  156. Seek(FE,FileSize(FE));
  157. End
  158. else
  159. Rewrite (FE);
  160. RedirError:=IOResult;
  161. IOStatus:=RedirError;
  162. If IOStatus <> 0 then Exit;
  163. {$ifndef FPC}
  164. Handles:=Ptr (prefseg, PWord (Ptr (prefseg, $34))^);
  165. OldErrorHandle:=Handles^[2];
  166. Handles^[2]:=Handles^[FileRec (FE).Handle];
  167. ChangeErrorRedir:=True;
  168. {$else}
  169. if dup(StdErrorHandle,TempErrorH) and
  170. dup2(FileRec(FE).Handle,StdErrorHandle) then
  171. ChangeErrorRedir:=True;
  172. {$endif}
  173. RedirErrorChanged:=True;
  174. end;
  175. {$IfDef MsDos}
  176. {Set HeapEnd Pointer to Current Used Heapsize}
  177. Procedure SmallHeap;assembler;
  178. asm
  179. mov bx,word ptr HeapPtr
  180. shr bx,4
  181. inc bx
  182. add bx,word ptr HeapPtr+2
  183. mov ax,PrefixSeg
  184. sub bx,ax
  185. mov es,ax
  186. mov ah,4ah
  187. int 21h
  188. end;
  189. {Set HeapEnd Pointer to Full Heapsize}
  190. Procedure FullHeap;assembler;
  191. asm
  192. mov bx,word ptr HeapEnd
  193. shr bx,4
  194. inc bx
  195. add bx,word ptr HeapEnd+2
  196. mov ax,PrefixSeg
  197. sub bx,ax
  198. mov es,ax
  199. mov ah,4ah
  200. int 21h
  201. end;
  202. {$EndIf MsDos}
  203. procedure RestoreRedir;
  204. begin
  205. If not RedirChanged then Exit;
  206. {$ifndef FPC}
  207. Handles^[1]:=OldHandle;
  208. OldHandle:=StdOutputHandle;
  209. {$else}
  210. dup2(TempH,StdOutputHandle);
  211. {$endif}
  212. Close (F);
  213. RedirChanged:=false;
  214. end;
  215. {............................................................................}
  216. procedure RestoreErrorRedir;
  217. begin
  218. If not RedirErrorChanged then Exit;
  219. {$ifndef FPC}
  220. Handles^[2]:=OldErrorHandle;
  221. OldErrorHandle:=StdErrorHandle;
  222. {$else}
  223. dup2(TempErrorH,StdErrorHandle);
  224. {$endif}
  225. Close (FE);
  226. RedirErrorChanged:=false;
  227. end;
  228. {............................................................................}
  229. procedure DosExecute(ProgName, ComLine : String);
  230. Begin
  231. {$IfDef MsDos}
  232. SmallHeap;
  233. {$EndIf MsDos}
  234. SwapVectors;
  235. { Must use shell() for linux for the wildcard expansion (PFV) }
  236. {$ifdef linux}
  237. Shell(Progname+' '+Comline);
  238. {$else}
  239. Dos.Exec (ProgName, ComLine);
  240. {$endif}
  241. IOStatus:=DosError;
  242. ExecuteResult:=DosExitCode;
  243. SwapVectors;
  244. {$IfDef MsDos}
  245. Fullheap;
  246. {$EndIf MsDos}
  247. End;
  248. {............................................................................}
  249. function ExecuteRedir (Const ProgName, ComLine, RedirStdOut, RedirStdErr : String) : boolean;
  250. Begin
  251. RedirError:=0;
  252. ExecuteResult:=0;
  253. IOStatus:=0;
  254. if RedirStdOut<>'' then
  255. ChangeRedir(RedirStdOut,false);
  256. if RedirStdErr<>'stderr' then
  257. RedirErrorChanged:=ChangeErrorRedir(RedirStdErr,false);
  258. DosExecute(ProgName,ComLine);
  259. RestoreRedir;
  260. RestoreErrorRedir;
  261. ExecuteRedir:=(IOStatus=0) and (RedirError=0) and (ExecuteResult=0);
  262. End;
  263. {$else not implemented}
  264. {*****************************************************************************
  265. Linux
  266. *****************************************************************************}
  267. function ExecuteRedir (Const ProgName, ComLine, RedirStdOut, RedirStdErr : String) : boolean;
  268. begin
  269. ExecuteRedir:=false;
  270. end;
  271. function ChangeRedir(Const Redir : String; AppendToFile : Boolean) : Boolean;
  272. begin
  273. ChangeRedir:=false;
  274. end;
  275. procedure RestoreRedir;
  276. begin
  277. end;
  278. function ChangeErrorRedir(Const Redir : String; AppendToFile : Boolean) : Boolean;
  279. begin
  280. ChangeErrorRedir:=false;
  281. end;
  282. procedure RestoreErrorRedir;
  283. begin
  284. end;
  285. procedure InitRedir;
  286. begin
  287. end;
  288. {$endif not implemented}
  289. {*****************************************************************************
  290. Initialize
  291. *****************************************************************************}
  292. End.
  293. {
  294. $Log$
  295. Revision 1.10 1999-02-22 12:46:58 peter
  296. * small fixes for linux and grep
  297. Revision 1.9 1999/02/22 11:12:33 pierre
  298. * dup and dup2 work for go32v2
  299. + also should work for linux (after linux.pp patch)
  300. Revision 1.8 1999/02/22 02:15:18 peter
  301. + default extension for save in the editor
  302. + Separate Text to Find for the grep dialog
  303. * fixed redir crash with tp7
  304. Revision 1.7 1999/02/20 15:18:32 peter
  305. + ctrl-c capture with confirm dialog
  306. + ascii table in the tools menu
  307. + heapviewer
  308. * empty file fixed
  309. * fixed callback routines in fpdebug to have far for tp7
  310. Revision 1.6 1999/02/05 13:51:43 peter
  311. * unit name of FPSwitches -> FPSwitch which is easier to use
  312. * some fixes for tp7 compiling
  313. }