IDE: circle detection for macros

git-svn-id: trunk@28626 -
This commit is contained in:
mattias 2010-12-05 11:02:53 +00:00
parent 43eaec2e45
commit e454608274

View File

@ -74,11 +74,15 @@ type
AMacroFunction: TMacroFunction; TheFlags: TTransferMacroFlags); AMacroFunction: TMacroFunction; TheFlags: TTransferMacroFlags);
end; end;
{ TTransferMacroList }
TTransferMacroList = class TTransferMacroList = class
private private
fItems: TList; // list of TTransferMacro fItems: TFPList; // list of TTransferMacro
FMarkUnhandledMacros: boolean; FMarkUnhandledMacros: boolean;
FMaxUsePerMacro: integer;
fOnSubstitution: TOnSubstitution; fOnSubstitution: TOnSubstitution;
fBusy: TStringList; // current working Macros, used for circle detection
function GetItems(Index: integer): TTransferMacro; function GetItems(Index: integer): TTransferMacro;
procedure SetItems(Index: integer; NewMacro: TTransferMacro); procedure SetItems(Index: integer; NewMacro: TTransferMacro);
procedure SetMarkUnhandledMacros(const AValue: boolean); procedure SetMarkUnhandledMacros(const AValue: boolean);
@ -107,7 +111,8 @@ type
property OnSubstitution: TOnSubstitution property OnSubstitution: TOnSubstitution
read fOnSubstitution write fOnSubstitution; read fOnSubstitution write fOnSubstitution;
property MarkUnhandledMacros: boolean read FMarkUnhandledMacros property MarkUnhandledMacros: boolean read FMarkUnhandledMacros
write SetMarkUnhandledMacros; write SetMarkUnhandledMacros default true;
property MaxUsePerMacro: integer read FMaxUsePerMacro write FMaxUsePerMacro default 1;
end; end;
{ TLazIDEMacros } { TLazIDEMacros }
@ -180,8 +185,9 @@ end;
constructor TTransferMacroList.Create; constructor TTransferMacroList.Create;
begin begin
inherited Create; inherited Create;
fItems:=TList.Create; fItems:=TFPList.Create;
FMarkUnhandledMacros:=true; FMarkUnhandledMacros:=true;
FMaxUsePerMacro:=3;
Add(TTransferMacro.Create('Ext', '', lisTMFunctionExtractFileExtension, Add(TTransferMacro.Create('Ext', '', lisTMFunctionExtractFileExtension,
@MF_Ext, [])); @MF_Ext, []));
Add(TTransferMacro.Create('Path', '', lisTMFunctionExtractFilePath, @MF_Path, Add(TTransferMacro.Create('Path', '', lisTMFunctionExtractFilePath, @MF_Path,
@ -199,7 +205,8 @@ end;
destructor TTransferMacroList.Destroy; destructor TTransferMacroList.Destroy;
begin begin
Clear; Clear;
fItems.Free; FreeAndNil(fItems);
FreeAndNil(fBusy);
inherited Destroy; inherited Destroy;
end; end;
@ -289,6 +296,8 @@ var
NewStringPos: Integer; NewStringPos: Integer;
sLen: Integer; sLen: Integer;
LoopPos, LoopDepth: integer; LoopPos, LoopDepth: integer;
InUse: Integer;
i: Integer;
function SearchBracketClose(Position:integer): integer; function SearchBracketClose(Position:integer): integer;
var BracketClose:char; var BracketClose:char;
@ -346,18 +355,37 @@ begin
// Macro function -> substitute macro parameter first // Macro function -> substitute macro parameter first
MacroParam:=copy(MacroStr,length(MacroName)+3, MacroParam:=copy(MacroStr,length(MacroName)+3,
length(MacroStr)-length(MacroName)-3); length(MacroStr)-length(MacroName)-3);
if not SubstituteStr(MacroParam,Data,Depth+1) then begin
Result:=false;
exit;
end;
AMacro:=FindByName(MacroName); AMacro:=FindByName(MacroName);
if Assigned(fOnSubstitution) then begin InUse:=0;
fOnSubstitution(AMacro,MacroName,MacroParam,Data,Handled,Abort,Depth+LoopDepth); for i:=0 to fBusy.Count-1 do begin
if Handled then if SysUtils.CompareText(fBusy[i],MacroName)=0 then begin
MacroStr:=MacroParam inc(InUse);
else if Abort then begin if InUse>MaxUsePerMacro then begin
Result:=false; // circle detected
exit; Handled:=true;
MacroStr:='<CIRCLE:'+MacroName+'>';
break;
end;
end;
end;
if not Handled then begin
try
fBusy.Add(MacroName);
if not SubstituteStr(MacroParam,Data,Depth+1) then begin
Result:=false;
exit;
end;
finally
fBusy.Delete(fBusy.Count-1);
end;
if Assigned(fOnSubstitution) then begin
fOnSubstitution(AMacro,MacroName,MacroParam,Data,Handled,Abort,Depth+LoopDepth);
if Handled then
MacroStr:=MacroParam
else if Abort then begin
Result:=false;
exit;
end;
end; end;
end; end;
if (not Handled) and (AMacro<>nil) and (Assigned(AMacro.MacroFunction)) if (not Handled) and (AMacro<>nil) and (Assigned(AMacro.MacroFunction))