source: trunk/Compiler/Producer.pas

Last change on this file was 75, checked in by chronos, 6 months ago
  • Modified: Removed U prefix from unit names.
  • Modified: Updated Common package.
File size: 3.5 KB
Line 
1unit Producer;
2
3interface
4
5uses
6 SourceCodePascal, Classes, SysUtils, StrUtils, Generics.Collections, Process,
7 FileUtil, Forms;
8
9type
10
11 TWriteTargetEvent = function (Name: string; const Code: string): Boolean of object;
12 TStringEvent = procedure (Value: string) of object;
13
14 { TProducer }
15
16 TProducer = class
17 private
18 FOnProcessOutput: TStringEvent;
19 FOnWriteTarget: TWriteTargetEvent;
20 public
21 Process: TProcess;
22 TextSource: TStringList;
23 IndentationLength: Integer;
24 Indentation: Integer;
25 CompilerPath: string;
26 CompilerParameters: string;
27 procedure Emit(AText: string);
28 procedure EmitLn(AText: string = '');
29 procedure AssignToStringList(Target: TStringList); virtual; abstract;
30 procedure Produce(Module: TSourceModule); virtual; abstract;
31 procedure ExternalExecute(CommandLine: string);
32 constructor Create;
33 destructor Destroy; override;
34 property OnWriteTarget: TWriteTargetEvent read FOnWriteTarget write FOnWriteTarget;
35 property OnProcessOutput: TStringEvent read FOnProcessOutput write FOnProcessOutput;
36 end;
37
38implementation
39
40{ TProducer }
41
42procedure TProducer.EmitLn(AText: string = '');
43begin
44 Emit(AText);
45 TextSource.Add('');
46end;
47
48procedure TProducer.ExternalExecute(CommandLine: string);
49var
50 Buffer: string;
51 Count: Integer;
52 Text: string;
53 Line: string;
54begin
55 if not FileExists(CompilerPath) then Exit;
56 Text := '';
57 try
58 Process := TProcess.Create(nil);
59 //if Path <> '' then
60 // Process.CurrentDirectory := Path;
61 //Path := '';
62 //if Environment <> '' then
63 // Process.Environment.Text := Environment;
64 //Environment := '';
65 Process.CommandLine := CommandLine;
66 Process.Options := [poUsePipes, poNoConsole];
67 Process.Execute;
68 Application.ProcessMessages;
69 while Process.Running or (Process.Output.NumBytesAvailable > 0) or
70 (Process.Stderr.NumBytesAvailable > 0) do
71 begin
72 if Process.Output.NumBytesAvailable > 0 then begin
73 SetLength(Buffer, 1000);
74 Count := Process.Output.Read(Buffer[1], Length(Buffer));
75 SetLength(Buffer, Count);
76 Text := Text + Buffer;
77 while Pos(LineEnding, Text) > 0 do begin
78 Line := Copy(Text, 1, Pos(LineEnding, Text) - 1);
79 Delete(Text, 1, Length(Line) + Length(LineEnding));
80 if Assigned(FOnProcessOutput) then
81 FOnProcessOutput(Line);
82 end;
83 end;
84
85 if Process.Stderr.NumBytesAvailable > 0 then begin
86 SetLength(Buffer, 1000);
87 Count := Process.Stderr.Read(Buffer[1], Length(Buffer));
88 SetLength(Buffer, Count);
89 Text := Text + Buffer;
90 while Pos(LineEnding, Text) > 0 do begin
91 Line := Copy(Text, 1, Pos(LineEnding, Text) - 1);
92 Delete(Text, 1, Length(Line) + Length(LineEnding));
93 if Assigned(FOnProcessOutput) then
94 FOnProcessOutput(Line);
95 end;
96 end;
97 Sleep(10);
98 Application.ProcessMessages;
99 end;
100 finally
101 if Assigned(FOnProcessOutput) then
102 FOnProcessOutput(Text);
103 FreeAndNil(Process);
104 end;
105end;
106
107constructor TProducer.Create;
108begin
109 TextSource := TStringList.Create;
110 IndentationLength := 2;
111 CompilerParameters := '%0:s';
112end;
113
114destructor TProducer.Destroy;
115begin
116 TextSource.Free;
117 inherited Destroy;
118end;
119
120procedure TProducer.Emit(AText: string);
121begin
122 with TextSource do begin
123 if Count = 0 then Add('');
124 if Strings[Count - 1] = '' then
125 Strings[Count - 1] := Strings[Count - 1] + DupeString(' ', IndentationLength * Indentation);
126 Strings[Count - 1] := Strings[Count - 1] + AText;
127 end;
128end;
129
130end.
Note: See TracBrowser for help on using the repository browser.