Browse Source

* When TProcess is available, pipe compiler console output to log instead of stdout. So that GUI applications can show it

git-svn-id: trunk@19046 -
joost 14 years ago
parent
commit
89f3b4d838
1 changed files with 104 additions and 0 deletions
  1. 104 0
      packages/fppkg/src/pkghandler.pp

+ 104 - 0
packages/fppkg/src/pkghandler.pp

@@ -2,12 +2,27 @@
 {$h+}
 unit pkghandler;
 
+{$IFDEF OS2}
+ {$DEFINE NO_UNIT_PROCESS}
+{$ENDIF OS2}
+
+{$IFDEF GO32V2}
+ {$DEFINE NO_UNIT_PROCESS}
+{$ENDIF GO32V2}
+
+{$ifndef NO_UNIT_PROCESS}
+  {$define HAS_UNIT_PROCESS}
+{$endif NO_UNIT_PROCESS}
+
 interface
 
 uses
   Classes,SysUtils,
   pkgglobals,
   pkgoptions,
+{$ifdef HAS_UNIT_PROCESS}
+  process,
+{$endif HAS_UNIT_PROCESS}
   fprepos;
 
 type
@@ -169,11 +184,100 @@ begin
   FPackageName:=APackageName;
 end;
 
+{$ifdef HAS_UNIT_PROCESS}
+function ExecuteFPC(const Path: string; const ComLine: string): integer;
+var
+  P: TProcess;
+  ConsoleOutput: TMemoryStream;
+  BytesRead: longint;
+
+  function ReadFromStream: longint;
+
+  const
+    READ_BYTES = 2048;
+
+  var
+    n: longint;
+    BuffPos: longint;
+    sLine: string;
+    ch: char;
+  begin
+    // make sure we have room
+    ConsoleOutput.SetSize(BytesRead + READ_BYTES);
+
+    // try reading it
+    n := P.Output.Read((ConsoleOutput.Memory + BytesRead)^, READ_BYTES);
+    if n > 0 then
+    begin
+      Inc(BytesRead, n);
+
+      sLine := '';
+      BuffPos := ConsoleOutput.Position;
+
+      //read lines from the stream
+      repeat
+        ConsoleOutput.Read(ch,1);
+
+        if ch in [#10, #13] then
+        begin
+          log(vlProgres,sLine);
+          sLine := '';
+          BuffPos := ConsoleOutput.Position;
+        end
+        else
+          sLine := sLine + ch;
+
+      until ConsoleOutput.Position >= BytesRead;
+
+      ConsoleOutput.Position := BuffPos;
+    end
+    else
+    begin
+      // no data, wait 100 ms
+      Sleep(100);
+    end;
+
+    Result := n;
+  end;
+
+begin
+  result := -1;
+  BytesRead := 0;
+  ConsoleOutput := TMemoryStream.Create;
+  try
+    P := TProcess.Create(nil);
+    try
+      P.CommandLine := Path + ' ' + ComLine;
+      P.Options := [poUsePipes];
+      P.Execute;
+      while P.Running do
+        ReadFromStream;
+
+      // read last part
+      repeat
+      until ReadFromStream = 0;
+      ConsoleOutput.SetSize(BytesRead);
+
+      result := P.ExitStatus;
+    finally
+      P.Free;
+    end;
+  finally
+    ConsoleOutput.Free;
+  end;
+end;
+{$endif HAS_UNIT_PROCESS}
+
 Function TPackageHandler.ExecuteProcess(Const Prog,Args:String):Integer;
+var T:TProcess;
 begin
   Log(vlCommands,SLogExecute,[Prog,Args]);
   Flush(StdOut);
+{$ifdef HAS_UNIT_PROCESS}
+  Result:=ExecuteFPC(Prog,Args);
+{$else HAS_UNIT_PROCESS}
   Result:=SysUtils.ExecuteProcess(Prog,Args);
+{$endif HAS_UNIT_PROCESS}
 end;