Ignore:
Timestamp:
Jul 17, 2012, 6:44:54 AM (12 years ago)
Author:
chronos
Message:
  • Modified: Compiler will accept source code not only from files but it can be feed by in-memory content.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Compiler/UCompiler.pas

    r51 r59  
    1616  end;
    1717
     18  { TSourceFileManager }
     19
     20  TSourceFileManager = class
     21    Files: TListString;
     22    function LoadStringFromFile(FileName: string): string;
     23    procedure SaveStringToFile(FileName: string; Content: string);
     24  public
     25    function GetFileContent(Name: string; var Content: string): Boolean;
     26    function SetFileContent(Name: string; const Content: string): Boolean;
     27    constructor Create;
     28    destructor Destroy; override;
     29  end;
     30
    1831  { TCompilerList }
    1932
     
    2134  private
    2235    FAnalyzer: TAnalyzer;
     36    FOnLoadSource: TGetSourceEvent;
     37    FOnSaveTarget: TWriteTargetEvent;
    2338    FTarget: TTarget;
    2439    FOnErrorMessage: TErrorMessageEvent;
    25     function GetSource(Name: string; var SourceCode: string): Boolean;
    26     function WriteTarget(Name: string; TargetCode: string): Boolean;
    2740    procedure ErrorMessage(Text: string; Position: TPoint; FileName: string);
    2841    procedure SetAnalyzer(const AValue: TAnalyzer);
     
    3851    Targets: TListTarget;
    3952    MainSource: string;
    40     SourceFiles: TListString;
    41     TargetFiles: TListString;
    42     constructor Create;
     53    constructor Create; virtual;
    4354    destructor Destroy; override;
    4455    procedure Init;
     
    4859    property Analyzer: TAnalyzer read FAnalyzer write SetAnalyzer;
    4960    property Target: TTarget read FTarget write SetTarget;
     61    property OnLoadSource: TGetSourceEvent read FOnLoadSource write FOnLoadSource;
     62    property OnSaveTarget: TWriteTargetEvent read FOnSaveTarget write FOnSaveTarget;
    5063  end;
    5164
     
    6073  SRewritingExistedTarget = 'Reqriting existing target file %s';
    6174
     75{ TSourceFileManager }
     76
     77function TSourceFileManager.LoadStringFromFile(FileName: string): string;
     78var
     79  F: TFileStream;
     80begin
     81  try
     82    F := TFileStream.Create(UTF8Decode(FileName), fmOpenRead);
     83    SetLength(Result, F.Size);
     84    if F.Size > 0 then
     85      F.Read(Result[1], F.Size);
     86  finally
     87    F.Free;
     88  end;
     89end;
     90
     91procedure TSourceFileManager.SaveStringToFile(FileName: string; Content: string);
     92var
     93  F: TFileStream;
     94begin
     95  try
     96    ForceDirectoriesUTF8(ExtractFileDir(FileName));
     97    if FileExistsUTF8(FileName) then
     98      F := TFileStream.Create(UTF8Decode(FileName), fmOpenWrite)
     99      else F := TFileStream.Create(UTF8Decode(FileName), fmCreate);
     100    F.Size := 0;
     101    if Length(Content) > 0 then
     102      F.Write(Content[1], Length(Content));
     103  finally
     104    F.Free;
     105  end;
     106end;
     107
     108function TSourceFileManager.GetFileContent(Name: string; var Content: string): Boolean;
     109var
     110  I: Integer;
     111begin
     112  I := 0;
     113  while (I < Files.Count) and (ExtractFileNameOnly(Files[I]) <> Name) do Inc(I);
     114  if I < Files.Count then begin
     115    if FileExistsUTF8(Files[I]) then begin
     116      Content := LoadStringFromFile(Files[I]);
     117      Result := True;
     118    end else Result := False;
     119  end else Result := False;
     120end;
     121
     122function TSourceFileManager.SetFileContent(Name: string; const Content: string
     123  ): Boolean;
     124var
     125  I: Integer;
     126  F: TFileStream;
     127begin
     128  I := 0;
     129  while (I < Files.Count) and (ExtractFileNameOnly(Files[I]) <> Name) do Inc(I);
     130  if I >= Files.Count then begin
     131    SaveStringToFile(Name, Content);
     132    Result := True;
     133    Files.Add(Name);
     134  end else begin
     135    Result := False;
     136    //ErrorMessage(Format(SRewritingExistedTarget, [Name]), Point(0, 0), '');
     137  end;
     138end;
     139
     140constructor TSourceFileManager.Create;
     141begin
     142  Files := TListString.Create;
     143end;
     144
     145destructor TSourceFileManager.Destroy;
     146begin
     147  Files.Free;
     148  inherited Destroy;
     149end;
     150
    62151{ TCompiler }
    63152
    64153procedure TCompiler.Compile;
    65154begin
     155  Analyzer.OnGetSource := OnLoadSource;
    66156  AnalyzeAll;
     157  if Assigned(Target.Producer) then
     158    Target.Producer.OnWriteTarget := OnSaveTarget;
    67159  ProduceAll;
    68160end;
     
    72164  Analyzer := TAnalyzerPascal.Create;
    73165  Targets := TListTarget.Create;
    74   SourceFiles := TListString.Create;
    75   TargetFiles := TListString.Create;
    76166
    77167  RegisterTargets(Self);
     
    94184  Targets.Free;
    95185  ErrorMessages.Free;
    96   SourceFiles.Free;
    97   TargetFiles.Free;
    98 end;
    99 
    100 function TCompiler.GetSource(Name: string; var SourceCode: string): Boolean;
    101 var
    102   I: Integer;
    103   F: TFileStream;
    104 begin
    105   I := 0;
    106   while (I < SourceFiles.Count) and (ExtractFileNameOnly(SourceFiles[I]) <> Name) do Inc(I);
    107   if I < SourceFiles.Count then begin
    108     if FileExistsUTF8(SourceFiles[I]) then
    109       try
    110         F := TFileStream.Create(UTF8Decode(SourceFiles[I]), fmOpenRead);
    111         SetLength(SourceCode, F.Size);
    112         if F.Size > 0 then
    113           F.Read(SourceCode[1], F.Size);
    114         Result := True;
    115       finally
    116         F.Free;
    117       end else Result := False;
    118   end else Result := False;
    119 end;
    120 
    121 function TCompiler.WriteTarget(Name: string; TargetCode: string): Boolean;
    122 var
    123   I: Integer;
    124   F: TFileStream;
    125 begin
    126   I := 0;
    127   while (I < TargetFiles.Count) and (ExtractFileNameOnly(TargetFiles[I]) <> Name) do Inc(I);
    128   if I >= TargetFiles.Count then begin
    129     try
    130       ForceDirectoriesUTF8(ExtractFileDir(Name));
    131       if FileExistsUTF8(Name) then
    132         F := TFileStream.Create(UTF8Decode(Name), fmOpenWrite)
    133         else F := TFileStream.Create(UTF8Decode(Name), fmCreate);
    134       F.Size := 0;
    135       if Length(TargetCode) > 0 then
    136         F.Write(TargetCode[1], Length(TargetCode));
    137       Result := True;
    138       TargetFiles.Add(Name);
    139     finally
    140       F.Free;
    141     end;
    142   end else begin
    143     Result := False;
    144     ErrorMessage(Format(SRewritingExistedTarget, [Name]), Point(0, 0), '');
    145   end;
    146186end;
    147187
     
    164204  if Assigned(Analyzer) then begin
    165205    Analyzer.OnErrorMessage := ErrorMessage;
    166     Analyzer.OnGetSource := GetSource;
     206    Analyzer.OnGetSource := OnLoadSource;
    167207  end;
    168208end;
     
    170210procedure TCompiler.AnalyzeAll;
    171211begin
    172   if (SourceFiles.Count > 0) then begin
     212  if MainSource <> '' then begin
    173213    Analyzer.FileName := MainSource;
    174214    Analyzer.OnGetSource(ExtractFileNameOnly(Analyzer.FileName), Analyzer.SourceCode);
     
    208248  FTarget.Compiler := Self;
    209249  if Assigned(FTarget.Producer) then
    210     FTarget.Producer.OnWriteTarget := WriteTarget;
     250    FTarget.Producer.OnWriteTarget := OnSaveTarget;
    211251end;
    212252
Note: See TracChangeset for help on using the changeset viewer.