mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-14 07:02:50 +02:00
1782 lines
52 KiB
ObjectPascal
1782 lines
52 KiB
ObjectPascal
{ Copyright (C) 2006 Mattias Gaertner
|
|
|
|
This source is free software; you can redistribute it and/or modify it under
|
|
the terms of the GNU General Public License as published by the Free
|
|
Software Foundation; either version 2 of the License, or (at your option)
|
|
any later version.
|
|
|
|
This code is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
details.
|
|
|
|
A copy of the GNU General Public License is available on the World Wide Web
|
|
at <http://www.gnu.org/copyleft/gpl.html>. You can also obtain it by writing
|
|
to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
|
MA 02111-1307, USA.
|
|
|
|
}
|
|
unit H2PasConvert;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, LCLProc, LResources, LazConfigStorage, XMLPropStorage,
|
|
Forms, Controls, Dialogs, FileUtil, FileProcs, AvgLvlTree,
|
|
// CodeTools
|
|
BasicCodeTools,
|
|
// IDEIntf
|
|
TextTools, IDEExternToolIntf, IDEDialogs, LazIDEIntf, SrcEditorIntf,
|
|
IDEMsgIntf, IDETextConverter;
|
|
|
|
type
|
|
|
|
{ TRemoveCPlusPlusExternCTool }
|
|
|
|
TRemoveCPlusPlusExternCTool = class(TCustomTextConverterTool)
|
|
public
|
|
class function ClassDescription: string; override;
|
|
function Execute(aText: TIDETextConverter): TModalResult; override;
|
|
end;
|
|
|
|
{ TRemoveEmptyCMacrosTool }
|
|
|
|
TRemoveEmptyCMacrosTool = class(TCustomTextConverterTool)
|
|
public
|
|
class function ClassDescription: string; override;
|
|
function Execute(aText: TIDETextConverter): TModalResult; override;
|
|
end;
|
|
|
|
{ TReplaceEdgedBracketPairWithStar }
|
|
|
|
TReplaceEdgedBracketPairWithStar = class(TCustomTextReplaceTool)
|
|
public
|
|
class function ClassDescription: string; override;
|
|
constructor Create(TheOwner: TComponent); override;
|
|
end;
|
|
|
|
{ TReplace0PointerWithNULL }
|
|
|
|
TReplaceMacro0PointerWithNULL = class(TCustomTextConverterTool)
|
|
public
|
|
class function ClassDescription: string; override;
|
|
function Execute(aText: TIDETextConverter): TModalResult; override;
|
|
end;
|
|
|
|
{ TReplaceUnitFilenameWithUnitName }
|
|
|
|
TReplaceUnitFilenameWithUnitName = class(TCustomTextReplaceTool)
|
|
public
|
|
class function ClassDescription: string; override;
|
|
constructor Create(TheOwner: TComponent); override;
|
|
end;
|
|
|
|
{ TRemoveSystemTypes }
|
|
|
|
TRemoveSystemTypes = class(TCustomTextConverterTool)
|
|
public
|
|
class function ClassDescription: string; override;
|
|
function Execute(aText: TIDETextConverter): TModalResult; override;
|
|
end;
|
|
|
|
{ TRemoveRedefinedPointerTypes }
|
|
|
|
TRemoveRedefinedPointerTypes = class(TCustomTextConverterTool)
|
|
public
|
|
class function ClassDescription: string; override;
|
|
function Execute(aText: TIDETextConverter): TModalResult; override;
|
|
end;
|
|
|
|
{ TRemoveEmptyTypeVarConstSections }
|
|
|
|
TRemoveEmptyTypeVarConstSections = class(TCustomTextConverterTool)
|
|
public
|
|
class function ClassDescription: string; override;
|
|
function Execute(aText: TIDETextConverter): TModalResult; override;
|
|
end;
|
|
|
|
TH2PasProject = class;
|
|
TH2PasConverter = class;
|
|
|
|
{ TH2PasFile }
|
|
|
|
TH2PasFile = class(TPersistent)
|
|
private
|
|
FEnabled: boolean;
|
|
FFilename: string;
|
|
FModified: boolean;
|
|
FProject: TH2PasProject;
|
|
procedure SetEnabled(const AValue: boolean);
|
|
procedure SetFilename(const AValue: string);
|
|
procedure SetModified(const AValue: boolean);
|
|
procedure SetProject(const AValue: TH2PasProject);
|
|
public
|
|
constructor Create;
|
|
destructor Destroy; override;
|
|
procedure Clear;
|
|
procedure Assign(Source: TPersistent); override;
|
|
function IsEqual(AFile: TH2PasFile): boolean;
|
|
procedure Load(Config: TConfigStorage);
|
|
procedure Save(Config: TConfigStorage);
|
|
function GetOutputFilename: string;
|
|
function GetOutputDirectory: string;
|
|
function GetOutputExtension: string;
|
|
function GetH2PasParameters(const InputFilename: string = ''): string;
|
|
public
|
|
property Project: TH2PasProject read FProject write SetProject;
|
|
property Filename: string read FFilename write SetFilename;
|
|
property Enabled: boolean read FEnabled write SetEnabled;
|
|
property Modified: boolean read FModified write SetModified;
|
|
end;
|
|
|
|
{ TH2PasProject }
|
|
|
|
TH2PasProject = class(TPersistent)
|
|
private
|
|
FBaseDir: string;
|
|
FCHeaderFiles: TFPList;// list of TH2PasFile
|
|
FCompactOutputmode: boolean;
|
|
FConstantsInsteadOfEnums: boolean;
|
|
FConverter: TH2PasConverter;
|
|
FCreateIncludeFile: boolean;
|
|
FFilename: string;
|
|
FIsVirtual: boolean;
|
|
FLibname: string;
|
|
FModified: boolean;
|
|
FOutputDirectory: string;
|
|
FOutputExt: string;
|
|
FPackAllRecords: boolean;
|
|
FPalmOSSYSTrap: boolean;
|
|
FPforPointers: boolean;
|
|
FPostH2PasTools: TComponent;
|
|
FPreH2PasTools: TComponent;
|
|
FStripComments: boolean;
|
|
FStripCommentsAndInfo: boolean;
|
|
FTforTypedefs: boolean;
|
|
FTforTypedefsRemoveUnderscore: boolean;
|
|
FUseExternal: boolean;
|
|
FUseExternalLibname: boolean;
|
|
FUseProcVarsForImport: boolean;
|
|
FVarParams: boolean;
|
|
FWin32Header: boolean;
|
|
FUseCTypes : boolean;
|
|
function GetCHeaderFileCount: integer;
|
|
function GetCHeaderFiles(Index: integer): TH2PasFile;
|
|
procedure InternalAddCHeaderFile(AFile: TH2PasFile);
|
|
procedure InternalRemoveCHeaderFile(AFile: TH2PasFile);
|
|
procedure SetCompactOutputmode(const AValue: boolean);
|
|
procedure SetConstantsInsteadOfEnums(const AValue: boolean);
|
|
procedure SetCreateIncludeFile(const AValue: boolean);
|
|
procedure SetFilename(const AValue: string);
|
|
procedure SetLibname(const AValue: string);
|
|
procedure SetModified(const AValue: boolean);
|
|
procedure FilenameChanged;
|
|
procedure SetOutputDirectory(const AValue: string);
|
|
procedure SetOutputExt(const AValue: string);
|
|
procedure SetPackAllRecords(const AValue: boolean);
|
|
procedure SetPalmOSSYSTrap(const AValue: boolean);
|
|
procedure SetPforPointers(const AValue: boolean);
|
|
procedure SetStripComments(const AValue: boolean);
|
|
procedure SetStripCommentsAndInfo(const AValue: boolean);
|
|
procedure SetTforTypedefs(const AValue: boolean);
|
|
procedure SetTforTypedefsRemoveUnderscore(const AValue: boolean);
|
|
procedure SetUseExternal(const AValue: boolean);
|
|
procedure SetUseExternalLibname(const AValue: boolean);
|
|
procedure SetUseProcVarsForImport(const AValue: boolean);
|
|
procedure SetVarParams(const AValue: boolean);
|
|
procedure SetWin32Header(const AValue: boolean);
|
|
procedure SetUseCTypes(const AValue: boolean);
|
|
public
|
|
constructor Create;
|
|
destructor Destroy; override;
|
|
procedure Clear(AddDefaults: boolean);
|
|
procedure Assign(Source: TPersistent); override;
|
|
function IsEqual(AProject: TH2PasProject): boolean;
|
|
procedure Load(Config: TConfigStorage);
|
|
procedure Save(Config: TConfigStorage);
|
|
procedure LoadFromFile(const AFilename: string);
|
|
procedure SaveToFile(const AFilename: string);
|
|
procedure AddFiles(List: TStrings);
|
|
procedure DeleteFiles(List: TStrings);
|
|
function CHeaderFileWithFilename(const AFilename: string): TH2PasFile;
|
|
function CHeaderFileIndexWithFilename(const AFilename: string): integer;
|
|
function ShortenFilename(const AFilename: string): string;
|
|
function LongenFilename(const AFilename: string): string;
|
|
function NormalizeFilename(const AFilename: string): string;
|
|
function HasEnabledFiles: boolean;
|
|
procedure AddDefaultPreH2PasTools;
|
|
procedure AddDefaultPostH2PasTools;
|
|
public
|
|
property CHeaderFileCount: integer read GetCHeaderFileCount;
|
|
property CHeaderFiles[Index: integer]: TH2PasFile read GetCHeaderFiles;
|
|
property Modified: boolean read FModified write SetModified;
|
|
property Filename: string read FFilename write SetFilename;
|
|
property BaseDir: string read FBaseDir;
|
|
property IsVirtual: boolean read FIsVirtual;
|
|
property Converter: TH2PasConverter read FConverter;
|
|
property PreH2PasTools: TComponent read FPreH2PasTools;
|
|
property PostH2PasTools: TComponent read FPostH2PasTools;
|
|
|
|
// h2pas options
|
|
property ConstantsInsteadOfEnums: boolean read FConstantsInsteadOfEnums write SetConstantsInsteadOfEnums;
|
|
property CompactOutputmode: boolean read FCompactOutputmode write SetCompactOutputmode;
|
|
property CreateIncludeFile: boolean read FCreateIncludeFile write SetCreateIncludeFile;
|
|
property Libname: string read FLibname write SetLibname;
|
|
property OutputExt: string read FOutputExt write SetOutputExt;
|
|
property PalmOSSYSTrap: boolean read FPalmOSSYSTrap write SetPalmOSSYSTrap;
|
|
property PforPointers: boolean read FPforPointers write SetPforPointers;
|
|
property PackAllRecords: boolean read FPackAllRecords write SetPackAllRecords;
|
|
property StripComments: boolean read FStripComments write SetStripComments;
|
|
property StripCommentsAndInfo: boolean read FStripCommentsAndInfo write SetStripCommentsAndInfo;
|
|
property TforTypedefs: boolean read FTforTypedefs write SetTforTypedefs;
|
|
property TforTypedefsRemoveUnderscore: boolean read FTforTypedefsRemoveUnderscore write SetTforTypedefsRemoveUnderscore;
|
|
property UseExternal: boolean read FUseExternal write SetUseExternal;
|
|
property UseExternalLibname: boolean read FUseExternalLibname write SetUseExternalLibname;
|
|
property UseProcVarsForImport: boolean read FUseProcVarsForImport write SetUseProcVarsForImport;
|
|
property VarParams: boolean read FVarParams write SetVarParams;
|
|
property Win32Header: boolean read FWin32Header write SetWin32Header;
|
|
property UseCTypes: boolean read FUseCTypes write SetUseCTypes;
|
|
property OutputDirectory: string read FOutputDirectory write SetOutputDirectory;
|
|
end;
|
|
|
|
{ TH2PasTool }
|
|
|
|
TH2PasTool = class(TIDEExternalToolOptions)
|
|
private
|
|
FH2PasFile: TH2PasFile;
|
|
FTargetFilename: string;
|
|
public
|
|
property H2PasFile: TH2PasFile read FH2PasFile write FH2PasFile;
|
|
property TargetFilename: string read FTargetFilename write FTargetFilename;
|
|
end;
|
|
|
|
{ TH2PasConverter }
|
|
|
|
TH2PasConverter = class(TPersistent)
|
|
private
|
|
FAutoOpenLastProject: boolean;
|
|
FExecuting: boolean;
|
|
Fh2pasFilename: string;
|
|
FLastUsedFilename: string;
|
|
FModified: boolean;
|
|
FProject: TH2PasProject;
|
|
FProjectHistory: TStrings;
|
|
FWindowBounds: TRect;
|
|
function GetCurrentProjectFilename: string;
|
|
procedure SetAutoOpenLastProject(const AValue: boolean);
|
|
procedure SetCurrentProjectFilename(const AValue: string);
|
|
procedure SetProject(const AValue: TH2PasProject);
|
|
procedure SetProjectHistory(const AValue: TStrings);
|
|
procedure SetWindowBounds(const AValue: TRect);
|
|
procedure Seth2pasFilename(const AValue: string);
|
|
procedure OnParseH2PasLine(Sender: TObject; Line: TIDEScanMessageLine);
|
|
public
|
|
constructor Create;
|
|
destructor Destroy; override;
|
|
procedure Clear;
|
|
procedure Assign(Source: TPersistent); override;
|
|
function IsEqual(AConverter: TH2PasConverter): boolean;
|
|
procedure Load(Config: TConfigStorage);
|
|
procedure Save(Config: TConfigStorage);
|
|
procedure LoadFromFile(const AFilename: string);
|
|
procedure SaveToFile(const AFilename: string);
|
|
procedure LoadProject(const Filename: string);
|
|
procedure SaveProject(const Filename: string);
|
|
function Execute: TModalResult;
|
|
function ConvertFile(AFile: TH2PasFile): TModalResult;
|
|
function GetH2PasFilename: string;
|
|
function FindH2PasErrorMessage: integer;
|
|
function GetH2PasErrorPostion(const Line: string;
|
|
out aFilename: string;
|
|
out LineNumber, Column: integer): boolean;
|
|
function FileIsRelated(const aFilename: string): Boolean;
|
|
public
|
|
property Project: TH2PasProject read FProject write SetProject;
|
|
property ProjectHistory: TStrings read FProjectHistory write SetProjectHistory;
|
|
property CurrentProjectFilename: string read GetCurrentProjectFilename
|
|
write SetCurrentProjectFilename;
|
|
property WindowBounds: TRect read FWindowBounds write SetWindowBounds;
|
|
property AutoOpenLastProject: boolean read FAutoOpenLastProject
|
|
write SetAutoOpenLastProject;
|
|
property h2pasFilename: string read Fh2pasFilename write Seth2pasFilename;
|
|
property Modified: boolean read FModified write FModified;
|
|
property Executing: boolean read FExecuting;
|
|
property LastUsedFilename: string read FLastUsedFilename;
|
|
end;
|
|
|
|
implementation
|
|
|
|
{ TH2PasFile }
|
|
|
|
procedure TH2PasFile.SetFilename(const AValue: string);
|
|
var
|
|
NewValue: String;
|
|
begin
|
|
NewValue:=TrimFilename(AValue);
|
|
if FFilename=NewValue then exit;
|
|
FFilename:=NewValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TH2PasFile.SetEnabled(const AValue: boolean);
|
|
begin
|
|
if FEnabled=AValue then exit;
|
|
FEnabled:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TH2PasFile.SetModified(const AValue: boolean);
|
|
begin
|
|
if FModified=AValue then exit;
|
|
FModified:=AValue;
|
|
if FModified and (Project<>nil) then
|
|
Project.Modified:=true;
|
|
end;
|
|
|
|
procedure TH2PasFile.SetProject(const AValue: TH2PasProject);
|
|
begin
|
|
if FProject=AValue then exit;
|
|
if FProject<>nil then begin
|
|
FProject.InternalRemoveCHeaderFile(Self);
|
|
end;
|
|
FProject:=AValue;
|
|
if FProject<>nil then begin
|
|
FProject.InternalAddCHeaderFile(Self);
|
|
end;
|
|
Modified:=true;
|
|
end;
|
|
|
|
constructor TH2PasFile.Create;
|
|
begin
|
|
Clear;
|
|
end;
|
|
|
|
destructor TH2PasFile.Destroy;
|
|
begin
|
|
if FProject<>nil then begin
|
|
Project:=nil;
|
|
end;
|
|
Clear;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TH2PasFile.Clear;
|
|
begin
|
|
FEnabled:=true;
|
|
FFilename:='';
|
|
FModified:=false;
|
|
end;
|
|
|
|
procedure TH2PasFile.Assign(Source: TPersistent);
|
|
var
|
|
Src: TH2PasFile;
|
|
begin
|
|
if Source is TH2PasFile then begin
|
|
Src:=TH2PasFile(Source);
|
|
if not IsEqual(Src) then begin
|
|
FEnabled:=Src.FEnabled;
|
|
FFilename:=Src.FFilename;
|
|
Modified:=true;
|
|
end;
|
|
end else begin
|
|
inherited Assign(Source);
|
|
end;
|
|
end;
|
|
|
|
function TH2PasFile.IsEqual(AFile: TH2PasFile): boolean;
|
|
begin
|
|
Result:=(CompareFilenames(Filename,AFile.Filename)=0)
|
|
and (Enabled=AFile.Enabled);
|
|
end;
|
|
|
|
procedure TH2PasFile.Load(Config: TConfigStorage);
|
|
begin
|
|
FEnabled:=Config.GetValue('Enabled/Value',true);
|
|
FFilename:=Config.GetValue('Filename/Value','');
|
|
if Project<>nil then
|
|
FFilename:=Project.NormalizeFilename(FFilename);
|
|
FModified:=false;
|
|
end;
|
|
|
|
procedure TH2PasFile.Save(Config: TConfigStorage);
|
|
var
|
|
AFilename: String;
|
|
begin
|
|
Config.SetDeleteValue('Enabled/Value',Enabled,true);
|
|
AFilename:=FFilename;
|
|
if Project<>nil then
|
|
AFilename:=Project.ShortenFilename(AFilename);
|
|
Config.SetDeleteValue('Filename/Value',AFilename,'');
|
|
FModified:=false;
|
|
end;
|
|
|
|
function TH2PasFile.GetOutputFilename: string;
|
|
begin
|
|
Result:=GetOutputDirectory+ExtractFileNameOnly(Filename)+GetOutputExtension;
|
|
end;
|
|
|
|
function TH2PasFile.GetOutputDirectory: string;
|
|
begin
|
|
Result:=Project.OutputDirectory;
|
|
if Result='' then
|
|
Result:=Project.BaseDir;
|
|
end;
|
|
|
|
function TH2PasFile.GetOutputExtension: string;
|
|
begin
|
|
Result:=Project.OutputExt;
|
|
end;
|
|
|
|
function TH2PasFile.GetH2PasParameters(const InputFilename: string): string;
|
|
|
|
procedure Add(const AnOption: string);
|
|
begin
|
|
if Result<>'' then
|
|
Result:=Result+' ';
|
|
Result:=Result+AnOption;
|
|
end;
|
|
|
|
begin
|
|
Result:='';
|
|
if Project.ConstantsInsteadOfEnums then Add('-e');
|
|
if Project.CompactOutputmode then Add('-c');
|
|
if Project.CreateIncludeFile then Add('-i');
|
|
if Project.PalmOSSYSTrap then Add('-x');
|
|
if Project.PforPointers then Add('-p');
|
|
if Project.PackAllRecords then Add('-pr');
|
|
if Project.StripComments then Add('-s');
|
|
if Project.StripCommentsAndInfo then Add('-S');
|
|
if Project.TforTypedefs then Add('-t');
|
|
if Project.TforTypedefsRemoveUnderscore then Add('-T');
|
|
if Project.UseExternal then Add('-d');
|
|
if Project.UseExternalLibname then Add('-D');
|
|
if Project.UseProcVarsForImport then Add('-P');
|
|
if Project.VarParams then Add('-v');
|
|
if Project.Win32Header then Add('-w');
|
|
if Project.UseCTypes then Add('-C');
|
|
if Project.Libname<>'' then Add('-l '+Project.Libname);
|
|
Add('-o '+GetOutputFilename);
|
|
if InputFilename<>'' then
|
|
Add(InputFilename)
|
|
else
|
|
Add(Filename);
|
|
end;
|
|
|
|
{ TH2PasProject }
|
|
|
|
function TH2PasProject.GetCHeaderFileCount: integer;
|
|
begin
|
|
Result:=FCHeaderFiles.Count;
|
|
end;
|
|
|
|
function TH2PasProject.GetCHeaderFiles(Index: integer): TH2PasFile;
|
|
begin
|
|
Result:=TH2PasFile(FCHeaderFiles[Index]);
|
|
end;
|
|
|
|
procedure TH2PasProject.InternalAddCHeaderFile(AFile: TH2PasFile);
|
|
begin
|
|
FCHeaderFiles.Add(AFile);
|
|
end;
|
|
|
|
procedure TH2PasProject.InternalRemoveCHeaderFile(AFile: TH2PasFile);
|
|
begin
|
|
FCHeaderFiles.Remove(AFile);
|
|
end;
|
|
|
|
procedure TH2PasProject.SetCompactOutputmode(const AValue: boolean);
|
|
begin
|
|
if FCompactOutputmode=AValue then exit;
|
|
FCompactOutputmode:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TH2PasProject.SetConstantsInsteadOfEnums(const AValue: boolean);
|
|
begin
|
|
if FConstantsInsteadOfEnums=AValue then exit;
|
|
FConstantsInsteadOfEnums:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TH2PasProject.SetCreateIncludeFile(const AValue: boolean);
|
|
begin
|
|
if FCreateIncludeFile=AValue then exit;
|
|
FCreateIncludeFile:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TH2PasProject.SetFilename(const AValue: string);
|
|
var
|
|
NewValue: String;
|
|
begin
|
|
NewValue:=TrimFilename(AValue);
|
|
if FFilename=NewValue then exit;
|
|
FFilename:=NewValue;
|
|
FilenameChanged;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TH2PasProject.SetLibname(const AValue: string);
|
|
begin
|
|
if FLibname=AValue then exit;
|
|
FLibname:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TH2PasProject.SetModified(const AValue: boolean);
|
|
begin
|
|
if FModified=AValue then exit;
|
|
FModified:=AValue;
|
|
end;
|
|
|
|
procedure TH2PasProject.FilenameChanged;
|
|
begin
|
|
FIsVirtual:=(FFilename='') or (not FilenameIsAbsolute(FFilename));
|
|
FBaseDir:=ExtractFilePath(FFilename);
|
|
end;
|
|
|
|
procedure TH2PasProject.SetOutputDirectory(const AValue: string);
|
|
begin
|
|
if FOutputDirectory=AValue then exit;
|
|
FOutputDirectory:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TH2PasProject.SetOutputExt(const AValue: string);
|
|
begin
|
|
if FOutputExt=AValue then exit;
|
|
FOutputExt:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TH2PasProject.SetPackAllRecords(const AValue: boolean);
|
|
begin
|
|
if FPackAllRecords=AValue then exit;
|
|
FPackAllRecords:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TH2PasProject.SetPalmOSSYSTrap(const AValue: boolean);
|
|
begin
|
|
if FPalmOSSYSTrap=AValue then exit;
|
|
FPalmOSSYSTrap:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TH2PasProject.SetPforPointers(const AValue: boolean);
|
|
begin
|
|
if FPforPointers=AValue then exit;
|
|
FPforPointers:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TH2PasProject.SetStripComments(const AValue: boolean);
|
|
begin
|
|
if FStripComments=AValue then exit;
|
|
FStripComments:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TH2PasProject.SetStripCommentsAndInfo(const AValue: boolean);
|
|
begin
|
|
if FStripCommentsAndInfo=AValue then exit;
|
|
FStripCommentsAndInfo:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TH2PasProject.SetTforTypedefs(const AValue: boolean);
|
|
begin
|
|
if FTforTypedefs=AValue then exit;
|
|
FTforTypedefs:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TH2PasProject.SetTforTypedefsRemoveUnderscore(const AValue: boolean);
|
|
begin
|
|
if FTforTypedefsRemoveUnderscore=AValue then exit;
|
|
FTforTypedefsRemoveUnderscore:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TH2PasProject.SetUseExternal(const AValue: boolean);
|
|
begin
|
|
if FUseExternal=AValue then exit;
|
|
FUseExternal:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TH2PasProject.SetUseExternalLibname(const AValue: boolean);
|
|
begin
|
|
if FUseExternalLibname=AValue then exit;
|
|
FUseExternalLibname:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TH2PasProject.SetUseProcVarsForImport(const AValue: boolean);
|
|
begin
|
|
if FUseProcVarsForImport=AValue then exit;
|
|
FUseProcVarsForImport:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TH2PasProject.SetVarParams(const AValue: boolean);
|
|
begin
|
|
if FVarParams=AValue then exit;
|
|
FVarParams:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TH2PasProject.SetWin32Header(const AValue: boolean);
|
|
begin
|
|
if FWin32Header=AValue then exit;
|
|
FWin32Header:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TH2PasProject.SetUseCTypes(const AValue: boolean);
|
|
begin
|
|
if FUseCTypes=AValue then exit;
|
|
FUseCTypes:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
constructor TH2PasProject.Create;
|
|
begin
|
|
FCHeaderFiles:=TFPList.Create;
|
|
Clear(true);
|
|
end;
|
|
|
|
destructor TH2PasProject.Destroy;
|
|
begin
|
|
Clear(false);
|
|
if (Converter<>nil) and (Converter.Project=Self) then
|
|
Converter.Project:=nil;
|
|
FreeAndNil(FCHeaderFiles);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TH2PasProject.Clear(AddDefaults: boolean);
|
|
begin
|
|
// FFilename is kept
|
|
FConstantsInsteadOfEnums:=true;
|
|
FCompactOutputmode:=false;
|
|
FCreateIncludeFile:=true;
|
|
FLibname:='';
|
|
FOutputExt:='.inc';
|
|
FPackAllRecords:=false;
|
|
FPalmOSSYSTrap:=false;
|
|
FPforPointers:=true;
|
|
FStripComments:=false;
|
|
FStripCommentsAndInfo:=false;
|
|
FTforTypedefs:=false;
|
|
FTforTypedefsRemoveUnderscore:=false;
|
|
FUseExternal:=false;
|
|
FUseExternalLibname:=true;
|
|
FUseProcVarsForImport:=false;
|
|
FVarParams:=false;
|
|
FWin32Header:=true;
|
|
FUseCTypes:=false;
|
|
FOutputDirectory:='';
|
|
while CHeaderFileCount>0 do
|
|
CHeaderFiles[CHeaderFileCount-1].Free;
|
|
FPreH2PasTools.Free;
|
|
FPreH2PasTools:=TComponent.Create(nil);
|
|
FPostH2PasTools.Free;
|
|
FPostH2PasTools:=TComponent.Create(nil);
|
|
if AddDefaults then begin
|
|
AddDefaultPreH2PasTools;
|
|
AddDefaultPostH2PasTools;
|
|
end;
|
|
FModified:=false;
|
|
end;
|
|
|
|
procedure TH2PasProject.Assign(Source: TPersistent);
|
|
|
|
procedure CopyTools(SrcList: TComponent; var DestList: TComponent);
|
|
var
|
|
SrcComponent: TComponent;
|
|
NewComponent: TObject;
|
|
i: Integer;
|
|
begin
|
|
DestList.Free;
|
|
DestList:=TComponent.Create(nil);
|
|
for i:=0 to SrcList.ComponentCount-1 do begin
|
|
SrcComponent:=SrcList.Components[i];
|
|
if SrcComponent is TCustomTextConverterTool then begin
|
|
NewComponent:=
|
|
TComponentClass(SrcComponent.ClassType).Create(DestList);
|
|
TCustomTextConverterTool(NewComponent).Assign(SrcComponent);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
var
|
|
Src: TH2PasProject;
|
|
i: Integer;
|
|
NewCHeaderFile: TH2PasFile;
|
|
begin
|
|
if Source is TH2PasProject then begin
|
|
Src:=TH2PasProject(Source);
|
|
if not IsEqual(Src) then begin
|
|
// FFilename is kept
|
|
FConstantsInsteadOfEnums:=Src.FConstantsInsteadOfEnums;
|
|
FCompactOutputmode:=Src.FCompactOutputmode;
|
|
FCreateIncludeFile:=Src.FCreateIncludeFile;
|
|
FLibname:=Src.FLibname;
|
|
FOutputExt:=Src.FOutputExt;
|
|
FPackAllRecords:=Src.FPackAllRecords;
|
|
FPalmOSSYSTrap:=Src.FPalmOSSYSTrap;
|
|
FPforPointers:=Src.FPforPointers;
|
|
FStripComments:=Src.FStripComments;
|
|
FStripCommentsAndInfo:=Src.FStripCommentsAndInfo;
|
|
FTforTypedefs:=Src.FTforTypedefs;
|
|
FTforTypedefsRemoveUnderscore:=Src.FTforTypedefsRemoveUnderscore;
|
|
FUseExternal:=Src.FUseExternal;
|
|
FUseExternalLibname:=Src.FUseExternalLibname;
|
|
FUseProcVarsForImport:=Src.FUseProcVarsForImport;
|
|
FVarParams:=Src.FVarParams;
|
|
FWin32Header:=Src.FWin32Header;
|
|
FUseCTypes:=Src.FUseCTypes;
|
|
FOutputDirectory:=Src.FOutputDirectory;
|
|
Clear(false);
|
|
for i:=0 to Src.CHeaderFileCount-1 do begin
|
|
NewCHeaderFile:=TH2PasFile.Create;
|
|
NewCHeaderFile.Project:=Self;
|
|
NewCHeaderFile.Assign(Src.CHeaderFiles[i]);
|
|
end;
|
|
CopyTools(Src.FPreH2PasTools,FPreH2PasTools);
|
|
CopyTools(Src.FPostH2PasTools,FPostH2PasTools);
|
|
Modified:=true;
|
|
end;
|
|
end else begin
|
|
inherited Assign(Source);
|
|
end;
|
|
end;
|
|
|
|
function TH2PasProject.IsEqual(AProject: TH2PasProject): boolean;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
Result:=(AProject.CHeaderFileCount=CHeaderFileCount)
|
|
and (FConstantsInsteadOfEnums=AProject.FConstantsInsteadOfEnums)
|
|
and (FCompactOutputmode=AProject.FCompactOutputmode)
|
|
and (FCreateIncludeFile=AProject.FCreateIncludeFile)
|
|
and (FLibname=AProject.FLibname)
|
|
and (FOutputExt=AProject.FOutputExt)
|
|
and (FPackAllRecords=AProject.FPackAllRecords)
|
|
and (FPalmOSSYSTrap=AProject.FPalmOSSYSTrap)
|
|
and (FPforPointers=AProject.FPforPointers)
|
|
and (FStripComments=AProject.FStripComments)
|
|
and (FStripCommentsAndInfo=AProject.FStripCommentsAndInfo)
|
|
and (FTforTypedefs=AProject.FTforTypedefs)
|
|
and (FTforTypedefsRemoveUnderscore=AProject.FTforTypedefsRemoveUnderscore)
|
|
and (FUseExternal=AProject.FUseExternal)
|
|
and (FUseExternalLibname=AProject.FUseExternalLibname)
|
|
and (FUseProcVarsForImport=AProject.FUseProcVarsForImport)
|
|
and (FVarParams=AProject.FVarParams)
|
|
and (FWin32Header=AProject.FWin32Header)
|
|
and (FUseCTypes=AProject.FUseCTypes)
|
|
and (FOutputDirectory=AProject.FOutputDirectory);
|
|
if not Result then exit;
|
|
for i:=0 to CHeaderFileCount-1 do
|
|
if not CHeaderFiles[i].IsEqual(AProject.CHeaderFiles[i]) then
|
|
exit(false);
|
|
if (not CompareComponents(FPreH2PasTools,AProject.FPreH2PasTools))
|
|
or (not CompareComponents(FPostH2PasTools,AProject.FPostH2PasTools)) then
|
|
exit(false);
|
|
end;
|
|
|
|
procedure TH2PasProject.Load(Config: TConfigStorage);
|
|
procedure LoadTools(const SubPath: string; List: TComponent);
|
|
var
|
|
NewComponent: TComponent;
|
|
NewCount: LongInt;
|
|
i: Integer;
|
|
begin
|
|
// load PreH2PasTools
|
|
Config.AppendBasePath(SubPath);
|
|
try
|
|
NewCount:=Config.GetValue('Count',0);
|
|
for i:=0 to NewCount-1 do begin
|
|
Config.AppendBasePath('Tool'+IntToStr(i+1));
|
|
try
|
|
NewComponent:=nil;
|
|
LoadComponentFromConfig(Config,'Value',NewComponent,
|
|
@TextConverterToolClasses.FindClass,List);
|
|
finally
|
|
Config.UndoAppendBasePath;
|
|
end;
|
|
end;
|
|
finally
|
|
Config.UndoAppendBasePath;
|
|
end;
|
|
end;
|
|
|
|
var
|
|
NewCount: LongInt;
|
|
i: Integer;
|
|
NewCHeaderFile: TH2PasFile;
|
|
begin
|
|
Clear(false);
|
|
|
|
// FFilename is not saved
|
|
FConstantsInsteadOfEnums:=Config.GetValue('ConstantsInsteadOfEnums/Value',true);
|
|
FCompactOutputmode:=Config.GetValue('CompactOutputmode/Value',false);
|
|
FCreateIncludeFile:=Config.GetValue('CreateIncludeFile/Value',true);
|
|
FLibname:=Config.GetValue('Libname/Value','');
|
|
FOutputExt:=Config.GetValue('OutputExt/Value','.inc');
|
|
FPackAllRecords:=Config.GetValue('PackAllRecords/Value',false);
|
|
FPalmOSSYSTrap:=Config.GetValue('PalmOSSYSTrap/Value',false);
|
|
FPforPointers:=Config.GetValue('PforPointers/Value',true);
|
|
FStripComments:=Config.GetValue('StripComments/Value',false);
|
|
FStripCommentsAndInfo:=Config.GetValue('StripCommentsAndInfo/Value',false);
|
|
FTforTypedefs:=Config.GetValue('TforTypedefs/Value',false);
|
|
FTforTypedefsRemoveUnderscore:=Config.GetValue('TforTypedefsRemoveUnderscore/Value',false);
|
|
FUseExternal:=Config.GetValue('UseExternal/Value',false);
|
|
FUseExternalLibname:=Config.GetValue('UseExternalLibname/Value',true);
|
|
FUseProcVarsForImport:=Config.GetValue('UseProcVarsForImport/Value',false);
|
|
FVarParams:=Config.GetValue('VarParams/Value',false);
|
|
FWin32Header:=Config.GetValue('Win32Header/Value',true);
|
|
FUseCTypes:=Config.GetValue('UseCTypes/Value',false);
|
|
FOutputDirectory:=NormalizeFilename(Config.GetValue('OutputDirectory/Value',''));
|
|
|
|
// load CHeaderFiles
|
|
Config.AppendBasePath('CHeaderFiles');
|
|
try
|
|
NewCount:=Config.GetValue('Count',0);
|
|
for i:=0 to NewCount-1 do begin
|
|
Config.AppendBasePath('File'+IntToStr(i+1));
|
|
try
|
|
NewCHeaderFile:=TH2PasFile.Create;
|
|
NewCHeaderFile.Project:=Self;
|
|
NewCHeaderFile.Load(Config);
|
|
finally
|
|
Config.UndoAppendBasePath;
|
|
end;
|
|
end;
|
|
finally
|
|
Config.UndoAppendBasePath;
|
|
end;
|
|
|
|
LoadTools('PreH2PasTools',FPreH2PasTools);
|
|
LoadTools('PostH2PasTools',FPostH2PasTools);
|
|
|
|
FModified:=false;
|
|
end;
|
|
|
|
procedure TH2PasProject.Save(Config: TConfigStorage);
|
|
|
|
procedure SaveTools(const SubPath: string; List: TComponent);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
Config.AppendBasePath(SubPath);
|
|
try
|
|
Config.SetDeleteValue('Count',List.ComponentCount,0);
|
|
for i:=0 to List.ComponentCount-1 do begin
|
|
Config.AppendBasePath('Tool'+IntToStr(i+1));
|
|
try
|
|
SaveComponentToConfig(Config,'Value',List.Components[i]);
|
|
finally
|
|
Config.UndoAppendBasePath;
|
|
end;
|
|
end;
|
|
finally
|
|
Config.UndoAppendBasePath;
|
|
end;
|
|
end;
|
|
|
|
var
|
|
i: Integer;
|
|
begin
|
|
// FFilename is kept
|
|
Config.SetDeleteValue('ConstantsInsteadOfEnums/Value',FConstantsInsteadOfEnums,true);
|
|
Config.SetDeleteValue('CompactOutputmode/Value',FCompactOutputmode,false);
|
|
Config.SetDeleteValue('CreateIncludeFile/Value',FCreateIncludeFile,true);
|
|
Config.SetDeleteValue('Libname/Value',FLibname,'');
|
|
Config.SetDeleteValue('OutputExt/Value',FOutputExt,'.inc');
|
|
Config.SetDeleteValue('PackAllRecords/Value',FPackAllRecords,false);
|
|
Config.SetDeleteValue('PalmOSSYSTrap/Value',FPalmOSSYSTrap,false);
|
|
Config.SetDeleteValue('PforPointers/Value',FPforPointers,true);
|
|
Config.SetDeleteValue('StripComments/Value',FStripComments,false);
|
|
Config.SetDeleteValue('StripCommentsAndInfo/Value',FStripCommentsAndInfo,false);
|
|
Config.SetDeleteValue('TforTypedefs/Value',FTforTypedefs,false);
|
|
Config.SetDeleteValue('TforTypedefsRemoveUnderscore/Value',FTforTypedefsRemoveUnderscore,false);
|
|
Config.SetDeleteValue('UseExternal/Value',FUseExternal,false);
|
|
Config.SetDeleteValue('UseExternalLibname/Value',FUseExternalLibname,true);
|
|
Config.SetDeleteValue('UseProcVarsForImport/Value',FUseProcVarsForImport,false);
|
|
Config.SetDeleteValue('VarParams/Value',FVarParams,false);
|
|
Config.SetDeleteValue('Win32Header/Value',FWin32Header,true);
|
|
Config.SetDeleteValue('UseCTypes/Value',FUseCTypes,false);
|
|
Config.SetDeleteValue('OutputDirectory/Value',ShortenFilename(FOutputDirectory),'');
|
|
|
|
// save CHeaderFiles
|
|
Config.AppendBasePath('CHeaderFiles');
|
|
try
|
|
Config.SetDeleteValue('Count',CHeaderFileCount,0);
|
|
for i:=0 to CHeaderFileCount-1 do begin
|
|
Config.AppendBasePath('File'+IntToStr(i+1));
|
|
try
|
|
CHeaderFiles[i].Save(Config);
|
|
finally
|
|
Config.UndoAppendBasePath;
|
|
end;
|
|
end;
|
|
finally
|
|
Config.UndoAppendBasePath;
|
|
end;
|
|
|
|
SaveTools('PreH2PasTools',FPreH2PasTools);
|
|
SaveTools('PostH2PasTools',FPostH2PasTools);
|
|
FModified:=false;
|
|
end;
|
|
|
|
procedure TH2PasProject.LoadFromFile(const AFilename: string);
|
|
var
|
|
Config: TXMLConfigStorage;
|
|
begin
|
|
Config:=TXMLConfigStorage.Create(AFilename,true);
|
|
try
|
|
Load(Config);
|
|
finally
|
|
Config.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TH2PasProject.SaveToFile(const AFilename: string);
|
|
var
|
|
Config: TXMLConfigStorage;
|
|
begin
|
|
Config:=TXMLConfigStorage.Create(AFilename,false);
|
|
try
|
|
Save(Config);
|
|
DebugLn(['TH2PasProject.SaveToFile ',AFilename]);
|
|
Config.WriteToDisk;
|
|
finally
|
|
Config.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TH2PasProject.AddFiles(List: TStrings);
|
|
var
|
|
i: Integer;
|
|
NewFilename: string;
|
|
NewFile: TH2PasFile;
|
|
begin
|
|
if List=nil then exit;
|
|
for i:=0 to List.Count-1 do begin
|
|
NewFilename:=CleanAndExpandFilename(List[i]);
|
|
if (NewFilename='') or (not FileExists(NewFilename)) then exit;
|
|
if CHeaderFileWithFilename(NewFilename)<>nil then exit;
|
|
NewFile:=TH2PasFile.Create;
|
|
NewFile.Project:=Self;
|
|
NewFile.Filename:=NewFilename;
|
|
end;
|
|
end;
|
|
|
|
procedure TH2PasProject.DeleteFiles(List: TStrings);
|
|
var
|
|
i: Integer;
|
|
NewFilename: String;
|
|
CurFile: TH2PasFile;
|
|
begin
|
|
if List=nil then exit;
|
|
for i:=0 to List.Count-1 do begin
|
|
NewFilename:=CleanAndExpandFilename(List[i]);
|
|
if (NewFilename='') then exit;
|
|
CurFile:=CHeaderFileWithFilename(NewFilename);
|
|
if CurFile<>nil then begin
|
|
CurFile.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TH2PasProject.CHeaderFileWithFilename(const AFilename: string
|
|
): TH2PasFile;
|
|
var
|
|
i: LongInt;
|
|
begin
|
|
i:=CHeaderFileIndexWithFilename(AFilename);
|
|
if i>=0 then
|
|
Result:=CHeaderFiles[i]
|
|
else
|
|
Result:=nil;
|
|
end;
|
|
|
|
function TH2PasProject.CHeaderFileIndexWithFilename(const AFilename: string
|
|
): integer;
|
|
begin
|
|
Result:=CHeaderFileCount-1;
|
|
while (Result>=0)
|
|
and (CompareFilenames(AFilename,CHeaderFiles[Result].Filename)<>0) do
|
|
dec(Result);
|
|
end;
|
|
|
|
function TH2PasProject.ShortenFilename(const AFilename: string): string;
|
|
begin
|
|
if IsVirtual then
|
|
Result:=AFilename
|
|
else
|
|
Result:=CreateRelativePath(AFilename,fBaseDir);
|
|
end;
|
|
|
|
function TH2PasProject.LongenFilename(const AFilename: string): string;
|
|
begin
|
|
if IsVirtual then
|
|
Result:=AFilename
|
|
else if not FilenameIsAbsolute(AFilename) then
|
|
Result:=TrimFilename(BaseDir+AFilename);
|
|
end;
|
|
|
|
function TH2PasProject.NormalizeFilename(const AFilename: string): string;
|
|
begin
|
|
Result:=LongenFilename(SetDirSeparators(AFilename));
|
|
end;
|
|
|
|
function TH2PasProject.HasEnabledFiles: boolean;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
for i:=0 to CHeaderFileCount-1 do
|
|
if CHeaderFiles[i].Enabled then exit(true);
|
|
Result:=false;
|
|
end;
|
|
|
|
procedure TH2PasProject.AddDefaultPreH2PasTools;
|
|
begin
|
|
AddNewTextConverterTool(FPreH2PasTools,TRemoveCPlusPlusExternCTool);
|
|
AddNewTextConverterTool(FPreH2PasTools,TRemoveEmptyCMacrosTool);
|
|
AddNewTextConverterTool(FPreH2PasTools,TReplaceEdgedBracketPairWithStar);
|
|
AddNewTextConverterTool(FPreH2PasTools,TReplaceMacro0PointerWithNULL);
|
|
end;
|
|
|
|
procedure TH2PasProject.AddDefaultPostH2PasTools;
|
|
begin
|
|
AddNewTextConverterTool(FPostH2PasTools,TReplaceUnitFilenameWithUnitName);
|
|
AddNewTextConverterTool(FPostH2PasTools,TRemoveSystemTypes);
|
|
AddNewTextConverterTool(FPostH2PasTools,TRemoveRedefinedPointerTypes);
|
|
AddNewTextConverterTool(FPostH2PasTools,TRemoveEmptyTypeVarConstSections);
|
|
end;
|
|
|
|
{ TH2PasConverter }
|
|
|
|
procedure TH2PasConverter.OnParseH2PasLine(Sender: TObject;
|
|
Line: TIDEScanMessageLine);
|
|
var
|
|
Tool: TH2PasTool;
|
|
LineNumber: String;
|
|
MsgType: String;
|
|
Msg: String;
|
|
begin
|
|
if Line.Tool is TH2PasTool then begin
|
|
Tool:=TH2PasTool(Line.Tool);
|
|
if REMatches(Line.Line,'^at line ([0-9]+) (error) : (.*)$') then begin
|
|
LineNumber:=REVar(1);
|
|
MsgType:=REVar(2);
|
|
Msg:=REVar(3);
|
|
Line.Line:=Tool.TargetFilename+'('+LineNumber+') '+MsgType+': '+Msg;
|
|
end;
|
|
//DebugLn(['TH2PasConverter.OnParseH2PasLine ',Line.Line]);
|
|
end;
|
|
end;
|
|
|
|
function TH2PasConverter.GetCurrentProjectFilename: string;
|
|
begin
|
|
if FProjectHistory.Count>0 then
|
|
Result:=FProjectHistory[FProjectHistory.Count-1]
|
|
else
|
|
Result:='';
|
|
end;
|
|
|
|
procedure TH2PasConverter.SetAutoOpenLastProject(const AValue: boolean);
|
|
begin
|
|
if FAutoOpenLastProject=AValue then exit;
|
|
FAutoOpenLastProject:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TH2PasConverter.SetCurrentProjectFilename(const AValue: string);
|
|
const
|
|
ProjectHistoryMax=30;
|
|
var
|
|
NewValue: String;
|
|
begin
|
|
NewValue:=TrimFilename(AValue);
|
|
if NewValue='' then exit;
|
|
if CompareFilenames(GetCurrentProjectFilename,NewValue)=0 then exit;
|
|
FProjectHistory.Add(NewValue);
|
|
while FProjectHistory.Count>ProjectHistoryMax do
|
|
FProjectHistory.Delete(0);
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TH2PasConverter.SetProject(const AValue: TH2PasProject);
|
|
begin
|
|
if FProject=AValue then exit;
|
|
if FProject<>nil then begin
|
|
FProject.fConverter:=nil;
|
|
end;
|
|
FProject:=AValue;
|
|
if FProject<>nil then begin
|
|
FProject.fConverter:=Self;
|
|
if FProject.Filename<>'' then
|
|
CurrentProjectFilename:=FProject.Filename;
|
|
end;
|
|
end;
|
|
|
|
procedure TH2PasConverter.SetProjectHistory(const AValue: TStrings);
|
|
begin
|
|
if FProjectHistory=AValue then exit;
|
|
FProjectHistory.Assign(AValue);
|
|
end;
|
|
|
|
procedure TH2PasConverter.SetWindowBounds(const AValue: TRect);
|
|
begin
|
|
if CompareRect(@FWindowBounds,@AValue) then exit;
|
|
FWindowBounds:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TH2PasConverter.Seth2pasFilename(const AValue: string);
|
|
begin
|
|
if Fh2pasFilename=AValue then exit;
|
|
Fh2pasFilename:=AValue;
|
|
Modified:=true;
|
|
end;
|
|
|
|
constructor TH2PasConverter.Create;
|
|
begin
|
|
FProjectHistory:=TStringList.Create;
|
|
Clear;
|
|
end;
|
|
|
|
destructor TH2PasConverter.Destroy;
|
|
begin
|
|
FreeAndNil(FProject);
|
|
Clear;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TH2PasConverter.Clear;
|
|
begin
|
|
FAutoOpenLastProject:=true;
|
|
if FProject<>nil then FreeAndNil(FProject);
|
|
FProjectHistory.Clear;
|
|
FWindowBounds:=Rect(0,0,0,0);
|
|
Fh2pasFilename:='h2pas';
|
|
FModified:=false;
|
|
end;
|
|
|
|
procedure TH2PasConverter.Assign(Source: TPersistent);
|
|
var
|
|
Src: TH2PasConverter;
|
|
begin
|
|
if Source is TH2PasConverter then begin
|
|
Src:=TH2PasConverter(Source);
|
|
if not IsEqual(Src) then begin
|
|
Clear;
|
|
// Note: project is kept unchanged
|
|
FProjectHistory.Assign(Src.FProjectHistory);
|
|
FWindowBounds:=Src.FWindowBounds;
|
|
Fh2pasFilename:=Src.Fh2pasFilename;
|
|
Modified:=true;
|
|
end;
|
|
end else begin
|
|
inherited Assign(Source);
|
|
end;
|
|
end;
|
|
|
|
function TH2PasConverter.IsEqual(AConverter: TH2PasConverter): boolean;
|
|
begin
|
|
if (FAutoOpenLastProject<>AConverter.FAutoOpenLastProject)
|
|
or (not CompareRect(@FWindowBounds,@AConverter.FWindowBounds))
|
|
or (Fh2pasFilename<>AConverter.h2pasFilename)
|
|
or (not FProjectHistory.Equals(AConverter.FProjectHistory))
|
|
then
|
|
exit(false);
|
|
Result:=true;
|
|
end;
|
|
|
|
procedure TH2PasConverter.Load(Config: TConfigStorage);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
FAutoOpenLastProject:=Config.GetValue('AutoOpenLastProject/Value',true);
|
|
Fh2pasFilename:=Config.GetValue('h2pas/Filename','h2pas');
|
|
Config.GetValue('WindowBounds/',FWindowBounds,Rect(0,0,0,0));
|
|
Config.GetValue('ProjectHistory/',FProjectHistory);
|
|
for i:=FProjectHistory.Count-1 downto 0 do
|
|
if FProjectHistory[i]='' then FProjectHistory.Delete(i);
|
|
|
|
// Note: project is saved in its own file
|
|
end;
|
|
|
|
procedure TH2PasConverter.Save(Config: TConfigStorage);
|
|
begin
|
|
Config.SetDeleteValue('AutoOpenLastProject/Value',FAutoOpenLastProject,true);
|
|
Config.SetDeleteValue('h2pas/Filename',Fh2pasFilename,'h2pas');
|
|
Config.SetDeleteValue('WindowBounds/',FWindowBounds,Rect(0,0,0,0));
|
|
Config.SetValue('ProjectHistory/',FProjectHistory);
|
|
end;
|
|
|
|
procedure TH2PasConverter.LoadFromFile(const AFilename: string);
|
|
var
|
|
Config: TXMLConfigStorage;
|
|
begin
|
|
Config:=TXMLConfigStorage.Create(AFilename,true);
|
|
try
|
|
Load(Config);
|
|
finally
|
|
Config.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TH2PasConverter.SaveToFile(const AFilename: string);
|
|
var
|
|
Config: TXMLConfigStorage;
|
|
begin
|
|
Config:=TXMLConfigStorage.Create(AFilename,false);
|
|
try
|
|
Save(Config);
|
|
Config.WriteToDisk;
|
|
finally
|
|
Config.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TH2PasConverter.LoadProject(const Filename: string);
|
|
begin
|
|
DebugLn(['TH2PasConverter.LoadProject ',Filename]);
|
|
if FProject=nil then
|
|
FProject:=TH2PasProject.Create;
|
|
FProject.Filename:=Filename;
|
|
FProject.LoadFromFile(Filename);
|
|
CurrentProjectFilename:=Filename;
|
|
end;
|
|
|
|
procedure TH2PasConverter.SaveProject(const Filename: string);
|
|
begin
|
|
DebugLn(['TH2PasConverter.SaveProject ',Filename]);
|
|
FProject.Filename:=Filename;
|
|
FProject.SaveToFile(Filename);
|
|
CurrentProjectFilename:=Filename;
|
|
end;
|
|
|
|
function TH2PasConverter.Execute: TModalResult;
|
|
var
|
|
i: Integer;
|
|
AFile: TH2PasFile;
|
|
CurResult: TModalResult;
|
|
begin
|
|
if FExecuting then begin
|
|
DebugLn(['TH2PasConverter.Execute FAILED: Already executing']);
|
|
exit(mrCancel);
|
|
end;
|
|
|
|
Result:=mrOK;
|
|
FExecuting:=true;
|
|
try
|
|
FLastUsedFilename:='';
|
|
// convert every c header file
|
|
for i:=0 to Project.CHeaderFileCount-1 do begin
|
|
AFile:=Project.CHeaderFiles[i];
|
|
if not AFile.Enabled then continue;
|
|
CurResult:=ConvertFile(AFile);
|
|
if CurResult=mrAbort then begin
|
|
DebugLn(['TH2PasConverter.Execute aborted on file ',AFile.Filename]);
|
|
exit(mrAbort);
|
|
end;
|
|
if CurResult<>mrOK then Result:=mrCancel;
|
|
end;
|
|
finally
|
|
FExecuting:=false;
|
|
end;
|
|
end;
|
|
|
|
function TH2PasConverter.ConvertFile(AFile: TH2PasFile): TModalResult;
|
|
var
|
|
OutputFilename: String;
|
|
TempCHeaderFilename: String;
|
|
InputFilename: String;
|
|
Tool: TH2PasTool;
|
|
TextConverter: TIDETextConverter;
|
|
begin
|
|
Result:=mrCancel;
|
|
FLastUsedFilename:='';
|
|
|
|
// check if file exists
|
|
InputFilename:=AFile.Filename;
|
|
if not FileExistsCached(InputFilename) then begin
|
|
Result:=IDEMessageDialog('File not found',
|
|
'C header file "'+InputFilename+'" not found',
|
|
mtError,[mbCancel,mbAbort],'');
|
|
exit;
|
|
end;
|
|
|
|
OutputFilename:=AFile.GetOutputFilename;
|
|
TempCHeaderFilename:=ChangeFileExt(OutputFilename,'.tmp.h');
|
|
TextConverter:=TIDETextConverter.Create(nil);
|
|
try
|
|
if not CopyFile(InputFilename,TempCHeaderFilename) then begin
|
|
Result:=IDEMessageDialog('Copying file failed',
|
|
'Unable to copy file "'+InputFilename+'"'#13
|
|
+'to "'+TempCHeaderFilename+'"',
|
|
mtError,[mbCancel,mbAbort],'');
|
|
exit;
|
|
end;
|
|
|
|
TextConverter.Filename:=TempCHeaderFilename;
|
|
FLastUsedFilename:=TextConverter.Filename;
|
|
DebugLn(['TH2PasConverter.ConvertFile TempCHeaderFilename="',TempCHeaderFilename,'" CurrentType=',ord(TextConverter.CurrentType),' FileSize=',FileSize(TempCHeaderFilename)]);
|
|
|
|
// run converters for .h file to make it compatible for h2pas
|
|
TextConverter.LoadFromFile(InputFilename);
|
|
Result:=TextConverter.Execute(Project.PreH2PasTools);
|
|
if Result<>mrOk then begin
|
|
DebugLn(['TH2PasConverter.ConvertFile Failed running Project.PreH2PasTools on ',TempCHeaderFilename]);
|
|
exit;
|
|
end;
|
|
|
|
// run h2pas
|
|
Tool:=TH2PasTool.Create;
|
|
try
|
|
Tool.Title:='h2pas';
|
|
Tool.H2PasFile:=AFile;
|
|
//DebugLn(['TH2PasConverter.ConvertFile AAA TempCHeaderFilename="',TempCHeaderFilename,'" CurrentType=',ord(TextConverter.CurrentType),' FileSize=',FileSize(TempCHeaderFilename)]);
|
|
Tool.TargetFilename:=TextConverter.Filename;
|
|
//DebugLn(['TH2PasConverter.ConvertFile BBB TempCHeaderFilename="',TempCHeaderFilename,'" CurrentType=',ord(TextConverter.CurrentType),' FileSize=',FileSize(TempCHeaderFilename)]);
|
|
Tool.Filename:=GetH2PasFilename;
|
|
Tool.CmdLineParams:=AFile.GetH2PasParameters(Tool.TargetFilename);
|
|
Tool.ScanOutput:=true;
|
|
Tool.ShowAllOutput:=true;
|
|
Tool.WorkingDirectory:=Project.BaseDir;
|
|
Tool.OnParseLine:=@OnParseH2PasLine;
|
|
DebugLn(['TH2PasConverter.ConvertFile Tool.Filename="',Tool.Filename,'" Tool.CmdLineParams="',Tool.CmdLineParams,'"']);
|
|
Result:=RunExternalTool(Tool);
|
|
if Result<>mrOk then exit(mrAbort);
|
|
if FindH2PasErrorMessage>=0 then exit(mrAbort);
|
|
finally
|
|
Tool.Free;
|
|
end;
|
|
|
|
// run beautification tools for new pascal code
|
|
TextConverter.InitWithFilename(OutputFilename);
|
|
DebugLn(['TH2PasConverter.ConvertFile OutputFilename: ',copy(TextConverter.Source,1,300)]);
|
|
Result:=TextConverter.Execute(Project.PostH2PasTools);
|
|
if Result<>mrOk then begin
|
|
DebugLn(['TH2PasConverter.ConvertFile Failed running Project.PostH2PasTools on ',TempCHeaderFilename]);
|
|
exit;
|
|
end;
|
|
TextConverter.Filename:=OutputFilename;// save
|
|
finally
|
|
TextConverter.Free;
|
|
if (LazarusIDE<>nil) then begin
|
|
// reload changed files, so that IDE does not report changed files
|
|
LazarusIDE.DoRevertEditorFile(TempCHeaderFilename);
|
|
LazarusIDE.DoRevertEditorFile(OutputFilename);
|
|
end;
|
|
end;
|
|
|
|
Result:=mrOk;
|
|
end;
|
|
|
|
function TH2PasConverter.GetH2PasFilename: string;
|
|
begin
|
|
Result:=FindDefaultExecutablePath(h2pasFilename);
|
|
end;
|
|
|
|
function TH2PasConverter.FindH2PasErrorMessage: integer;
|
|
var
|
|
i: Integer;
|
|
Line: TIDEMessageLine;
|
|
begin
|
|
for i:=0 to IDEMessagesWindow.LinesCount-1 do begin
|
|
Line:=IDEMessagesWindow.Lines[i];
|
|
if REMatches(Line.Msg,'^(.*)\([0-9]+\)') then begin
|
|
Result:=i;
|
|
exit;
|
|
end;
|
|
end;
|
|
Result:=-1;
|
|
end;
|
|
|
|
function TH2PasConverter.GetH2PasErrorPostion(const Line: string;
|
|
out aFilename: string; out LineNumber, Column: integer): boolean;
|
|
begin
|
|
Result:=REMatches(Line,'^(.*)\(([0-9]+)\)');
|
|
if Result then begin
|
|
aFilename:=REVar(1);
|
|
LineNumber:=StrToIntDef(REVar(2),-1);
|
|
Column:=1;
|
|
end else begin
|
|
aFilename:='';
|
|
LineNumber:=-1;
|
|
Column:=-1;
|
|
end;
|
|
end;
|
|
|
|
function TH2PasConverter.FileIsRelated(const aFilename: string): Boolean;
|
|
begin
|
|
Result:=(CompareFilenames(AFilename,LastUsedFilename)=0)
|
|
or ((Project<>nil) and (Project.CHeaderFileWithFilename(aFilename)<>nil));
|
|
end;
|
|
|
|
{ TRemoveCPlusPlusExternCTool }
|
|
|
|
class function TRemoveCPlusPlusExternCTool.ClassDescription: string;
|
|
begin
|
|
Result:='Remove C++ ''extern "C"'' lines';
|
|
end;
|
|
|
|
function TRemoveCPlusPlusExternCTool.Execute(aText: TIDETextConverter
|
|
): TModalResult;
|
|
var
|
|
i: Integer;
|
|
Lines: TStrings;
|
|
Line: string;
|
|
begin
|
|
Result:=mrCancel;
|
|
if aText=nil then exit;
|
|
Lines:=aText.Strings;
|
|
i:=0;
|
|
while i<=Lines.Count-1 do begin
|
|
Line:=Trim(Lines[i]);
|
|
if Line='extern "C" {' then begin
|
|
Lines[i]:='';
|
|
end
|
|
else if (i>0) and (Line='}') and (Lines[i-1]='#if defined(__cplusplus)')
|
|
then begin
|
|
Lines[i]:='';
|
|
end;
|
|
inc(i);
|
|
end;
|
|
Result:=mrOk;
|
|
end;
|
|
|
|
{ TRemoveEmptyCMacrosTool }
|
|
|
|
class function TRemoveEmptyCMacrosTool.ClassDescription: string;
|
|
begin
|
|
Result:='Remove empty C macros';
|
|
end;
|
|
|
|
function TRemoveEmptyCMacrosTool.Execute(aText: TIDETextConverter
|
|
): TModalResult;
|
|
var
|
|
EmptyMacros: TAvgLvlTree;// tree of PChar
|
|
|
|
procedure AddEmptyMacro(const MacroName: string);
|
|
var
|
|
TempStr: String;
|
|
Identifier: PChar;
|
|
begin
|
|
//DebugLn(['AddEmptyMacro MacroName="',MacroName,'"']);
|
|
if EmptyMacros=nil then
|
|
EmptyMacros:=TAvgLvlTree.Create(TListSortCompare(@CompareIdentifiers));
|
|
Identifier:=@MacroName[1];
|
|
if EmptyMacros.Find(Identifier)<>nil then exit;
|
|
TempStr:=MacroName; // increase refcount
|
|
if TempStr<>'' then
|
|
Pointer(TempStr):=nil;
|
|
EmptyMacros.Add(Identifier);
|
|
end;
|
|
|
|
procedure DeleteEmptyMacro(const MacroName: string);
|
|
var
|
|
OldMacroName: String;
|
|
Identifier: PChar;
|
|
Node: TAvgLvlTreeNode;
|
|
begin
|
|
//DebugLn(['DeleteEmptyMacro MacroName="',MacroName,'"']);
|
|
if EmptyMacros=nil then exit;
|
|
Identifier:=@MacroName[1];
|
|
Node:=EmptyMacros.Find(Identifier);
|
|
if Node=nil then exit;
|
|
OldMacroName:='';
|
|
Pointer(OldMacroName):=Node.Data;
|
|
if OldMacroName<>'' then OldMacroName:=''; // decrease refcount
|
|
EmptyMacros.Delete(Node);
|
|
end;
|
|
|
|
procedure FreeMacros;
|
|
var
|
|
CurMacroName: String;
|
|
Node: TAvgLvlTreeNode;
|
|
begin
|
|
if EmptyMacros=nil then exit;
|
|
CurMacroName:='';
|
|
Node:=EmptyMacros.FindLowest;
|
|
while Node<>nil do begin
|
|
Pointer(CurMacroName):=Node.Data;
|
|
if CurMacroName<>'' then CurMacroName:=''; // decrease refcount
|
|
Node:=EmptyMacros.FindSuccessor(Node);
|
|
end;
|
|
EmptyMacros.Free;
|
|
end;
|
|
|
|
procedure RemoveEmptyMacrosFromString(var s: string);
|
|
var
|
|
IdentEnd: Integer;
|
|
IdentStart: LongInt;
|
|
Identifier: PChar;
|
|
IdentLen: LongInt;
|
|
begin
|
|
if EmptyMacros=nil then exit;
|
|
IdentEnd:=1;
|
|
repeat
|
|
IdentStart:=FindNextIdentifier(s,IdentEnd,length(s));
|
|
if IdentStart>length(s) then exit;
|
|
Identifier:=@s[IdentStart];
|
|
IdentLen:=GetIdentLen(Identifier);
|
|
if EmptyMacros.Find(Identifier)<>nil then begin
|
|
// empty macro found -> remove
|
|
System.Delete(s,IdentStart,IdentLen);
|
|
IdentEnd:=IdentStart;
|
|
end else begin
|
|
IdentEnd:=IdentStart+IdentLen;
|
|
end;
|
|
until false;
|
|
end;
|
|
|
|
var
|
|
MacroStart, MacroLen: integer;
|
|
Lines: TStrings;
|
|
i: Integer;
|
|
Line: string;
|
|
MacroName: String;
|
|
begin
|
|
Result:=mrCancel;
|
|
if aText=nil then exit;
|
|
Lines:=aText.Strings;
|
|
EmptyMacros:=nil;
|
|
try
|
|
i:=0;
|
|
while i<=Lines.Count-1 do begin
|
|
Line:=Lines[i];
|
|
if REMatches(Line,'^#define\s+([a-zA-Z0-9_]+)\b(.*)$') then begin
|
|
REVarPos(1,MacroStart,MacroLen);
|
|
MacroName:=copy(Line,MacroStart,MacroLen);
|
|
if Trim(copy(Line,MacroStart+MacroLen,length(Line)))='' then
|
|
AddEmptyMacro(MacroName)
|
|
else
|
|
DeleteEmptyMacro(MacroName);
|
|
end;
|
|
if (Line<>'') and (Line[1]<>'#') then
|
|
RemoveEmptyMacrosFromString(Line);
|
|
Lines[i]:=Line;
|
|
inc(i);
|
|
end;
|
|
finally
|
|
FreeMacros;
|
|
end;
|
|
Result:=mrOk;
|
|
end;
|
|
|
|
{ TReplaceMacro0PointerWithNULL }
|
|
|
|
class function TReplaceMacro0PointerWithNULL.ClassDescription: string;
|
|
begin
|
|
Result:='Replace macro values 0 pointer like (char *)0 with NULL';
|
|
end;
|
|
|
|
function TReplaceMacro0PointerWithNULL.Execute(aText: TIDETextConverter
|
|
): TModalResult;
|
|
var
|
|
Lines: TStrings;
|
|
i: Integer;
|
|
Line: string;
|
|
MacroStart, MacroLen: integer;
|
|
begin
|
|
Result:=mrCancel;
|
|
if aText=nil then exit;
|
|
Lines:=aText.Strings;
|
|
i:=0;
|
|
while i<=Lines.Count-1 do begin
|
|
Line:=Lines[i];
|
|
if REMatches(Line,'^#define\s+([a-zA-Z0-9_]+)\s+(\(.*\*\)0)\s*($|//|/\*)')
|
|
then begin
|
|
REVarPos(2,MacroStart,MacroLen);
|
|
Line:=copy(Line,1,MacroStart-1)+'NULL'
|
|
+copy(Line,MacroStart+MacroLen,length(Line));
|
|
Lines[i]:=Line;
|
|
end;
|
|
inc(i);
|
|
end;
|
|
Result:=mrOk;
|
|
end;
|
|
|
|
{ TReplaceEdgedBracketPairWithStar }
|
|
|
|
class function TReplaceEdgedBracketPairWithStar.ClassDescription: string;
|
|
begin
|
|
Result:='Replace [] with *';
|
|
end;
|
|
|
|
constructor TReplaceEdgedBracketPairWithStar.Create(TheOwner: TComponent);
|
|
begin
|
|
inherited Create(TheOwner);
|
|
SearchFor:='[]';
|
|
ReplaceWith:='*';
|
|
end;
|
|
|
|
{ TReplaceUnitFilenameWithUnitName }
|
|
|
|
class function TReplaceUnitFilenameWithUnitName.ClassDescription: string;
|
|
begin
|
|
Result:='Replace "unit filename;" with "unit name;"';
|
|
end;
|
|
|
|
constructor TReplaceUnitFilenameWithUnitName.Create(TheOwner: TComponent);
|
|
begin
|
|
inherited Create(TheOwner);
|
|
SearchFor:='^(unit\s).*(/|\\)([a-z_0-9]+;)';
|
|
ReplaceWith:='$1$3';
|
|
Options:=Options+[trtRegExpr];
|
|
end;
|
|
|
|
{ TRemoveSystemTypes }
|
|
|
|
class function TRemoveSystemTypes.ClassDescription: string;
|
|
begin
|
|
Result:='Remove type redefinitons like PLongint';
|
|
end;
|
|
|
|
function TRemoveSystemTypes.Execute(aText: TIDETextConverter): TModalResult;
|
|
var
|
|
Source: String;
|
|
Flags: TSrcEditSearchOptions;
|
|
Prompt: Boolean;
|
|
SearchFor: string;
|
|
begin
|
|
Result:=mrCancel;
|
|
if aText=nil then exit;
|
|
Source:=aText.Source;
|
|
Flags:=[sesoReplace,sesoReplaceAll,sesoRegExpr];
|
|
Prompt:=false;
|
|
SearchFor:='^\s*('
|
|
+'PLongint\s*=\s*\^Longint'
|
|
+'|PSmallInt\s*=\s*\^SmallInt'
|
|
+'|PByte\s*=\s*\^Byte'
|
|
+'|PWord\s*=\s*\^Word'
|
|
+'|PDWord\s*=\s*\^DWord'
|
|
+'|PDouble\s*=\s*\^Double'
|
|
+'|PChar\s*=\s*\^Char'
|
|
+');\s*$';
|
|
Result:=IDESearchInText('',Source,SearchFor,'',Flags,Prompt,nil);
|
|
if Result<>mrOk then exit;
|
|
aText.Source:=Source;
|
|
end;
|
|
|
|
{ TRemoveRedefinedPointerTypes }
|
|
|
|
class function TRemoveRedefinedPointerTypes.ClassDescription: string;
|
|
begin
|
|
Result:='Remove redefined pointer types';
|
|
end;
|
|
|
|
function TRemoveRedefinedPointerTypes.Execute(aText: TIDETextConverter
|
|
): TModalResult;
|
|
{ search for
|
|
Pname = ^name;
|
|
if PName has a redefinition, delete the first one
|
|
}
|
|
var
|
|
Lines: TStrings;
|
|
i: Integer;
|
|
Line: string;
|
|
PointerName: String;
|
|
TypeName: String;
|
|
j: Integer;
|
|
Pattern: String;
|
|
begin
|
|
Result:=mrCancel;
|
|
if aText=nil then exit;
|
|
Lines:=aText.Strings;
|
|
i:=0;
|
|
while i<=Lines.Count-1 do begin
|
|
Line:=Lines[i];
|
|
if REMatches(Line,'^\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*\^\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*;\s*($|//|/\*)') then begin
|
|
PointerName:=REVar(1);
|
|
TypeName:=REVar(2);
|
|
Pattern:='^\s*'+PointerName+'\s*=\s*\^\s*'+TypeName+'\s*;';
|
|
j:=i+1;
|
|
while (j<Lines.Count-1) and (not REMatches(Line,Pattern)) do
|
|
dec(j);
|
|
if j<Lines.Count then begin
|
|
Lines.Delete(i);
|
|
dec(i);
|
|
end;
|
|
end;
|
|
inc(i);
|
|
end;
|
|
Result:=mrOk;
|
|
end;
|
|
|
|
{ TRemoveEmptyTypeVarConstSections }
|
|
|
|
class function TRemoveEmptyTypeVarConstSections.ClassDescription: string;
|
|
begin
|
|
Result:='Remove empty type/var/const sections';
|
|
end;
|
|
|
|
function TRemoveEmptyTypeVarConstSections.Execute(aText: TIDETextConverter
|
|
): TModalResult;
|
|
var
|
|
Src: String;
|
|
p: Integer;
|
|
AtomStart: Integer;
|
|
CurAtom, NextAtom: PChar;
|
|
KeyWordStart: LongInt;
|
|
KeyWordEnd: LongInt;
|
|
DeleteSection: Boolean;
|
|
Modified: Boolean;
|
|
begin
|
|
Result:=mrCancel;
|
|
Src:=aText.Source;
|
|
p:=1;
|
|
repeat
|
|
ReadRawNextPascalAtom(Src,p,AtomStart);
|
|
if p>length(Src) then break;
|
|
CurAtom:=@Src[AtomStart];
|
|
if (CompareIdentifiers(CurAtom,'type')=0)
|
|
or (CompareIdentifiers(CurAtom,'var')=0)
|
|
or (CompareIdentifiers(CurAtom,'const')=0)
|
|
or (CompareIdentifiers(CurAtom,'threadvar')=0)
|
|
or (CompareIdentifiers(CurAtom,'resourcestring')=0)
|
|
then begin
|
|
// start of a section found
|
|
// read next atoms to check if they are identifier plus definition operator
|
|
// 'name =' or 'name:' or 'name,'
|
|
KeyWordStart:=AtomStart;
|
|
KeyWordEnd:=p;
|
|
ReadRawNextPascalAtom(Src,p,AtomStart);
|
|
if p<length(Src) then begin
|
|
NextAtom:=@Src[AtomStart];
|
|
DeleteSection:=true;
|
|
if GetIdentLen(NextAtom)>0 then begin
|
|
ReadRawNextPascalAtom(Src,p,AtomStart);
|
|
if (p<=length(Src)) and (p-AtomStart=1)
|
|
and (Src[AtomStart] in ['=',':',',']) then
|
|
DeleteSection:=false;
|
|
end;
|
|
if DeleteSection then begin
|
|
// this section is empty -> delete it
|
|
Src:=copy(Src,1,KeyWordStart-1)+copy(Src,KeyWordEnd,length(Src));
|
|
Modified:=true;
|
|
// adjust position
|
|
p:=KeyWordStart;
|
|
end;
|
|
end;
|
|
end;
|
|
until false;
|
|
if Modified then
|
|
aText.Source:=Src;
|
|
|
|
Result:=mrOk;
|
|
end;
|
|
|
|
end.
|
|
|