Converter: optimize function replacement, use binary search and skip short identifiers.

git-svn-id: trunk@43198 -
This commit is contained in:
juha 2013-10-10 22:20:05 +00:00
parent 1baa61cb47
commit 52c26ec4d5
2 changed files with 46 additions and 27 deletions

View File

@ -644,39 +644,40 @@ var
procedure ReadFuncCall(MaxPos: Integer);
var
FuncDefInfo, FuncCallInfo: TFuncReplacement;
FuncName: string;
i, x, IdentEndPos: Integer;
IdentName: string;
i, x, IdentEndPos, IdentLen: Integer;
begin
IdentEndPos:=xStart;
with fCTLink.CodeTool, fCTLink.Settings do begin
with fCTLink.CodeTool, fCTLink.Settings do
try
while (IdentEndPos<=MaxPos) and (IsIdentChar[Src[IdentEndPos]]) do
inc(IdentEndPos);
for i:=0 to ReplaceFuncs.Funcs.Count-1 do begin
FuncName:=ReplaceFuncs.Funcs[i];
if (IdentEndPos-xStart=length(FuncName))
and (CompareIdentifiers(PChar(FuncName),@Src[xStart])=0)
and not fDefinedProcNames.Find(FuncName, x)
then begin
FuncDefInfo:=ReplaceFuncs.FuncAtInd(i);
if ReplaceFuncs.Categories.Find(FuncDefInfo.Category, x)
// Categories.Objects[x] is used as a boolean flag.
and Assigned(ReplaceFuncs.Categories.Objects[x])
// UTF8 funcs are in LCL which console apps don't have -> don't change.
and not (aIsConsoleApp and (FuncDefInfo.Category='UTF8Names'))
// Keep Windows funcs in a Windows application.
and (fCTLink.Settings.CrossPlatform or (FuncDefInfo.Category<>'WindowsAPI'))
then begin
// Create a new replacement object for params, position and other info.
FuncCallInfo:=TFuncReplacement.Create(FuncDefInfo);
ReadParams(FuncCallInfo);
IdentEndPos:=FuncCallInfo.EndPos; // Skip the params, too, for next search.
fFuncsToReplace.Add(FuncCallInfo);
Break;
end;
end;
IdentLen:=IdentEndPos-xStart;
SetLength(IdentName, IdentLen);
StrMove(PChar(IdentName), @Src[xStart], IdentLen);
// Don't try to uselessly find short identifiers
if (IdentLen<ReplaceFuncs.MinFuncLen) and (IdentName<>'Ptr') then Exit;
if fDefinedProcNames.Find(IdentName, x) then Exit;
if not ReplaceFuncs.Funcs.Find(IdentName, i) then Exit;
// Now function name is found in replacement list, get function info.
FuncDefInfo:=ReplaceFuncs.FuncAtInd(i);
if ReplaceFuncs.Categories.Find(FuncDefInfo.Category, i)
// Categories.Objects[i] is used as a boolean flag.
and Assigned(ReplaceFuncs.Categories.Objects[i])
// UTF8 funcs are in LCL which console apps don't have -> don't change.
and not (aIsConsoleApp and (FuncDefInfo.Category='UTF8Names'))
// Keep Windows funcs in a Windows application.
and (fCTLink.Settings.CrossPlatform or (FuncDefInfo.Category<>'WindowsAPI'))
then begin
// Create a new replacement object for params, position and other info.
FuncCallInfo:=TFuncReplacement.Create(FuncDefInfo);
ReadParams(FuncCallInfo);
IdentEndPos:=FuncCallInfo.EndPos; // Skip the params, too, for next search.
fFuncsToReplace.Add(FuncCallInfo);
end;
finally
xStart:=IdentEndPos;
end;
xStart:=IdentEndPos;
end;
function SearchFuncCalls(aNode: TCodeTreeNode): TCodeTreeNode;

View File

@ -69,6 +69,7 @@ type
private
// Delphi func names, objects property has TFuncReplacement items.
fFuncs: TStringList;
fMinFuncLen: Integer;
// Category names, objects property has boolean info Used/Not used.
fCategories: TStringList;
public
@ -77,6 +78,7 @@ type
procedure Clear;
function AddFunc(aCategory, aDelphiFunc, aReplaceFunc, aPackage, aUnitName: string): integer;
function FuncAtInd(Ind: integer): TFuncReplacement;
function MinFuncLen: Integer;
function AddCategory(aCategory: string; aUsed: Boolean): integer;
function CategoryIsUsed(Ind: integer): Boolean;
public
@ -383,6 +385,22 @@ begin
Result:=CategUsed=1;
end;
function TFuncsAndCategories.MinFuncLen: Integer;
var
i, Len: Integer;
begin
if (fMinFuncLen=0) and (fFuncs.Count>0) then begin
fMinFuncLen:=10000; // First a big enough length
for i:=0 to fFuncs.Count-1 do begin
if fFuncs[i]='Ptr' then Continue; // 'Ptr' is short and is a special case.
Len:=Length(fFuncs[i]);
if Len<fMinFuncLen then
fMinFuncLen:=Len;
end;
end;
Result:=fMinFuncLen;
end;
{ TReplaceFuncsForm }