browcol.pas 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. {
  2. $Id$
  3. Copyright (c) 1993-98 by the FPC development team
  4. Support routines for getting browser info in collections
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. {$ifdef TP}
  19. {$N+,E+}
  20. {$endif}
  21. unit browcol;
  22. interface
  23. uses
  24. objects,symtable;
  25. const
  26. SymbolTypLen : integer = 6;
  27. RecordTypes : set of tsymtyp =
  28. ([typesym,unitsym,programsym]);
  29. type
  30. TStoreCollection = object(TStringCollection)
  31. function Add(const S: string): PString;
  32. end;
  33. PModuleNameCollection = ^TModuleNameCollection;
  34. TModuleNameCollection = object(TStoreCollection)
  35. end;
  36. PTypeNameCollection = ^TTypeNameCollection;
  37. TTypeNameCollection = object(TStoreCollection)
  38. end;
  39. PSymbolCollection = ^TSymbolCollection;
  40. PSortedSymbolCollection = ^TSortedSymbolCollection;
  41. PReferenceCollection = ^TReferenceCollection;
  42. PReference = ^TReference;
  43. TReference = object(TObject)
  44. FileName : PString;
  45. Position : TPoint;
  46. constructor Init(AFileName: PString; ALine, AColumn: Sw_integer);
  47. function GetFileName: string;
  48. destructor Done; virtual;
  49. end;
  50. PSymbol = ^TSymbol;
  51. TSymbol = object(TObject)
  52. Name : PString;
  53. Typ : tsymtyp;
  54. ParamCount : Sw_integer;
  55. Params : PPointerArray;
  56. References : PReferenceCollection;
  57. Items : PSymbolCollection;
  58. constructor Init(const AName: string; ATyp: tsymtyp; AParamCount: Sw_integer; AParams: PPointerArray);
  59. procedure SetParams(AParamCount: Sw_integer; AParams: PPointerArray);
  60. function GetReferenceCount: Sw_integer;
  61. function GetReference(Index: Sw_integer): PReference;
  62. function GetItemCount: Sw_integer;
  63. function GetItem(Index: Sw_integer): PSymbol;
  64. function GetName: string;
  65. function GetText: string;
  66. function GetTypeName: string;
  67. destructor Done; virtual;
  68. end;
  69. TSymbolCollection = object(TSortedCollection)
  70. function At(Index: Sw_Integer): PSymbol;
  71. procedure Insert(Item: Pointer); virtual;
  72. function LookUp(const S: string; var Idx: sw_integer): string; virtual;
  73. end;
  74. TSortedSymbolCollection = object(TSymbolCollection)
  75. function Compare(Key1, Key2: Pointer): Sw_Integer; virtual;
  76. procedure Insert(Item: Pointer); virtual;
  77. function LookUp(const S: string; var Idx: sw_integer): string; virtual;
  78. end;
  79. TReferenceCollection = object(TCollection)
  80. function At(Index: Sw_Integer): PReference;
  81. end;
  82. const
  83. Modules : PSymbolCollection = nil;
  84. ModuleNames : PModuleNameCollection = nil;
  85. TypeNames : PTypeNameCollection = nil;
  86. procedure DisposeBrowserCol;
  87. procedure NewBrowserCol;
  88. procedure CreateBrowserCol;
  89. procedure InitBrowserCol;
  90. procedure DoneBrowserCol;
  91. implementation
  92. uses
  93. Drivers,Views,App,
  94. globals,files,comphook;
  95. {****************************************************************************
  96. Helpers
  97. ****************************************************************************}
  98. function GetStr(P: PString): string;
  99. begin
  100. if P=nil then
  101. GetStr:=''
  102. else
  103. GetStr:=P^;
  104. end;
  105. {****************************************************************************
  106. TStoreCollection
  107. ****************************************************************************}
  108. function TStoreCollection.Add(const S: string): PString;
  109. var P: PString;
  110. Index: Sw_integer;
  111. begin
  112. if Search(@S,Index) then P:=At(Index) else
  113. begin
  114. P:=NewStr(S);
  115. Insert(P);
  116. end;
  117. Add:=P;
  118. end;
  119. {****************************************************************************
  120. TSymbolCollection
  121. ****************************************************************************}
  122. function TSymbolCollection.At(Index: Sw_Integer): PSymbol;
  123. begin
  124. At:=inherited At(Index);
  125. end;
  126. procedure TSymbolCollection.Insert(Item: Pointer);
  127. begin
  128. TCollection.Insert(Item);
  129. end;
  130. function TSymbolCollection.LookUp(const S: string; var Idx: sw_integer): string;
  131. begin
  132. Idx:=-1;
  133. LookUp:='';
  134. end;
  135. {****************************************************************************
  136. TReferenceCollection
  137. ****************************************************************************}
  138. function TReferenceCollection.At(Index: Sw_Integer): PReference;
  139. begin
  140. At:=inherited At(Index);
  141. end;
  142. {****************************************************************************
  143. TSortedSymbolCollection
  144. ****************************************************************************}
  145. function TSortedSymbolCollection.Compare(Key1, Key2: Pointer): Sw_Integer;
  146. var K1: PSymbol absolute Key1;
  147. K2: PSymbol absolute Key2;
  148. R: Sw_integer;
  149. S1,S2: string;
  150. begin
  151. S1:=Upper(K1^.GetName);
  152. S2:=Upper(K2^.GetName);
  153. if S1<S2 then R:=-1 else
  154. if S1>S2 then R:=1 else
  155. R:=0;
  156. Compare:=R;
  157. end;
  158. procedure TSortedSymbolCollection.Insert(Item: Pointer);
  159. begin
  160. TSortedCollection.Insert(Item);
  161. end;
  162. function TSortedSymbolCollection.LookUp(const S: string; var Idx: sw_integer): string;
  163. var OLI,ORI,Left,Right,Mid: integer;
  164. LeftP,RightP,MidP: PSymbol;
  165. RL: integer;
  166. LeftS,MidS,RightS: string;
  167. FoundS: string;
  168. UpS : string;
  169. begin
  170. Idx:=-1; FoundS:='';
  171. Left:=0; Right:=Count-1;
  172. UpS:=Upper(S);
  173. if Left<Right then
  174. begin
  175. while (Left<Right) do
  176. begin
  177. OLI:=Left; ORI:=Right;
  178. Mid:=Left+(Right-Left) div 2;
  179. LeftP:=At(Left); RightP:=At(Right); MidP:=At(Mid);
  180. LeftS:=Upper(LeftP^.GetName); MidS:=Upper(MidP^.GetName);
  181. RightS:=Upper(RightP^.GetName);
  182. if copy(MidS,1,length(UpS))=UpS then
  183. begin
  184. Idx:=Mid; FoundS:=copy(MidS,1,length(S));
  185. end;
  186. { else}
  187. if UpS<MidS then
  188. Right:=Mid
  189. else
  190. Left:=Mid;
  191. if (OLI=Left) and (ORI=Right) then
  192. Break;
  193. end;
  194. end;
  195. LookUp:=FoundS;
  196. end;
  197. {****************************************************************************
  198. TReference
  199. ****************************************************************************}
  200. constructor TReference.Init(AFileName: PString; ALine, AColumn: Sw_integer);
  201. begin
  202. inherited Init;
  203. FileName:=AFileName;
  204. Position.X:=AColumn;
  205. Position.Y:=ALine;
  206. end;
  207. function TReference.GetFileName: string;
  208. begin
  209. GetFileName:=GetStr(FileName);
  210. end;
  211. destructor TReference.Done;
  212. begin
  213. inherited Done;
  214. end;
  215. {****************************************************************************
  216. TSymbol
  217. ****************************************************************************}
  218. constructor TSymbol.Init(const AName: string; ATyp: tsymtyp; AParamCount: Sw_integer; AParams: PPointerArray);
  219. begin
  220. inherited Init;
  221. Name:=NewStr(AName); Typ:=ATyp;
  222. SetParams(AParamCount,AParams);
  223. New(References, Init(20,50));
  224. if ATyp in RecordTypes then
  225. begin
  226. Items:=New(PSortedSymbolCollection, Init(50,100));
  227. end;
  228. end;
  229. procedure TSymbol.SetParams(AParamCount: Sw_integer; AParams: PPointerArray);
  230. begin
  231. if AParams=nil then AParamCount:=0 else
  232. if AParamCount=0 then AParams:=nil;
  233. ParamCount:=AParamCount;
  234. if (ParamCount>0) and (AParams<>nil) then
  235. begin
  236. GetMem(Params, ParamCount*4);
  237. Move(AParams^,Params^,ParamCount*4);
  238. end;
  239. end;
  240. function TSymbol.GetReferenceCount: Sw_integer;
  241. var Count: Sw_integer;
  242. begin
  243. if References=nil then Count:=0 else
  244. Count:=References^.Count;
  245. GetReferenceCount:=Count;
  246. end;
  247. function TSymbol.GetReference(Index: Sw_integer): PReference;
  248. begin
  249. GetReference:=References^.At(Index);
  250. end;
  251. function TSymbol.GetItemCount: Sw_integer;
  252. var Count: Sw_integer;
  253. begin
  254. if Items=nil then Count:=0 else
  255. Count:=Items^.Count;
  256. GetItemCount:=Count;
  257. end;
  258. function TSymbol.GetItem(Index: Sw_integer): PSymbol;
  259. begin
  260. GetItem:=Items^.At(Index);
  261. end;
  262. function TSymbol.GetName: string;
  263. begin
  264. GetName:=GetStr(Name);
  265. end;
  266. function TSymbol.GetText: string;
  267. var S: string;
  268. I: Sw_integer;
  269. begin
  270. S:=GetTypeName;
  271. if length(S)>SymbolTypLen then
  272. S:=Copy(S,1,SymbolTypLen)
  273. else
  274. begin
  275. while length(S)<SymbolTypLen do
  276. S:=S+' ';
  277. end;
  278. S:=S+' '+GetName;
  279. if ParamCount>0 then
  280. begin
  281. S:=S+'(';
  282. for I:=1 to ParamCount do
  283. begin
  284. S:=S+GetStr(Params^[I-1]);
  285. if I<>ParamCount then S:=S+', ';
  286. end;
  287. S:=S+')';
  288. end;
  289. GetText:=S;
  290. end;
  291. function TSymbol.GetTypeName: string;
  292. var S: string;
  293. begin
  294. case Typ of
  295. abstractsym : S:='abst';
  296. varsym : S:='var';
  297. typesym : S:='type';
  298. procsym : S:='proc';
  299. unitsym : S:='unit';
  300. programsym : S:='prog';
  301. constsym : S:='const';
  302. enumsym : S:='enum';
  303. typedconstsym: S:='const';
  304. errorsym : S:='error';
  305. syssym : S:='sys';
  306. labelsym : S:='label';
  307. absolutesym : S:='abs';
  308. propertysym : S:='prop';
  309. funcretsym : S:='func';
  310. macrosym : S:='macro';
  311. else S:='';
  312. end;
  313. GetTypeName:=S;
  314. end;
  315. destructor TSymbol.Done;
  316. begin
  317. inherited Done;
  318. if assigned(References) then
  319. Dispose(References, Done);
  320. if assigned(Items) then
  321. Dispose(Items, Done);
  322. if assigned(Name) then
  323. DisposeStr(Name);
  324. if assigned(Params) then
  325. FreeMem(Params,ParamCount*2);
  326. end;
  327. {*****************************************************************************
  328. Main Routines
  329. *****************************************************************************}
  330. procedure DisposeBrowserCol;
  331. begin
  332. if assigned(Modules) then
  333. begin
  334. dispose(Modules,Done);
  335. Modules:=nil;
  336. end;
  337. if assigned(ModuleNames) then
  338. begin
  339. dispose(ModuleNames,Done);
  340. ModuleNames:=nil;
  341. end;
  342. if assigned(TypeNames) then
  343. begin
  344. dispose(TypeNames,Done);
  345. TypeNames:=nil;
  346. end;
  347. end;
  348. procedure NewBrowserCol;
  349. begin
  350. New(Modules, Init(50,50));
  351. New(ModuleNames, Init(50,50));
  352. New(TypeNames, Init(1000,5000));
  353. end;
  354. procedure CreateBrowserCol;
  355. procedure ProcessSymTable(var Owner: PSymbolCollection; Table: PSymTable);
  356. var I,J,defcount, symcount: longint;
  357. Ref: PRef;
  358. Sym,ParSym: PSym;
  359. Symbol: PSymbol;
  360. Reference: PReference;
  361. ParamCount: Sw_integer;
  362. Params: array[0..20] of PString;
  363. inputfile : pinputfile;
  364. begin
  365. if Assigned(Table)=false then Exit;
  366. if Owner=nil then Owner:=New(PSortedSymbolCollection, Init(10,50));
  367. defcount:=Table^.number_defs;
  368. symcount:=Table^.number_symbols;
  369. { for I:=0 to defcount-1 do
  370. begin
  371. Def:=Table^.GetDefNr(I);
  372. end;}
  373. for I:=1 to symcount-1 do
  374. begin
  375. Sym:=Table^.GetsymNr(I);
  376. if Sym=nil then Continue;
  377. ParamCount:=0;
  378. New(Symbol, Init(Sym^.Name,Sym^.Typ,0,nil));
  379. case Sym^.Typ of
  380. unitsym :
  381. begin
  382. { ProcessSymTable(Symbol^.Items,punitsym(sym)^.unitsymtable);}
  383. end;
  384. procsym :
  385. with pprocsym(sym)^ do
  386. if assigned(definition) then
  387. begin
  388. if assigned(definition^.parast) then
  389. begin
  390. with definition^.parast^ do
  391. for J:=1 to number_symbols do
  392. begin
  393. ParSym:=GetsymNr(J);
  394. if ParSym=nil then Break;
  395. Inc(ParamCount);
  396. Params[ParamCount-1]:=TypeNames^.Add(ParSym^.Name);
  397. end;
  398. end;
  399. if assigned(definition^.localst) then
  400. ProcessSymTable(Symbol^.Items,definition^.localst);
  401. end;
  402. typesym :
  403. begin
  404. end;
  405. end;
  406. Ref:=Sym^.defref;
  407. while assigned(Ref) do
  408. begin
  409. inputfile:=get_source_file(ref^.moduleindex,ref^.posinfo.fileindex);
  410. if Assigned(inputfile) and Assigned(inputfile^.name) then
  411. begin
  412. New(Reference, Init(ModuleNames^.Add(inputfile^.name^),
  413. ref^.posinfo.line,ref^.posinfo.column));
  414. Symbol^.References^.Insert(Reference);
  415. end;
  416. Ref:=Ref^.nextref;
  417. end;
  418. Owner^.Insert(Symbol);
  419. end;
  420. end;
  421. var
  422. T: PSymTable;
  423. UnitS: PSymbol;
  424. begin
  425. DisposeBrowserCol;
  426. NewBrowserCol;
  427. T:=SymTableStack;
  428. while assigned(T) do
  429. begin
  430. New(UnitS, Init(T^.Name^,unitsym, 0, nil));
  431. Modules^.Insert(UnitS);
  432. ProcessSymTable(UnitS^.Items,T);
  433. T:=T^.Next;
  434. end;
  435. end;
  436. {*****************************************************************************
  437. Initialize
  438. *****************************************************************************}
  439. var
  440. oldexit : pointer;
  441. procedure browcol_exit;{$ifndef FPC}far;{$endif}
  442. begin
  443. exitproc:=oldexit;
  444. DisposeBrowserCol;
  445. end;
  446. procedure InitBrowserCol;
  447. begin
  448. end;
  449. procedure DoneBrowserCol;
  450. begin
  451. { nothing, the collections are freed in the exitproc }
  452. end;
  453. begin
  454. oldexit:=exitproc;
  455. exitproc:=@browcol_exit;
  456. end.
  457. {
  458. $Log$
  459. Revision 1.3 1999-01-22 10:19:43 peter
  460. * fixed typo
  461. Revision 1.2 1999/01/21 11:49:14 peter
  462. * updates from gabor
  463. Revision 1.1 1999/01/12 14:25:24 peter
  464. + BrowserLog for browser.log generation
  465. + BrowserCol for browser info in TCollections
  466. * released all other UseBrowser
  467. }