symppu.inc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. {
  2. $Id$
  3. Copyright (c) 1993-98 by Florian Klaempfl, Pierre Muller
  4. Implementation of the reading of PPU Files for the symtable
  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. const
  19. {$ifdef FPC}
  20. ppubufsize=32768;
  21. {$ELSE}
  22. {$IFDEF USEOVERLAY}
  23. ppubufsize=512;
  24. {$ELSE}
  25. ppubufsize=4096;
  26. {$ENDIF}
  27. {$ENDIF}
  28. {*****************************************************************************
  29. PPU Writing
  30. *****************************************************************************}
  31. procedure writebyte(b:byte);
  32. begin
  33. current_ppu^.putbyte(b);
  34. end;
  35. procedure writeword(w:word);
  36. begin
  37. current_ppu^.putword(w);
  38. end;
  39. procedure writelong(l:longint);
  40. begin
  41. current_ppu^.putlongint(l);
  42. end;
  43. procedure writereal(d:bestreal);
  44. begin
  45. current_ppu^.putreal(d);
  46. end;
  47. procedure writestring(const s:string);
  48. begin
  49. current_ppu^.putstring(s);
  50. end;
  51. procedure writenormalset(var s); {You cannot pass an array[0..31] of byte!}
  52. begin
  53. current_ppu^.putdata(s,sizeof(tnormalset));
  54. end;
  55. procedure writecontainer(var p:tstringcontainer;id:byte;hold,strippath:boolean);
  56. var
  57. hcontainer : tstringcontainer;
  58. s : string;
  59. begin
  60. if hold then
  61. hcontainer.init;
  62. while not p.empty do
  63. begin
  64. s:=p.get;
  65. if strippath then
  66. current_ppu^.putstring(SplitFileName(s))
  67. else
  68. current_ppu^.putstring(s);
  69. if hold then
  70. hcontainer.insert(s);
  71. end;
  72. current_ppu^.writeentry(id);
  73. if hold then
  74. p:=hcontainer;
  75. end;
  76. procedure writeposinfo(const p:tfileposinfo);
  77. begin
  78. current_ppu^.putword(p.fileindex);
  79. current_ppu^.putlongint(p.line);
  80. current_ppu^.putword(p.column);
  81. end;
  82. procedure writedefref(p : pdef);
  83. begin
  84. if p=nil then
  85. current_ppu^.putlongint($ffffffff)
  86. else
  87. begin
  88. if (p^.owner^.symtabletype in [recordsymtable,objectsymtable]) then
  89. current_ppu^.putword($ffff)
  90. else
  91. current_ppu^.putword(p^.owner^.unitid);
  92. current_ppu^.putword(p^.indexnb);
  93. end;
  94. end;
  95. procedure writesymref(p : psym);
  96. begin
  97. if p=nil then
  98. current_ppu^.putlongint($ffffffff)
  99. else
  100. begin
  101. if (p^.owner^.symtabletype in [recordsymtable,objectsymtable]) then
  102. current_ppu^.putword($ffff)
  103. else
  104. current_ppu^.putword(p^.owner^.unitid);
  105. current_ppu^.putword(p^.indexnb);
  106. end;
  107. end;
  108. procedure writesourcefiles;
  109. var
  110. hp : pinputfile;
  111. begin
  112. { second write the used source files }
  113. hp:=current_module^.sourcefiles^.files;
  114. while assigned(hp) do
  115. begin
  116. { only name and extension }
  117. current_ppu^.putstring(hp^.name^);
  118. hp:=hp^.ref_next;
  119. end;
  120. current_ppu^.writeentry(ibsourcefiles);
  121. end;
  122. procedure writeusedunit;
  123. var
  124. hp : pused_unit;
  125. begin
  126. numberunits;
  127. hp:=pused_unit(current_module^.used_units.first);
  128. while assigned(hp) do
  129. begin
  130. current_ppu^.putstring(hp^.name^);
  131. { the checksum should not affect the crc of this unit ! (PFV) }
  132. current_ppu^.do_crc:=false;
  133. current_ppu^.putlongint(hp^.checksum);
  134. current_ppu^.do_crc:=true;
  135. current_ppu^.putbyte(byte(hp^.in_interface));
  136. hp:=pused_unit(hp^.next);
  137. end;
  138. current_ppu^.writeentry(ibloadunit_int);
  139. end;
  140. procedure writeunitas(const s : string;unittable : punitsymtable);
  141. begin
  142. Message1(unit_u_ppu_write,s);
  143. { create unit flags }
  144. with Current_Module^ do
  145. begin
  146. if cs_create_staticlib in aktmoduleswitches then
  147. begin
  148. flags:=flags or uf_static_linked;
  149. if SplitName(ppufilename^)<>SplitName(staticlibfilename^) then
  150. flags:=flags or uf_in_library;
  151. end;
  152. if cs_create_sharedlib in aktmoduleswitches then
  153. begin
  154. flags:=flags or uf_shared_linked;
  155. if SplitName(ppufilename^)<>SplitName(sharedlibfilename^) then
  156. flags:=flags or uf_in_library;
  157. end;
  158. if cs_smartlink in aktmoduleswitches then
  159. flags:=flags or uf_smartlink;
  160. {$ifdef GDB}
  161. if use_dbx then
  162. flags:=flags or uf_has_dbx;
  163. {$endif GDB}
  164. if target_os.endian=endian_big then
  165. flags:=flags or uf_big_endian;
  166. {$ifdef UseBrowser}
  167. if cs_browser in aktmoduleswitches then
  168. flags:=flags or uf_has_browser;
  169. if cs_local_browser in aktmoduleswitches then
  170. flags:=flags or uf_local_browser;
  171. {$endif UseBrowser}
  172. end;
  173. { open ppufile }
  174. current_ppu:=new(pppufile,init(s));
  175. if not current_ppu^.create then
  176. Message(unit_f_ppu_cannot_write);
  177. current_ppu^.change_endian:=source_os.endian<>target_os.endian;
  178. { write symbols and definitions }
  179. unittable^.writeasunit;
  180. { flush to be sure }
  181. current_ppu^.flush;
  182. { create and write header }
  183. current_ppu^.header.size:=current_ppu^.size;
  184. current_ppu^.header.checksum:=current_ppu^.crc;
  185. current_ppu^.header.compiler:=wordversion;
  186. current_ppu^.header.cpu:=word(target_cpu);
  187. current_ppu^.header.target:=word(target_info.target);
  188. current_ppu^.header.flags:=current_module^.flags;
  189. current_ppu^.writeheader;
  190. { save crc in current_module also }
  191. current_module^.crc:=current_ppu^.crc;
  192. { close }
  193. current_ppu^.close;
  194. dispose(current_ppu,done);
  195. end;
  196. {*****************************************************************************
  197. PPU Reading
  198. *****************************************************************************}
  199. function readbyte:byte;
  200. begin
  201. readbyte:=current_ppu^.getbyte;
  202. if current_ppu^.error then
  203. Message(unit_f_ppu_read_error);
  204. end;
  205. function readword:word;
  206. begin
  207. readword:=current_ppu^.getword;
  208. if current_ppu^.error then
  209. Message(unit_f_ppu_read_error);
  210. end;
  211. function readlong:longint;
  212. begin
  213. readlong:=current_ppu^.getlongint;
  214. if current_ppu^.error then
  215. Message(unit_f_ppu_read_error);
  216. end;
  217. function readreal : bestreal;
  218. begin
  219. readreal:=current_ppu^.getreal;
  220. if current_ppu^.error then
  221. Message(unit_f_ppu_read_error);
  222. end;
  223. function readstring : string;
  224. begin
  225. readstring:=current_ppu^.getstring;
  226. if current_ppu^.error then
  227. Message(unit_f_ppu_read_error);
  228. end;
  229. procedure readnormalset(var s); {You cannot pass an array [0..31] of byte.}
  230. begin
  231. current_ppu^.getdata(s,sizeof(tnormalset));
  232. if current_ppu^.error then
  233. Message(unit_f_ppu_read_error);
  234. end;
  235. procedure readcontainer(var p:tstringcontainer);
  236. begin
  237. while not current_ppu^.endofentry do
  238. p.insert(current_ppu^.getstring);
  239. end;
  240. procedure readposinfo(var p:tfileposinfo);
  241. begin
  242. p.fileindex:=current_ppu^.getword;
  243. p.line:=current_ppu^.getlongint;
  244. p.column:=current_ppu^.getword;
  245. end;
  246. function readdefref : pdef;
  247. var
  248. hd : pdef;
  249. begin
  250. longint(hd):=current_ppu^.getword;
  251. longint(hd):=longint(hd) or (longint(current_ppu^.getword) shl 16);
  252. readdefref:=hd;
  253. end;
  254. {$ifdef UseBrowser}
  255. function readsymref : psym;
  256. var
  257. hd : psym;
  258. begin
  259. longint(hd):=current_ppu^.getword;
  260. longint(hd):=longint(hd) or (longint(current_ppu^.getword) shl 16);
  261. readsymref:=hd;
  262. end;
  263. {$endif}
  264. procedure readsourcefiles;
  265. var
  266. temp,hs : string;
  267. incfile_found : boolean;
  268. ppufiletime,
  269. source_time : longint;
  270. {$ifdef UseBrowser}
  271. hp : pinputfile;
  272. {$endif UseBrowser}
  273. begin
  274. ppufiletime:=getnamedfiletime(current_module^.ppufilename^);
  275. current_module^.sources_avail:=true;
  276. while not current_ppu^.endofentry do
  277. begin
  278. hs:=current_ppu^.getstring;
  279. temp:='';
  280. if (current_module^.flags and uf_in_library)<>0 then
  281. begin
  282. current_module^.sources_avail:=false;
  283. temp:=' library';
  284. end
  285. else if pos('Macro ',hs)=1 then
  286. begin
  287. { we don't want to find this file }
  288. { but there is a problem with file indexing !! }
  289. temp:='';
  290. end
  291. else
  292. begin
  293. { check the date of the source files }
  294. Source_Time:=GetNamedFileTime(current_module^.path^+hs);
  295. { search for include files in the includepathlist, this
  296. can't be done, becuase a .inc file with the same name as
  297. used by a unit will cause the unit to recompile which is
  298. not the intention (PFV) }
  299. { OK but then only the last filename
  300. should not be searched in include files (PM)}
  301. if (Source_Time=-1) and not current_ppu^.endofentry then
  302. begin
  303. temp:=search(hs,includesearchpath,incfile_found);
  304. if incfile_found then
  305. begin
  306. hs:=temp+hs;
  307. Source_Time:=GetNamedFileTime(hs);
  308. end;
  309. end
  310. else
  311. hs:=current_module^.path^+hs;
  312. if Source_Time=-1 then
  313. begin
  314. current_module^.sources_avail:=false;
  315. temp:=' not found';
  316. end
  317. else
  318. begin
  319. temp:=' time '+filetimestring(source_time);
  320. if (source_time>ppufiletime) then
  321. begin
  322. current_module^.do_compile:=true;
  323. temp:=temp+' *'
  324. end;
  325. end;
  326. {$ifdef UseBrowser}
  327. new(hp,init(hs));
  328. { the indexing is wrong here PM }
  329. current_module^.sourcefiles^.register_file(hp);
  330. {$endif UseBrowser}
  331. end;
  332. Message1(unit_u_ppu_source,hs+temp);
  333. end;
  334. { main source is always the last }
  335. stringdispose(current_module^.mainsource);
  336. current_module^.mainsource:=stringdup(hs);
  337. { the indexing is corrected here PM }
  338. current_module^.sourcefiles^.inverse_register_indexes;
  339. { check if we want to rebuild every unit, only if the sources are
  340. available }
  341. if do_build and current_module^.sources_avail then
  342. current_module^.do_compile:=true;
  343. end;
  344. procedure readloadunit;
  345. var
  346. hs : string;
  347. checksum : longint;
  348. in_interface : boolean;
  349. begin
  350. while not current_ppu^.endofentry do
  351. begin
  352. hs:=current_ppu^.getstring;
  353. checksum:=current_ppu^.getlongint;
  354. in_interface:=(current_ppu^.getbyte<>0);
  355. current_module^.used_units.concat(new(pused_unit,init_to_load(hs,checksum,in_interface)));
  356. end;
  357. end;
  358. procedure load_interface;
  359. var
  360. b : byte;
  361. begin
  362. { read interface part }
  363. repeat
  364. b:=current_ppu^.readentry;
  365. case b of
  366. { ibinitunit : usedunits^.insert(readstring); }
  367. ibmodulename : begin
  368. stringdispose(current_module^.modulename);
  369. current_module^.modulename:=stringdup(current_ppu^.getstring);
  370. end;
  371. ibsourcefiles : readsourcefiles;
  372. ibloadunit_int : readloadunit;
  373. iblinksharedlibs : readcontainer(current_module^.LinkSharedLibs);
  374. iblinkstaticlibs : readcontainer(current_module^.LinkStaticLibs);
  375. iblinkofiles : readcontainer(current_module^.LinkOFiles);
  376. ibendinterface : break;
  377. else
  378. Message1(unit_f_ppu_invalid_entry,tostr(b));
  379. end;
  380. until false;
  381. end;
  382. {
  383. $Log$
  384. Revision 1.22 1998-10-14 13:38:24 peter
  385. * fixed path with staticlib/objects in ppufiles
  386. Revision 1.21 1998/10/14 10:45:10 pierre
  387. * ppu problems for m68k fixed (at least in cross compiling)
  388. * one last memory leak for sysamiga fixed
  389. * the amiga RTL compiles now completely !!
  390. Revision 1.20 1998/10/13 13:10:30 peter
  391. * new style for m68k/i386 infos and enums
  392. Revision 1.19 1998/10/08 23:29:07 peter
  393. * -vu shows unit info, -vt shows tried/used files
  394. Revision 1.18 1998/09/28 16:57:27 pierre
  395. * changed all length(p^.value_str^) into str_length(p)
  396. to get it work with and without ansistrings
  397. * changed sourcefiles field of tmodule to a pointer
  398. Revision 1.17 1998/09/22 17:13:53 pierre
  399. + browsing updated and developed
  400. records and objects fields are also stored
  401. Revision 1.16 1998/09/22 15:40:56 peter
  402. * some extra ifdef GDB
  403. Revision 1.15 1998/09/21 08:45:23 pierre
  404. + added vmt_offset in tobjectdef.write for fututre use
  405. (first steps to have objects without vmt if no virtual !!)
  406. + added fpu_used field for tabstractprocdef :
  407. sets this level to 2 if the functions return with value in FPU
  408. (is then set to correct value at parsing of implementation)
  409. THIS MIGHT refuse some code with FPU expression too complex
  410. that were accepted before and even in some cases
  411. that don't overflow in fact
  412. ( like if f : float; is a forward that finally in implementation
  413. only uses one fpu register !!)
  414. Nevertheless I think that it will improve security on
  415. FPU operations !!
  416. * most other changes only for UseBrowser code
  417. (added symtable references for record and objects)
  418. local switch for refs to args and local of each function
  419. (static symtable still missing)
  420. UseBrowser still not stable and probably broken by
  421. the definition hash array !!
  422. Revision 1.14 1998/09/01 07:54:24 pierre
  423. * UseBrowser a little updated (might still be buggy !!)
  424. * bug in psub.pas in function specifier removed
  425. * stdcall allowed in interface and in implementation
  426. (FPC will not yet complain if it is missing in either part
  427. because stdcall is only a dummy !!)
  428. Revision 1.13 1998/08/17 10:10:11 peter
  429. - removed OLDPPU
  430. Revision 1.12 1998/08/17 09:17:53 peter
  431. * static/shared linking updates
  432. Revision 1.11 1998/08/16 20:32:49 peter
  433. * crcs of used units are not important for the current crc, reduces the
  434. amount of recompiles
  435. Revision 1.10 1998/08/13 10:57:30 peter
  436. * constant sets are now written correctly to the ppufile
  437. Revision 1.9 1998/08/11 15:31:41 peter
  438. * write extended to ppu file
  439. * new version 0.99.7
  440. Revision 1.8 1998/08/10 14:50:29 peter
  441. + localswitches, moduleswitches, globalswitches splitting
  442. Revision 1.7 1998/07/14 14:47:07 peter
  443. * released NEWINPUT
  444. Revision 1.6 1998/07/07 11:20:14 peter
  445. + NEWINPUT for a better inputfile and scanner object
  446. Revision 1.5 1998/06/24 14:48:39 peter
  447. * ifdef newppu -> ifndef oldppu
  448. Revision 1.4 1998/06/16 08:56:32 peter
  449. + targetcpu
  450. * cleaner pmodules for newppu
  451. Revision 1.3 1998/06/13 00:10:17 peter
  452. * working browser and newppu
  453. * some small fixes against crashes which occured in bp7 (but not in
  454. fpc?!)
  455. Revision 1.2 1998/05/28 14:40:28 peter
  456. * fixes for newppu, remake3 works now with it
  457. Revision 1.1 1998/05/27 19:45:09 peter
  458. * symtable.pas splitted into includefiles
  459. * symtable adapted for $ifdef NEWPPU
  460. }