browcol.pas 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  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. RecordTypes : set of tsymtyp =
  27. ([typesym,unitsym,programsym]);
  28. type
  29. TStoreCollection = object(TStringCollection)
  30. function Add(const S: string): PString;
  31. end;
  32. PModuleNameCollection = ^TModuleNameCollection;
  33. TModuleNameCollection = object(TStoreCollection)
  34. end;
  35. PTypeNameCollection = ^TTypeNameCollection;
  36. TTypeNameCollection = object(TStoreCollection)
  37. end;
  38. PSymbolCollection = ^TSymbolCollection;
  39. PSortedSymbolCollection = ^TSortedSymbolCollection;
  40. PReferenceCollection = ^TReferenceCollection;
  41. PReference = ^TReference;
  42. TReference = object(TObject)
  43. FileName : PString;
  44. Position : TPoint;
  45. constructor Init(AFileName: PString; ALine, AColumn: Sw_integer);
  46. function GetFileName: string;
  47. destructor Done; virtual;
  48. end;
  49. PSymbol = ^TSymbol;
  50. TSymbol = object(TObject)
  51. Name : PString;
  52. Typ : tsymtyp;
  53. ParamCount : Sw_integer;
  54. Params : PPointerArray;
  55. References : PReferenceCollection;
  56. Items : PSymbolCollection;
  57. constructor Init(const AName: string; ATyp: tsymtyp; AParamCount: Sw_integer; AParams: PPointerArray);
  58. procedure SetParams(AParamCount: Sw_integer; AParams: PPointerArray);
  59. function GetReferenceCount: Sw_integer;
  60. function GetReference(Index: Sw_integer): PReference;
  61. function GetItemCount: Sw_integer;
  62. function GetItem(Index: Sw_integer): PSymbol;
  63. function GetName: string;
  64. function GetText: string;
  65. function GetTypeName: string;
  66. destructor Done; virtual;
  67. end;
  68. TSymbolCollection = object(TSortedCollection)
  69. function At(Index: Sw_Integer): PSymbol;
  70. procedure Insert(Item: Pointer); virtual;
  71. end;
  72. TSortedSymbolCollection = object(TSymbolCollection)
  73. function Compare(Key1, Key2: Pointer): Sw_Integer; virtual;
  74. procedure Insert(Item: Pointer); virtual;
  75. end;
  76. TReferenceCollection = object(TCollection)
  77. function At(Index: Sw_Integer): PReference;
  78. end;
  79. const
  80. Modules : PSymbolCollection = nil;
  81. ModuleNames : PModuleNameCollection = nil;
  82. TypeNames : PTypeNameCollection = nil;
  83. procedure CreateBrowserCol;
  84. procedure InitBrowserCol;
  85. procedure DoneBrowserCol;
  86. implementation
  87. uses
  88. files;
  89. {****************************************************************************
  90. Helpers
  91. ****************************************************************************}
  92. function GetStr(P: PString): string;
  93. begin
  94. if P=nil then
  95. GetStr:=''
  96. else
  97. GetStr:=P^;
  98. end;
  99. {****************************************************************************
  100. TStoreCollection
  101. ****************************************************************************}
  102. function TStoreCollection.Add(const S: string): PString;
  103. var P: PString;
  104. Index: Sw_integer;
  105. begin
  106. if Search(@S,Index) then P:=At(Index) else
  107. begin
  108. P:=NewStr(S);
  109. Insert(P);
  110. end;
  111. Add:=P;
  112. end;
  113. {****************************************************************************
  114. TSymbolCollection
  115. ****************************************************************************}
  116. function TSymbolCollection.At(Index: Sw_Integer): PSymbol;
  117. begin
  118. At:=inherited At(Index);
  119. end;
  120. procedure TSymbolCollection.Insert(Item: Pointer);
  121. begin
  122. TCollection.Insert(Item);
  123. end;
  124. {****************************************************************************
  125. TReferenceCollection
  126. ****************************************************************************}
  127. function TReferenceCollection.At(Index: Sw_Integer): PReference;
  128. begin
  129. At:=inherited At(Index);
  130. end;
  131. {****************************************************************************
  132. TSortedSymbolCollection
  133. ****************************************************************************}
  134. function TSortedSymbolCollection.Compare(Key1, Key2: Pointer): Sw_Integer;
  135. var K1: PSymbol absolute Key1;
  136. K2: PSymbol absolute Key2;
  137. R: Sw_integer;
  138. begin
  139. if K1^.GetName<K2^.GetName then R:=-1 else
  140. if K1^.GetName>K2^.GetName then R:=1 else
  141. R:=0;
  142. Compare:=R;
  143. end;
  144. procedure TSortedSymbolCollection.Insert(Item: Pointer);
  145. begin
  146. TSortedCollection.Insert(Item);
  147. end;
  148. {****************************************************************************
  149. TReference
  150. ****************************************************************************}
  151. constructor TReference.Init(AFileName: PString; ALine, AColumn: Sw_integer);
  152. begin
  153. inherited Init;
  154. FileName:=AFileName;
  155. Position.X:=AColumn;
  156. Position.Y:=ALine;
  157. end;
  158. function TReference.GetFileName: string;
  159. begin
  160. GetFileName:=GetStr(FileName);
  161. end;
  162. destructor TReference.Done;
  163. begin
  164. inherited Done;
  165. end;
  166. {****************************************************************************
  167. TSymbol
  168. ****************************************************************************}
  169. constructor TSymbol.Init(const AName: string; ATyp: tsymtyp; AParamCount: Sw_integer; AParams: PPointerArray);
  170. begin
  171. inherited Init;
  172. Name:=NewStr(AName); Typ:=ATyp;
  173. SetParams(AParamCount,AParams);
  174. New(References, Init(20,50));
  175. if ATyp in RecordTypes then
  176. begin
  177. Items:=New(PSortedSymbolCollection, Init(50,100));
  178. end;
  179. end;
  180. procedure TSymbol.SetParams(AParamCount: Sw_integer; AParams: PPointerArray);
  181. begin
  182. if AParams=nil then AParamCount:=0 else
  183. if AParamCount=0 then AParams:=nil;
  184. ParamCount:=AParamCount;
  185. if (ParamCount>0) and (AParams<>nil) then
  186. begin
  187. GetMem(Params, ParamCount*4);
  188. Move(AParams^,Params^,ParamCount*4);
  189. end;
  190. end;
  191. function TSymbol.GetReferenceCount: Sw_integer;
  192. var Count: Sw_integer;
  193. begin
  194. if References=nil then Count:=0 else
  195. Count:=References^.Count;
  196. GetReferenceCount:=Count;
  197. end;
  198. function TSymbol.GetReference(Index: Sw_integer): PReference;
  199. begin
  200. GetReference:=References^.At(Index);
  201. end;
  202. function TSymbol.GetItemCount: Sw_integer;
  203. var Count: Sw_integer;
  204. begin
  205. if Items=nil then Count:=0 else
  206. Count:=Items^.Count;
  207. GetItemCount:=Count;
  208. end;
  209. function TSymbol.GetItem(Index: Sw_integer): PSymbol;
  210. begin
  211. GetItem:=Items^.At(Index);
  212. end;
  213. function TSymbol.GetName: string;
  214. begin
  215. GetName:=GetStr(Name);
  216. end;
  217. function TSymbol.GetText: string;
  218. var S: string;
  219. I: Sw_integer;
  220. begin
  221. S:=GetTypeName+' '+GetName;
  222. if ParamCount>0 then
  223. begin
  224. S:=S+'(';
  225. for I:=1 to ParamCount do
  226. begin
  227. S:=S+GetStr(Params^[I-1]);
  228. if I<>ParamCount then S:=S+', ';
  229. end;
  230. S:=S+')';
  231. end;
  232. GetText:=S;
  233. end;
  234. function TSymbol.GetTypeName: string;
  235. var S: string;
  236. begin
  237. case Typ of
  238. abstractsym : S:='abst ';
  239. varsym : S:='var ';
  240. typesym : S:='type ';
  241. procsym : S:='proc ';
  242. unitsym : S:='unit ';
  243. programsym : S:='prog ';
  244. constsym : S:='const';
  245. enumsym : S:='enum ';
  246. typedconstsym: S:='const';
  247. errorsym : S:='error';
  248. syssym : S:='sys ';
  249. labelsym : S:='label';
  250. absolutesym : S:='abs ';
  251. propertysym : S:='prop ';
  252. funcretsym : S:='func ';
  253. macrosym : S:='macro';
  254. else S:='';
  255. end;
  256. GetTypeName:=S;
  257. end;
  258. destructor TSymbol.Done;
  259. begin
  260. inherited Done;
  261. if References<>nil then Dispose(References, Done);
  262. if Items<>nil then Dispose(Items, Done);
  263. if Name<>nil then DisposeStr(Name);
  264. if Params<>nil then FreeMem(Params,ParamCount*2);
  265. end;
  266. procedure CreateBrowserCol;
  267. procedure ProcessSymTable(var Owner: PSymbolCollection; Table: PSymTable);
  268. var I,J,defcount, symcount: longint;
  269. Ref: PRef;
  270. Sym,ParSym: PSym;
  271. Symbol: PSymbol;
  272. Reference: PReference;
  273. ParamCount: Sw_integer;
  274. Params: array[0..20] of PString;
  275. inputfile : pinputfile;
  276. begin
  277. if Assigned(Table)=false then Exit;
  278. if Owner=nil then Owner:=New(PSortedSymbolCollection, Init(10,50));
  279. defcount:=Table^.number_defs;
  280. symcount:=Table^.number_symbols;
  281. { for I:=0 to defcount-1 do
  282. begin
  283. Def:=Table^.GetDefNr(I);
  284. end;}
  285. for I:=1 to symcount-1 do
  286. begin
  287. Sym:=Table^.GetsymNr(I);
  288. if Sym=nil then Continue;
  289. ParamCount:=0;
  290. New(Symbol, Init(Sym^.Name,Sym^.Typ,0,nil));
  291. case Sym^.Typ of
  292. unitsym :
  293. begin
  294. { ProcessSymTable(Symbol^.Items,punitsym(sym)^.unitsymtable);}
  295. end;
  296. procsym :
  297. with pprocsym(sym)^ do
  298. if assigned(definition) then
  299. begin
  300. if assigned(definition^.parast) then
  301. begin
  302. with definition^.parast^ do
  303. for J:=1 to number_symbols do
  304. begin
  305. ParSym:=GetsymNr(J);
  306. if ParSym=nil then Break;
  307. Inc(ParamCount);
  308. Params[ParamCount-1]:=TypeNames^.Add(ParSym^.Name);
  309. end;
  310. end;
  311. if assigned(definition^.localst) then
  312. ProcessSymTable(Symbol^.Items,definition^.localst);
  313. end;
  314. typesym :
  315. begin
  316. end;
  317. end;
  318. Ref:=Sym^.defref;
  319. while assigned(Ref) do
  320. begin
  321. inputfile:=get_source_file(ref^.moduleindex,ref^.posinfo.fileindex);
  322. if Assigned(inputfile) and Assigned(inputfile^.name) then
  323. begin
  324. New(Reference, Init(ModuleNames^.Add(inputfile^.name^),
  325. ref^.posinfo.line,ref^.posinfo.column));
  326. Symbol^.References^.Insert(Reference);
  327. end;
  328. Ref:=Ref^.nextref;
  329. end;
  330. Owner^.Insert(Symbol);
  331. end;
  332. end;
  333. var
  334. T: PSymTable;
  335. UnitS: PSymbol;
  336. begin
  337. T:=SymTableStack;
  338. while T<>nil do
  339. begin
  340. New(UnitS, Init(T^.Name^,unitsym, 0, nil));
  341. Modules^.Insert(UnitS);
  342. ProcessSymTable(UnitS^.Items,T);
  343. T:=T^.Next;
  344. end;
  345. end;
  346. {*****************************************************************************
  347. Initialize
  348. *****************************************************************************}
  349. var
  350. oldexit : pointer;
  351. procedure browcol_exit;{$ifndef FPC}far;{$endif}
  352. begin
  353. exitproc:=oldexit;
  354. if assigned(Modules) then
  355. begin
  356. dispose(Modules,Done);
  357. Modules:=nil;
  358. end;
  359. if assigned(ModuleNames) then
  360. begin
  361. dispose(ModuleNames,Done);
  362. Modules:=nil;
  363. end;
  364. if assigned(TypeNames) then
  365. begin
  366. dispose(TypeNames,Done);
  367. TypeNames:=nil;
  368. end;
  369. end;
  370. procedure InitBrowserCol;
  371. begin
  372. New(Modules, Init(50,50));
  373. New(ModuleNames, Init(50,50));
  374. New(TypeNames, Init(1000,5000));
  375. end;
  376. procedure DoneBrowserCol;
  377. begin
  378. { nothing, the collections are freed in the exitproc }
  379. end;
  380. begin
  381. oldexit:=exitproc;
  382. exitproc:=@browcol_exit;
  383. end.
  384. {
  385. $Log$
  386. Revision 1.1 1999-01-12 14:25:24 peter
  387. + BrowserLog for browser.log generation
  388. + BrowserCol for browser info in TCollections
  389. * released all other UseBrowser
  390. }