unit UnitTextAnalyze; // Unit for analyzing code for code explorer, auto // complete and call tips interface uses SysUtils, Classes, ComCtrls, Windows, Forms, Messages, ScintillaLanguageManager; procedure UpdateList(Code: String); procedure AddAutoComplete(eAdd: String; AddCallTip: Boolean); var eExpand1, eExpand2, eExpand3, eExpand4, eExpand5: Boolean; implementation uses UnitfrmMain, UnitFunc; procedure UpdateList(Code: String); var i, k: integer; eStr, eStr2: TStringList; eEndVariables: Boolean; eParent1, eParent2, eParent3, eParent4, eParent5: TTreeNode; eBracketsOpen, eStartLine: Integer; eTemp: String; begin eStr := TStringList.Create; eStr2 := TStringList.Create; eStr.Text := Code; frmMain.sacComplete.AStrings.Text := frmMain.StdAutoComplete; frmMain.cltEditor.ApiStrings.Text := frmMain.StdCallTips; frmMain.trvFunctions.Items.BeginUpdate; for i := 0 to 4 do frmMain.trvFunctions.Items[i].DeleteChildren; for i := eStr.Count -1 downto 0 do begin eStr[i] := TrimLeft(eStr[i]); if (Pos('//', eStr[i]) > 0) then eStr[i] := Copy(eStr[i], 1, Pos('//', eStr[i]) -2); if (Pos('/*', eStr[i]) > 0) then eStr[i] := Copy(eStr[i], 1, Pos('/*', eStr[i]) -2); if (Pos('*', eStr[i]) = 1) then eStr.Delete(i); if (Pos('*/', eStr[i]) > 0) then eStr[i] := Copy(eStr[i], 1, Pos('*/', eStr[i]) -2); end; eEndVariables := False; eBracketsOpen := -1; eStartLine := -1; eParent1 := frmMain.trvFunctions.Items[3]; eParent2 := frmMain.trvFunctions.Items[1]; eParent3 := frmMain.trvFunctions.Items[4]; eParent4 := frmMain.trvFunctions.Items[0]; eParent5 := frmMain.trvFunctions.Items[2]; for i := 0 to eStr.Count -1 do begin // Included: if Pos('#include', LowerCase(eStr[i])) = 1 then begin if (ExtractFileExt(Between(eStr[i], '<', '>')) = '') and (ExtractFileExt(Between(eStr[i], '"', '"')) = '') then begin if Pos('<', eStr[i]) > 0 then frmMain.trvFunctions.Items.AddChild(eParent1, Between(eStr[i], '<', '>') + '.inc') else frmMain.trvFunctions.Items.AddChild(eParent1, Between(eStr[i], '"', '"') + '.inc'); end else begin if Pos('<', eStr[i]) > 0 then frmMain.trvFunctions.Items.AddChild(eParent1, Between(eStr[i], '<', '>')) else frmMain.trvFunctions.Items.AddChild(eParent1, Between(eStr[i], '"', '"')); end; end; // Defined if Pos('#define', LowerCase(eStr[i])) = 1 then begin eStr[i] := Copy(eStr[i], 8, Length(eStr[i])); if Pos(#32, eStr[i]) <> 0 then begin frmMain.trvFunctions.Items.AddChild(eParent2, Copy(TrimLeft(eStr[i]), 1, Pos(#32, TrimLeft(eStr[i])) -1)); AddAutoComplete(Copy(TrimLeft(eStr[i]), 1, Pos(#32, TrimLeft(eStr[i])) -1), False); end else begin frmMain.trvFunctions.Items.AddChild(eParent2, TrimLeft(eStr[i])); AddAutoComplete(TrimLeft(eStr[i]), False); end; end; // Variables and constants if not eEndVariables then begin if Pos('new', LowerCase(eStr[i])) = 1 then begin if Pos(',', eStr[i]) > 0 then begin eStr2.Text := StringReplace(Trim(Copy(eStr[i], 4, Length(eStr[i]))), ',', #13, [rfReplaceAll]); for k := 0 to eStr2.Count -1 do begin if Pos('=', eStr[i]) = 0 then frmMain.trvFunctions.Items.AddChild(eParent3, Trim(eStr2[k])) else frmMain.trvFunctions.Items.AddChild(eParent4, Trim(eStr2[k])); AddAutoComplete(Trim(eStr2[k]), False); end; end else if Pos('{', Trim(eStr[i])) = Length(Trim(eStr[i])) then begin if Pos('=', eStr[i]) = 0 then frmMain.trvFunctions.Items.AddChild(eParent3, TrimLeft(Copy(eStr[i], 4, Length(eStr[i]))) + ' Array }') else frmMain.trvFunctions.Items.AddChild(eParent4, TrimLeft(Copy(eStr[i], 4, Length(eStr[i]))) + ' Array }'); AddAutoComplete(Trim(Copy(eStr[i], 1, Pos('{', eStr[i]) -1)), False); end else begin if Pos('=', eStr[i]) = 0 then frmMain.trvFunctions.Items.AddChild(eParent3, TrimLeft(Copy(eStr[i], 4, Length(eStr[i])))) else frmMain.trvFunctions.Items.AddChild(eParent4, TrimLeft(Copy(eStr[i], 4, Length(eStr[i])))); AddAutoComplete(TrimLeft(Copy(eStr[i], 4, Length(eStr[i]))), False); end; end; end; // Functions if (Pos('forward', LowerCase(eStr[i])) = 1) or (Pos('public', LowerCase(eStr[i])) = 1) or (Pos('native', LowerCase(eStr[i])) = 1) or (Pos('stock', LowerCase(eStr[i])) = 1) then begin eBracketsOpen := 0; eEndVariables := True; if ((Pos('{', eStr[i]) = 0)) or (Pos('{', eStr[i]) <> 0) and (Pos('}', eStr[i]) <> 0) then begin eTemp := Copy(eStr[i], 1, Pos(#32, eStr[i])); frmMain.FunctionType.Add(eTemp); frmMain.trvFunctions.Items.AddChild(eParent5, Copy(eStr[i], Pos(#32, eStr[i]) +1, Length(eStr[i]))); AddAutoComplete(Copy(eStr[i], Pos(#32, eStr[i]) +1, Length(eStr[i])), True); end; end; if Pos('{', eStr[i]) <> 0 then begin if eStartLine = -1 then eStartLine := i; Inc(eBracketsOpen, 1); end; if Pos('}', eStr[i]) <> 0 then begin Inc(eBracketsOpen, -1); if (eBracketsOpen = 0) then begin eStr[eStartLine] := StringReplace(eStr[eStartLine], '{', '', [rfReplaceAll]); eStr[eStartLine] := TrimRight(eStr[eStartLine]); if (Pos(#32, eStr[eStartLine]) <> 0) and (Pos(#32, eStr[eStartLine]) < Pos('(', eStr[eStartLine])) then eTemp := Copy(eStr[eStartLine], 1, Pos(#32, eStr[eStartLine])) else eTemp := ''; frmMain.FunctionType.Add(eTemp); frmMain.trvFunctions.Items.AddChild(eParent5, Copy(eStr[eStartLine], Pos(#32, eStr[eStartLine]) +1, Length(eStr[eStartLine]))); AddAutoComplete(Copy(eStr[eStartLine], Pos(#32, eStr[eStartLine]) +1, Length(eStr[eStartLine])), True); eStartLine := -1; eBracketsOpen := -2; end; end; end; for i := frmMain.trvFunctions.Items.Count -1 downto 0 do begin if Assigned(frmMain.trvFunctions.Items[i].Parent) then begin frmMain.trvFunctions.Items[i].ImageIndex := 20; frmMain.trvFunctions.Items[i].SelectedIndex := 20; end else begin frmMain.trvFunctions.Items[i].ImageIndex := 18; frmMain.trvFunctions.Items[i].SelectedIndex := 18; end; if frmMain.trvFunctions.Items[i].Text = '' then // Remove empty items frmMain.trvFunctions.Items.Delete(frmMain.trvFunctions.Items[i]); end; eStr.Free; eStr2.Free; frmMain.trvFunctions.Items.AlphaSort(True); frmMain.trvFunctions.FullExpand; if not eExpand1 then eParent1.Collapse(False); if not eExpand2 then eParent2.Collapse(False); if not eExpand3 then eParent3.Collapse(False); if not eExpand4 then eParent4.Collapse(False); if not eExpand5 then eParent5.Collapse(False); frmMain.trvFunctions.Perform(WM_VSCROLL, SB_TOP, 0); frmMain.trvFunctions.Items.EndUpdate; Application.ProcessMessages; end; procedure AddAutoComplete(eAdd: String; AddCallTip: Boolean); function AlreadyAdded: Boolean; var i: integer; eTemp: String; begin Result := False; eTemp := Trim(eAdd); for i := 0 to frmMain.sacComplete.AStrings.Count -1 do begin if Trim(frmMain.sacComplete.AStrings[i]) = eAdd then Result := True; if Trim(frmMain.sacComplete.AStrings[i] + '()') = eAdd then Result := True; end; end; begin if not AlreadyAdded then begin if Pos('(', eAdd) <> 0 then frmMain.sacComplete.AStrings.Add(Copy(eAdd, 1, Pos('(', eAdd) -1)) else frmMain.sacComplete.AStrings.Add(eAdd); if AddCallTip then frmMain.cltEditor.ApiStrings.Add(eAdd); end; end; end.