browlog.pas 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. {
  2. $Id$
  3. Copyright (c) 1993-98 by the FPC development team
  4. Support routines for creating the browser log
  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 browlog;
  22. interface
  23. uses
  24. cobjects,globtype,files,symtable;
  25. const
  26. {$ifdef TP}
  27. logbufsize = 1024;
  28. {$else}
  29. logbufsize = 16384;
  30. {$endif}
  31. type
  32. pbrowserlog=^tbrowserlog;
  33. tbrowserlog=object
  34. fname : string;
  35. logopen : boolean;
  36. stderrlog : boolean;
  37. f : file;
  38. elements_to_list : pstringqueue;
  39. buf : pchar;
  40. bufidx : longint;
  41. identidx : longint;
  42. constructor init;
  43. destructor done;
  44. procedure setfilename(const fn:string);
  45. procedure createlog;
  46. procedure flushlog;
  47. procedure addlog(const s:string);
  48. procedure addlogrefs(p:pref);
  49. procedure closelog;
  50. procedure ident;
  51. procedure unident;
  52. procedure browse_symbol(const sr : string);
  53. procedure list_elements;
  54. procedure list_debug_infos;
  55. end;
  56. var
  57. browserlog : tbrowserlog;
  58. procedure WriteBrowserLog;
  59. procedure InitBrowserLog;
  60. procedure DoneBrowserLog;
  61. implementation
  62. uses
  63. comphook,globals,systems,verbose;
  64. function get_file_line(ref:pref): string;
  65. var
  66. inputfile : pinputfile;
  67. begin
  68. get_file_line:='';
  69. with ref^ do
  70. begin
  71. inputfile:=get_source_file(moduleindex,posinfo.fileindex);
  72. if assigned(inputfile) then
  73. if status.use_gccoutput then
  74. { for use with rhide
  75. add warning so that it does not interpret
  76. this as an error !! }
  77. get_file_line:=lower(inputfile^.name^)
  78. +':'+tostr(posinfo.line)+': warning: '+tostr(posinfo.column)+':'
  79. else
  80. get_file_line:=inputfile^.name^
  81. +'('+tostr(posinfo.line)+','+tostr(posinfo.column)+')'
  82. else
  83. if status.use_gccoutput then
  84. get_file_line:='file_unknown:'
  85. +tostr(posinfo.line)+': warning: '+tostr(posinfo.column)+':'
  86. else
  87. get_file_line:='file_unknown('
  88. +tostr(posinfo.line)+','+tostr(posinfo.column)+')'
  89. end;
  90. end;
  91. {****************************************************************************
  92. TBrowser
  93. ****************************************************************************}
  94. constructor tbrowserlog.init;
  95. begin
  96. fname:=FixFileName('browser.log');
  97. logopen:=false;
  98. elements_to_list:=new(pstringqueue,init);
  99. end;
  100. destructor tbrowserlog.done;
  101. begin
  102. if logopen then
  103. closelog;
  104. dispose(elements_to_list,done);
  105. end;
  106. procedure tbrowserlog.setfilename(const fn:string);
  107. begin
  108. fname:=FixFileName(fn);
  109. end;
  110. procedure tbrowserlog.createlog;
  111. begin
  112. if logopen then
  113. closelog;
  114. assign(f,fname);
  115. {$I-}
  116. rewrite(f,1);
  117. {$I+}
  118. if ioresult<>0 then
  119. exit;
  120. logopen:=true;
  121. getmem(buf,logbufsize);
  122. bufidx:=0;
  123. identidx:=0;
  124. end;
  125. procedure tbrowserlog.flushlog;
  126. begin
  127. if logopen then
  128. if not stderrlog then
  129. blockwrite(f,buf^,bufidx)
  130. else
  131. begin
  132. buf[bufidx]:=#0;
  133. {$ifndef TP}
  134. write(stderr,buf);
  135. {$else TP}
  136. write(buf);
  137. {$endif TP}
  138. end;
  139. bufidx:=0;
  140. end;
  141. procedure tbrowserlog.closelog;
  142. begin
  143. if logopen then
  144. begin
  145. flushlog;
  146. close(f);
  147. freemem(buf,logbufsize);
  148. logopen:=false;
  149. end;
  150. end;
  151. procedure tbrowserlog.list_elements;
  152. begin
  153. stderrlog:=true;
  154. getmem(buf,logbufsize);
  155. logopen:=true;
  156. while not elements_to_list^.empty do
  157. browse_symbol(elements_to_list^.get);
  158. flushlog;
  159. logopen:=false;
  160. freemem(buf,logbufsize);
  161. stderrlog:=false;
  162. end;
  163. procedure tbrowserlog.list_debug_infos;
  164. {$ifndef debug}
  165. begin
  166. end;
  167. {$else debug}
  168. var
  169. hp : pmodule;
  170. ff : pinputfile;
  171. begin
  172. hp:=pmodule(loaded_units.first);
  173. while assigned(hp) do
  174. begin
  175. addlog('Unit '+hp^.modulename^+' has index '+tostr(hp^.unit_index));
  176. ff:=hp^.sourcefiles^.files;
  177. while assigned(ff) do
  178. begin
  179. addlog('File '+ff^.name^+' index '+tostr(ff^.ref_index));
  180. ff:=ff^.ref_next;
  181. end;
  182. hp:=pmodule(hp^.next);
  183. end;
  184. end;
  185. {$endif debug}
  186. procedure tbrowserlog.addlog(const s:string);
  187. begin
  188. if not logopen then
  189. exit;
  190. { add ident }
  191. if (identidx>0) and not stderrlog then
  192. begin
  193. if bufidx+identidx>logbufsize then
  194. flushlog;
  195. fillchar(buf[bufidx],identidx,' ');
  196. inc(bufidx,identidx);
  197. end;
  198. { add text }
  199. if bufidx+length(s)>logbufsize-2 then
  200. flushlog;
  201. move(s[1],buf[bufidx],length(s));
  202. inc(bufidx,length(s));
  203. { add crlf }
  204. buf[bufidx]:=target_os.newline[1];
  205. inc(bufidx);
  206. if length(target_os.newline)=2 then
  207. begin
  208. buf[bufidx]:=target_os.newline[2];
  209. inc(bufidx);
  210. end;
  211. end;
  212. procedure tbrowserlog.addlogrefs(p:pref);
  213. var
  214. ref : pref;
  215. begin
  216. ref:=p;
  217. Ident;
  218. while assigned(ref) do
  219. begin
  220. Browserlog.AddLog(get_file_line(ref));
  221. ref:=ref^.nextref;
  222. end;
  223. Unident;
  224. end;
  225. procedure tbrowserlog.browse_symbol(const sr : string);
  226. var
  227. sym,symb : psym;
  228. symt : psymtable;
  229. hp : pmodule;
  230. s,ss : string;
  231. p : byte;
  232. procedure next_substring;
  233. begin
  234. p:=pos('.',s);
  235. if p>0 then
  236. begin
  237. ss:=copy(s,1,p-1);
  238. s:=copy(s,p+1,255);
  239. end
  240. else
  241. begin
  242. ss:=s;
  243. s:='';
  244. end;
  245. addlog('substring : '+ss);
  246. end;
  247. begin
  248. { don't create a new reference when
  249. looking for the symbol !! }
  250. make_ref:=false;
  251. s:=sr;
  252. symt:=symtablestack;
  253. next_substring;
  254. if assigned(symt) then
  255. begin
  256. sym:=symt^.search(ss);
  257. if sym=nil then
  258. sym:=symt^.search(upper(ss));
  259. end
  260. else
  261. sym:=nil;
  262. if assigned(sym) and (sym^.typ=unitsym) and (s<>'') then
  263. begin
  264. addlog('Unitsym found !');
  265. symt:=punitsym(sym)^.unitsymtable;
  266. if assigned(symt) then
  267. begin
  268. next_substring;
  269. sym:=symt^.search(ss);
  270. end
  271. else
  272. sym:=nil;
  273. end;
  274. if not assigned(sym) then
  275. begin
  276. symt:=nil;
  277. { try all loaded_units }
  278. hp:=pmodule(loaded_units.first);
  279. while assigned(hp) do
  280. begin
  281. if hp^.modulename^=upper(ss) then
  282. begin
  283. symt:=hp^.globalsymtable;
  284. break;
  285. end;
  286. hp:=pmodule(hp^.next);
  287. end;
  288. if not assigned(symt) then
  289. begin
  290. addlog('!!!Symbol '+ss+' not found !!!');
  291. make_ref:=true;
  292. exit;
  293. end
  294. else
  295. begin
  296. next_substring;
  297. sym:=symt^.search(ss);
  298. if sym=nil then
  299. sym:=symt^.search(upper(ss));
  300. end;
  301. end;
  302. while assigned(sym) and (s<>'') do
  303. begin
  304. next_substring;
  305. case sym^.typ of
  306. typesym :
  307. begin
  308. if ptypesym(sym)^.definition^.deftype in [recorddef,objectdef] then
  309. begin
  310. if ptypesym(sym)^.definition^.deftype=recorddef then
  311. symt:=precorddef(ptypesym(sym)^.definition)^.symtable
  312. else
  313. symt:=pobjectdef(ptypesym(sym)^.definition)^.symtable;
  314. sym:=symt^.search(ss);
  315. if sym=nil then
  316. sym:=symt^.search(upper(ss));
  317. end;
  318. end;
  319. varsym :
  320. begin
  321. if pvarsym(sym)^.definition^.deftype in [recorddef,objectdef] then
  322. begin
  323. if pvarsym(sym)^.definition^.deftype=recorddef then
  324. symt:=precorddef(pvarsym(sym)^.definition)^.symtable
  325. else
  326. symt:=pobjectdef(pvarsym(sym)^.definition)^.symtable;
  327. sym:=symt^.search(ss);
  328. if sym=nil then
  329. sym:=symt^.search(upper(ss));
  330. end;
  331. end;
  332. procsym :
  333. begin
  334. symt:=pprocsym(sym)^.definition^.parast;
  335. symb:=symt^.search(ss);
  336. if symb=nil then
  337. symb:=symt^.search(upper(ss));
  338. if not assigned(symb) then
  339. begin
  340. symt:=pprocsym(sym)^.definition^.parast;
  341. sym:=symt^.search(ss);
  342. if symb=nil then
  343. symb:=symt^.search(upper(ss));
  344. end
  345. else
  346. sym:=symb;
  347. end;
  348. {else
  349. sym^.add_to_browserlog;}
  350. end;
  351. end;
  352. if assigned(sym) then
  353. sym^.add_to_browserlog
  354. else
  355. addlog('!!!Symbol '+ss+' not found !!!');
  356. make_ref:=true;
  357. end;
  358. procedure tbrowserlog.ident;
  359. begin
  360. inc(identidx,2);
  361. end;
  362. procedure tbrowserlog.unident;
  363. begin
  364. dec(identidx,2);
  365. end;
  366. {****************************************************************************
  367. Helpers
  368. ****************************************************************************}
  369. procedure WriteBrowserLog;
  370. var
  371. p : psymtable;
  372. hp : pmodule;
  373. begin
  374. browserlog.CreateLog;
  375. browserlog.list_debug_infos;
  376. hp:=pmodule(loaded_units.first);
  377. while assigned(hp) do
  378. begin
  379. p:=psymtable(hp^.globalsymtable);
  380. if assigned(p) then
  381. p^.writebrowserlog;
  382. if cs_local_browser in aktmoduleswitches then
  383. begin
  384. p:=psymtable(hp^.localsymtable);
  385. if assigned(p) then
  386. p^.writebrowserlog;
  387. end;
  388. hp:=pmodule(hp^.next);
  389. end;
  390. browserlog.CloseLog;
  391. end;
  392. procedure InitBrowserLog;
  393. begin
  394. browserlog.init;
  395. end;
  396. procedure DoneBrowserLog;
  397. begin
  398. browserlog.done;
  399. end;
  400. end.
  401. {
  402. $Log$
  403. Revision 1.2 1999-08-03 22:02:30 peter
  404. * moved bitmask constants to sets
  405. * some other type/const renamings
  406. Revision 1.1 1999/01/12 14:25:24 peter
  407. + BrowserLog for browser.log generation
  408. + BrowserCol for browser info in TCollections
  409. * released all other UseBrowser
  410. }