browlog.pas 12 KB

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