amxmodx/editor/studio/UnitfrmTextAnalyze.~pa
2005-08-26 18:29:39 +00:00

199 lines
7.5 KiB
Plaintext
Executable File

unit UnitfrmTextAnalyze;
interface
uses SysUtils, Classes;
type TPAWNParseResult = class
public
end
function ParseCodePAWN(eCode: TStringList): TPAWNParseResult;
implementation
function ParseCodePAWN(eCode: TStringList): TPAWNParseResult;
var i, k: integer;
eTrimmed, eLowered, eNoComments: String;
eStr, ePreEvents: TStringList;
eStartLine, eBracesOpen: Integer;
eTemp: String;
begin
Synchronize(GetCodeAndPos);
eConstants.Clear;
eDefined.Clear;
eCVars.Clear;
eIncluded.Clear;
eMethodsDefault.Clear;
eMethodsEvents.Clear;
eStocks.Clear;
eNatives.Clear;
eForwards.Clear;
eVariables.Clear;
ePreEvents.Clear;
eBracesOpen := 0;
eCurrLine := 0;
eStartLine := -1;
for i := 0 to eCode.Count -1 do begin
eTrimmed := Trim(eCode[i]);
eLowered := LowerCase(eTrimmed);
eNoComments := RemoveStringsAndComments(eTrimmed);
{ Constants and Variables }
if (Pos('new ', eLowered) = 1) and (eBracesOpen = 0) then begin // const or variable
Delete(eTrimmed, 1, 4);
eLowered := Trim(eTrimmed);
// we don't need braces so delete them...
while (CountChars(eTrimmed, '{') = CountChars(eTrimmed, '}')) and (CountChars(eTrimmed, '{') <> 0) and (Pos('{', eTrimmed) < Pos('}', eTrimmed)) do
eTrimmed := StringReplace(eTrimmed, '{' + Between(eTrimmed, '{', '}') + '}', '', [rfReplaceAll]);
while (CountChars(eTrimmed, '[') = CountChars(eTrimmed, ']')) and (CountChars(eTrimmed, '[') <> 0) and (Pos('[', eTrimmed) < Pos(']', eTrimmed)) do
eTrimmed := StringReplace(eTrimmed, '[' + Between(eTrimmed, '[', ']') + ']', '', [rfReplaceAll]);
// done? okay, split all items if there are more than one; and if not, it's okay...
eStr.Text := StringReplace(eTrimmed, ',', #13, [rfReplaceAll]);
for k := 0 to eStr.Count -1 do begin
if Trim(eStr[k]) <> '' then begin
if Pos(':', eStr[k]) <> 0 then
eStr[k] := Copy(eStr[k], Pos(':', eStr[k]) +1, Length(eStr[k]));
eStr[k] := Trim(RemoveSemicolon(eStr[k]));
if Pos('=', eStr[k]) <> 0 then // constant
eConstants.AddObject(Copy(eStr[k], 1, Pos('=', eStr[k]) -1), TObject(i))
else
eVariables.AddObject(eStr[k], TObject(i));
end;
end;
end
{ Included }
else if Pos('#include ', eLowered) = 1 then begin
if Between(eTrimmed, '<', '>') <> '' then begin
eTrimmed := Between(eTrimmed, '<', '>');
if ExtractFileExt(eTrimmed) <> '' then
ChangeFileExt(eTrimmed, '');
end
else if Between(eTrimmed, '"', '"') <> '' then begin
eTrimmed := Between(eTrimmed, '"', '"');
if ExtractFileExt(eTrimmed) <> '' then
ChangeFileExt(eTrimmed, '');
end
else begin
eTrimmed := Copy(eTrimmed, 9, Length(eTrimmed));
if ExtractFileExt(eTrimmed) <> '' then
ChangeFileExt(eTrimmed, '');
end;
eTrimmed := Trim(eTrimmed);
eIncluded.AddObject(eTrimmed, TObject(i));
end
{ CVars }
else if Pos('register_cvar(', eLowered) = 1 then begin
if Between(eTrimmed, '"', '"') <> '' then
eCVars.AddObject(Between(eTrimmed, '"', '"'), TObject(i));
end
{ Defined }
else if Pos('#define ', eLowered) = 1 then begin
eTrimmed := Copy(eTrimmed, 8, Length(eTrimmed));
eTrimmed := Trim(eTrimmed);
if Pos(#32, eTrimmed) <> 0 then
eTrimmed := Copy(eTrimmed, 1, Pos(#32, eTrimmed) -1);
eDefined.AddObject(eTrimmed, TObject(i));
end
{ Events (Part 1) }
else if Pos('register_event(', eLowered) = 1 then begin
if CountChars(eLowered, '"') >= 4 then
ePreEvents.Add(Between(eTrimmed, '"', '"'));
end;
{ Functions, this is adapted from AMXX-Edit v2 [see TextAnalyze.pas] }
if Pos('{', eNoComments) <> 0 then begin
if eStartLine = -1 then
eStartLine := i;
Inc(eBracesOpen, CountChars(eTrimmed, '{'));
end;
if Pos('}', eNoComments) <> 0 then begin
Inc(eBracesOpen, -CountChars(eTrimmed, '}'));
if (eBracesOpen = 0) then begin
eTemp := Trim(StringReplace(eCode[eStartLine], '{', '', [rfReplaceAll]));
// Analyze type
k := 0;
if Pos('public ', LowerCase(eTemp)) = 1 then
k := 1
else if Pos('stock ', LowerCase(eTemp)) = 1 then
k := 2
else if Pos('native ', LowerCase(eTemp)) = 1 then
k := 3
else if Pos('forward ', LowerCase(eTemp)) = 1 then
k := 4;
// Remove type
if (Pos(#32, eTemp) <> 0) and (Pos(#32, eTemp) < Pos('(', eTemp)) then
eTemp := Copy(eCode[eStartLine], Pos(#32, eCode[eStartLine]) +1, Length(eCode[eStartLine]));
// Copy function-name
if Pos('(', eTemp) <> 0 then
eTemp := Copy(eTemp, 1, Pos('(', eTemp) -1);
// Remove return-type
if Pos(':', eTemp) <> 0 then
Delete(eTemp, 1, Pos(':', eTemp));
eTemp := Trim(eTemp);
if eTemp <> '' then begin
case k of
0: eMethodsDefault.AddObject(eTemp, TObject(i)); // Default Method
1: begin
k := ePreEvents.IndexOf(eTemp);
if k <> -1 then begin
eMethodsEvents.AddObject(eTemp, ePreEvents.Objects[k]);
ePreEvents.Delete(k);
end
else
eMethodsDefault.AddObject(eTemp, TObject(i));
end;
2: eStocks.AddObject(eTemp, TObject(i));
3: eNatives.AddObject(eTemp, TObject(i));
4: eForwards.AddObject(eTemp, TObject(i));
end;
end;
eStartLine := -1;
eBracesOpen := -2;
end;
end;
if (Pos('forward ', eLowered) = 1) or (Pos('public ', eLowered) = 1) or (Pos('native ', eLowered) = 1) or (Pos('stock ', eLowered) = 1) then begin
eBracesOpen := 0;
if ((Pos('{', eLowered) = 0)) or (Pos('{', eLowered) <> 0) and (Pos('}', eLowered) <> 0) then begin
eTemp := eTrimmed;
// Remove type
if (Pos(#32, eTemp) <> 0) and (Pos(#32, eTemp) < Pos('(', eTemp)) then
eTemp := Copy(eTemp, Pos(#32, eTemp) +1, Length(eTemp));
// Copy function-name
if Pos('(', eTemp) <> 0 then
eTemp := Copy(eTemp, 1, Pos('(', eTemp) -1);
// Remove return-type
if Pos(':', eTemp) <> 0 then
Delete(eTemp, 1, Pos(':', eTemp));
eTemp := Trim(eTemp);
if eTemp <> '' then begin
if Pos('forward', eLowered) = 1 then
eForwards.AddObject(eTrimmed, TObject(i))
else if Pos('public', eLowered) = 1 then begin
k := ePreEvents.IndexOf(eTemp);
if k <> -1 then begin
eMethodsEvents.AddObject(eTemp, ePreEvents.Objects[k]);
ePreEvents.Delete(k);
end
else
eMethodsDefault.Add(eTemp);
end
else if Pos('native', eLowered) = 1 then
eNatives.AddObject(eTemp, TObject(i))
else if Pos('stock', eLowered) = 1 then
eStocks.AddObject(eTemp, TObject(i))
else
eMethodsDefault.AddObject(eTemp, TObject(i));
end;
end;
end;
Sleep(5);
end;
end;
end.