fmodule.pas 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl
  4. This unit implements the first loading and searching of the modules
  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 fmodule;
  19. {$i defines.inc}
  20. {$ifdef go32v1}
  21. {$define SHORTASMprefix}
  22. {$endif}
  23. {$ifdef go32v2}
  24. {$define SHORTASMprefix}
  25. {$endif}
  26. {$ifdef OS2}
  27. { Allthough OS/2 supports long filenames I play it safe and
  28. use 8.3 filenames, because this allows the compiler to run
  29. on a FAT partition. (DM) }
  30. {$define SHORTASMprefix}
  31. {$endif}
  32. interface
  33. uses
  34. cutils,cclasses,
  35. globals,ppu,finput,
  36. symbase;
  37. const
  38. maxunits = 1024;
  39. type
  40. trecompile_reason = (rr_unknown,
  41. rr_noppu,rr_sourcenewer,rr_build,rr_crcchanged
  42. );
  43. TExternalsItem=class(TLinkedListItem)
  44. public
  45. found : longbool;
  46. data : pstring;
  47. constructor Create(const s:string);
  48. Destructor Destroy;override;
  49. end;
  50. tlinkcontaineritem=class(tlinkedlistitem)
  51. public
  52. data : pstring;
  53. needlink : cardinal;
  54. constructor Create(const s:string;m:cardinal);
  55. destructor Destroy;override;
  56. end;
  57. tlinkcontainer=class(tlinkedlist)
  58. procedure add(const s : string;m:cardinal);
  59. function get(var m:cardinal) : string;
  60. function getusemask(mask:cardinal) : string;
  61. function find(const s:string):boolean;
  62. end;
  63. {$ifndef NEWMAP}
  64. tunitmap = array[0..maxunits-1] of pointer;
  65. punitmap = ^tunitmap;
  66. {$else NEWMAP}
  67. tunitmap = array[0..maxunits-1] of tmodule;
  68. punitmap = ^tunitmap;
  69. {$endif NEWMAP}
  70. tmodule = class(tmodulebase)
  71. ppufile : pppufile; { the PPU file }
  72. crc,
  73. interface_crc,
  74. flags : longint; { the PPU flags }
  75. compiled, { unit is already compiled }
  76. do_reload, { force reloading of the unit }
  77. do_compile, { need to compile the sources }
  78. sources_avail, { if all sources are reachable }
  79. sources_checked, { if there is already done a check for the sources }
  80. is_unit,
  81. in_compile, { is it being compiled ?? }
  82. in_second_compile, { is this unit being compiled for the 2nd time? }
  83. in_second_load, { is this unit PPU loaded a 2nd time? }
  84. in_implementation, { processing the implementation part? }
  85. in_global : boolean; { allow global settings }
  86. recompile_reason : trecompile_reason; { the reason why the unit should be recompiled }
  87. islibrary : boolean; { if it is a library (win32 dll) }
  88. map : punitmap; { mapping of all used units }
  89. unitcount : longint; { local unit counter }
  90. globalsymtable, { pointer to the global symtable of this unit }
  91. localsymtable : tsymtable;{ pointer to the local symtable of this unit }
  92. scanner : pointer; { scanner object used }
  93. loaded_from : tmodule;
  94. uses_imports : boolean; { Set if the module imports from DLL's.}
  95. imports : tlinkedlist;
  96. _exports : tlinkedlist;
  97. externals : tlinkedlist; {Only for DLL scanners by using Unix-style $LINKLIB }
  98. resourcefiles : tstringlist;
  99. linkunitofiles,
  100. linkunitstaticlibs,
  101. linkunitsharedlibs,
  102. linkotherofiles, { objects,libs loaded from the source }
  103. linkothersharedlibs, { using $L or $LINKLIB or import lib (for linux) }
  104. linkotherstaticlibs : tlinkcontainer;
  105. used_units : tlinkedlist;
  106. dependent_units : tlinkedlist;
  107. localunitsearchpath, { local searchpaths }
  108. localobjectsearchpath,
  109. localincludesearchpath,
  110. locallibrarysearchpath : TSearchPathList;
  111. asmprefix : pstring; { prefix for the smartlink asmfiles }
  112. {$ifdef Test_Double_checksum}
  113. crc_array : pointer;
  114. crc_size : longint;
  115. crc_array2 : pointer;
  116. crc_size2 : longint;
  117. {$endif def Test_Double_checksum}
  118. constructor create(const s:string;_is_unit:boolean);
  119. destructor destroy;override;
  120. procedure reset;
  121. procedure setfilename(const fn:string;allowoutput:boolean);
  122. function openppu:boolean;
  123. function search_unit(const n : string;onlysource:boolean):boolean;
  124. end;
  125. tused_unit = class(tlinkedlistitem)
  126. unitid : longint;
  127. name : pstring;
  128. checksum,
  129. interface_checksum : longint;
  130. loaded : boolean;
  131. in_uses,
  132. in_interface,
  133. is_stab_written : boolean;
  134. u : tmodule;
  135. constructor create(_u : tmodule;intface:boolean);
  136. constructor create_to_load(const n:string;c,intfc:longint;intface:boolean);
  137. destructor destroy;override;
  138. end;
  139. tdependent_unit = class(tlinkedlistitem)
  140. u : tmodule;
  141. constructor create(_u : tmodule);
  142. end;
  143. var
  144. main_module : tmodule; { Main module of the program }
  145. current_module : tmodule; { Current module which is compiled or loaded }
  146. compiled_module : tmodule; { Current module which is compiled }
  147. usedunits : tlinkedlist; { Used units for this program }
  148. loaded_units : tlinkedlist; { All loaded units }
  149. SmartLinkOFiles : TStringList; { List of .o files which are generated,
  150. used to delete them after linking }
  151. function get_source_file(moduleindex,fileindex : longint) : tinputfile;
  152. implementation
  153. uses
  154. {$ifdef delphi}
  155. dmisc,
  156. {$else}
  157. dos,
  158. {$endif}
  159. globtype,verbose,systems,
  160. scanner;
  161. {*****************************************************************************
  162. Global Functions
  163. *****************************************************************************}
  164. function get_source_file(moduleindex,fileindex : longint) : tinputfile;
  165. var
  166. hp : tmodule;
  167. begin
  168. hp:=tmodule(loaded_units.first);
  169. while assigned(hp) and (hp.unit_index<>moduleindex) do
  170. hp:=tmodule(hp.next);
  171. if assigned(hp) then
  172. get_source_file:=hp.sourcefiles.get_file(fileindex)
  173. else
  174. get_source_file:=nil;
  175. end;
  176. {****************************************************************************
  177. TLinkContainerItem
  178. ****************************************************************************}
  179. constructor TLinkContainerItem.Create(const s:string;m:cardinal);
  180. begin
  181. inherited Create;
  182. data:=stringdup(s);
  183. needlink:=m;
  184. end;
  185. destructor TLinkContainerItem.Destroy;
  186. begin
  187. stringdispose(data);
  188. end;
  189. {****************************************************************************
  190. TLinkContainer
  191. ****************************************************************************}
  192. procedure TLinkContainer.add(const s : string;m:cardinal);
  193. begin
  194. inherited concat(TLinkContainerItem.Create(s,m));
  195. end;
  196. function TLinkContainer.get(var m:cardinal) : string;
  197. var
  198. p : tlinkcontaineritem;
  199. begin
  200. p:=tlinkcontaineritem(inherited getfirst);
  201. if p=nil then
  202. begin
  203. get:='';
  204. m:=0;
  205. end
  206. else
  207. begin
  208. get:=p.data^;
  209. m:=p.needlink;
  210. p.free;
  211. end;
  212. end;
  213. function TLinkContainer.getusemask(mask:cardinal) : string;
  214. var
  215. p : tlinkcontaineritem;
  216. found : boolean;
  217. begin
  218. found:=false;
  219. repeat
  220. p:=tlinkcontaineritem(inherited getfirst);
  221. if p=nil then
  222. begin
  223. getusemask:='';
  224. exit;
  225. end;
  226. getusemask:=p.data^;
  227. found:=(p.needlink and mask)<>0;
  228. p.free;
  229. until found;
  230. end;
  231. function TLinkContainer.find(const s:string):boolean;
  232. var
  233. newnode : tlinkcontaineritem;
  234. begin
  235. find:=false;
  236. newnode:=tlinkcontaineritem(First);
  237. while assigned(newnode) do
  238. begin
  239. if newnode.data^=s then
  240. begin
  241. find:=true;
  242. exit;
  243. end;
  244. newnode:=tlinkcontaineritem(newnode.next);
  245. end;
  246. end;
  247. {****************************************************************************
  248. TExternalsItem
  249. ****************************************************************************}
  250. constructor tExternalsItem.Create(const s:string);
  251. begin
  252. inherited Create;
  253. found:=false;
  254. data:=stringdup(s);
  255. end;
  256. destructor tExternalsItem.Destroy;
  257. begin
  258. stringdispose(data);
  259. inherited;
  260. end;
  261. {****************************************************************************
  262. TMODULE
  263. ****************************************************************************}
  264. procedure tmodule.setfilename(const fn:string;allowoutput:boolean);
  265. var
  266. p : dirstr;
  267. n : NameStr;
  268. e : ExtStr;
  269. begin
  270. stringdispose(objfilename);
  271. stringdispose(asmfilename);
  272. stringdispose(ppufilename);
  273. stringdispose(staticlibfilename);
  274. stringdispose(sharedlibfilename);
  275. stringdispose(exefilename);
  276. stringdispose(outputpath);
  277. stringdispose(path);
  278. { Create names }
  279. fsplit(fn,p,n,e);
  280. n:=FixFileName(n);
  281. { set path }
  282. path:=stringdup(FixPath(p,false));
  283. { obj,asm,ppu names }
  284. p:=path^;
  285. if AllowOutput then
  286. begin
  287. if (OutputUnitDir<>'') then
  288. p:=OutputUnitDir
  289. else
  290. if (OutputExeDir<>'') then
  291. p:=OutputExeDir;
  292. end;
  293. outputpath:=stringdup(p);
  294. objfilename:=stringdup(p+n+target_info.objext);
  295. asmfilename:=stringdup(p+n+target_info.asmext);
  296. ppufilename:=stringdup(p+n+target_info.unitext);
  297. { lib and exe could be loaded with a file specified with -o }
  298. if AllowOutput and (OutputFile<>'') and (compile_level=1) then
  299. n:=OutputFile;
  300. staticlibfilename:=stringdup(p+target_info.libprefix+n+target_info.staticlibext);
  301. if target_info.target=target_i386_WIN32 then
  302. sharedlibfilename:=stringdup(p+n+target_info.sharedlibext)
  303. else
  304. sharedlibfilename:=stringdup(p+target_info.libprefix+n+target_info.sharedlibext);
  305. { output dir of exe can be specified separatly }
  306. if AllowOutput and (OutputExeDir<>'') then
  307. p:=OutputExeDir
  308. else
  309. p:=path^;
  310. exefilename:=stringdup(p+n+target_info.exeext);
  311. end;
  312. function tmodule.openppu:boolean;
  313. var
  314. ppufiletime : longint;
  315. begin
  316. openppu:=false;
  317. Message1(unit_t_ppu_loading,ppufilename^);
  318. { Get ppufile time (also check if the file exists) }
  319. ppufiletime:=getnamedfiletime(ppufilename^);
  320. if ppufiletime=-1 then
  321. exit;
  322. { Open the ppufile }
  323. Message1(unit_u_ppu_name,ppufilename^);
  324. ppufile:=new(pppufile,init(ppufilename^));
  325. ppufile^.change_endian:=source_info.endian<>target_info.endian;
  326. if not ppufile^.open then
  327. begin
  328. dispose(ppufile,done);
  329. Message(unit_u_ppu_file_too_short);
  330. exit;
  331. end;
  332. { check for a valid PPU file }
  333. if not ppufile^.CheckPPUId then
  334. begin
  335. dispose(ppufile,done);
  336. Message(unit_u_ppu_invalid_header);
  337. exit;
  338. end;
  339. { check for allowed PPU versions }
  340. if not (ppufile^.GetPPUVersion = CurrentPPUVersion) then
  341. begin
  342. dispose(ppufile,done);
  343. Message1(unit_u_ppu_invalid_version,tostr(ppufile^.GetPPUVersion));
  344. exit;
  345. end;
  346. { check the target processor }
  347. if ttargetcpu(ppufile^.header.cpu)<>target_cpu then
  348. begin
  349. dispose(ppufile,done);
  350. Message(unit_u_ppu_invalid_processor);
  351. exit;
  352. end;
  353. { check target }
  354. if ttarget(ppufile^.header.target)<>target_info.target then
  355. begin
  356. dispose(ppufile,done);
  357. Message(unit_u_ppu_invalid_target);
  358. exit;
  359. end;
  360. { Load values to be access easier }
  361. flags:=ppufile^.header.flags;
  362. crc:=ppufile^.header.checksum;
  363. interface_crc:=ppufile^.header.interface_checksum;
  364. { Show Debug info }
  365. Message1(unit_u_ppu_time,filetimestring(ppufiletime));
  366. Message1(unit_u_ppu_flags,tostr(flags));
  367. Message1(unit_u_ppu_crc,tostr(ppufile^.header.checksum));
  368. Message1(unit_u_ppu_crc,tostr(ppufile^.header.interface_checksum)+' (intfc)');
  369. do_compile:=false;
  370. openppu:=true;
  371. end;
  372. function tmodule.search_unit(const n : string;onlysource:boolean):boolean;
  373. var
  374. singlepathstring,
  375. filename : string;
  376. Function UnitExists(const ext:string;var foundfile:string):boolean;
  377. begin
  378. Message1(unit_t_unitsearch,Singlepathstring+filename+ext);
  379. UnitExists:=FindFile(FileName+ext,Singlepathstring,foundfile);
  380. end;
  381. Function PPUSearchPath(const s:string):boolean;
  382. var
  383. found : boolean;
  384. hs : string;
  385. begin
  386. Found:=false;
  387. singlepathstring:=FixPath(s,false);
  388. { Check for PPU file }
  389. Found:=UnitExists(target_info.unitext,hs);
  390. if Found then
  391. Begin
  392. SetFileName(hs,false);
  393. Found:=OpenPPU;
  394. End;
  395. PPUSearchPath:=Found;
  396. end;
  397. Function SourceSearchPath(const s:string):boolean;
  398. var
  399. found : boolean;
  400. hs : string;
  401. begin
  402. Found:=false;
  403. singlepathstring:=FixPath(s,false);
  404. { Check for Sources }
  405. ppufile:=nil;
  406. do_compile:=true;
  407. recompile_reason:=rr_noppu;
  408. {Check for .pp file}
  409. Found:=UnitExists(target_info.sourceext,hs);
  410. if not Found then
  411. begin
  412. { Check for .pas }
  413. Found:=UnitExists(target_info.pasext,hs);
  414. end;
  415. stringdispose(mainsource);
  416. if Found then
  417. begin
  418. sources_avail:=true;
  419. { Load Filenames when found }
  420. mainsource:=StringDup(hs);
  421. SetFileName(hs,false);
  422. end
  423. else
  424. sources_avail:=false;
  425. SourceSearchPath:=Found;
  426. end;
  427. Function SearchPath(const s:string):boolean;
  428. var
  429. found : boolean;
  430. begin
  431. { First check for a ppu, then for the source }
  432. found:=false;
  433. if not onlysource then
  434. found:=PPUSearchPath(s);
  435. if not found then
  436. found:=SourceSearchPath(s);
  437. SearchPath:=found;
  438. end;
  439. Function SearchPathList(list:TSearchPathList):boolean;
  440. var
  441. hp : TStringListItem;
  442. found : boolean;
  443. begin
  444. found:=false;
  445. hp:=TStringListItem(list.First);
  446. while assigned(hp) do
  447. begin
  448. found:=SearchPath(hp.Str);
  449. if found then
  450. break;
  451. hp:=TStringListItem(hp.next);
  452. end;
  453. SearchPathList:=found;
  454. end;
  455. var
  456. fnd : boolean;
  457. begin
  458. filename:=FixFileName(n);
  459. { try to find unit
  460. 1. look for ppu in cwd
  461. 2. look for ppu in outputpath if set, this is tp7 compatible (PFV)
  462. 3. look for source in cwd
  463. 4. local unit pathlist
  464. 5. global unit pathlist }
  465. fnd:=false;
  466. if not onlysource then
  467. begin
  468. fnd:=PPUSearchPath('.');
  469. if (not fnd) and (current_module.outputpath^<>'') then
  470. fnd:=PPUSearchPath(current_module.outputpath^);
  471. end;
  472. if (not fnd) then
  473. fnd:=SourceSearchPath('.');
  474. if (not fnd) then
  475. fnd:=SearchPathList(current_module.LocalUnitSearchPath);
  476. if (not fnd) then
  477. fnd:=SearchPathList(UnitSearchPath);
  478. { try to find a file with the first 8 chars of the modulename, like
  479. dos }
  480. if (not fnd) and (length(filename)>8) then
  481. begin
  482. filename:=copy(filename,1,8);
  483. fnd:=SearchPath('.');
  484. if (not fnd) then
  485. fnd:=SearchPathList(current_module.LocalUnitSearchPath);
  486. if not fnd then
  487. fnd:=SearchPathList(UnitSearchPath);
  488. end;
  489. search_unit:=fnd;
  490. end;
  491. procedure tmodule.reset;
  492. var
  493. pm : tdependent_unit;
  494. begin
  495. if assigned(scanner) then
  496. tscannerfile(scanner).invalid:=true;
  497. if assigned(globalsymtable) then
  498. begin
  499. globalsymtable.free;
  500. globalsymtable:=nil;
  501. end;
  502. if assigned(localsymtable) then
  503. begin
  504. localsymtable.free;
  505. localsymtable:=nil;
  506. end;
  507. if assigned(map) then
  508. begin
  509. dispose(map);
  510. map:=nil;
  511. end;
  512. if assigned(ppufile) then
  513. begin
  514. dispose(ppufile,done);
  515. ppufile:=nil;
  516. end;
  517. sourcefiles.free;
  518. sourcefiles:=tinputfilemanager.create;
  519. imports.free;
  520. imports:=tlinkedlist.create;
  521. _exports.free;
  522. _exports:=tlinkedlist.create;
  523. externals.free;
  524. externals:=tlinkedlist.create;
  525. used_units.free;
  526. used_units:=TLinkedList.Create;
  527. { all units that depend on this one must be recompiled ! }
  528. pm:=tdependent_unit(dependent_units.first);
  529. while assigned(pm) do
  530. begin
  531. if pm.u.in_second_compile then
  532. Comment(v_debug,'No reload already in second compile: '+pm.u.modulename^)
  533. else
  534. begin
  535. pm.u.do_reload:=true;
  536. Comment(v_debug,'Reloading '+pm.u.modulename^+' needed because '+modulename^+' is reloaded');
  537. end;
  538. pm:=tdependent_unit(pm.next);
  539. end;
  540. dependent_units.free;
  541. dependent_units:=TLinkedList.Create;
  542. resourcefiles.Free;
  543. resourcefiles:=TStringList.Create;
  544. linkunitofiles.Free;
  545. linkunitofiles:=TLinkContainer.Create;
  546. linkunitstaticlibs.Free;
  547. linkunitstaticlibs:=TLinkContainer.Create;
  548. linkunitsharedlibs.Free;
  549. linkunitsharedlibs:=TLinkContainer.Create;
  550. linkotherofiles.Free;
  551. linkotherofiles:=TLinkContainer.Create;
  552. linkotherstaticlibs.Free;
  553. linkotherstaticlibs:=TLinkContainer.Create;
  554. linkothersharedlibs.Free;
  555. linkothersharedlibs:=TLinkContainer.Create;
  556. uses_imports:=false;
  557. do_compile:=false;
  558. { sources_avail:=true;
  559. should not be changed PM }
  560. compiled:=false;
  561. in_implementation:=false;
  562. in_global:=true;
  563. {loaded_from:=nil;
  564. should not be changed PFV }
  565. flags:=0;
  566. crc:=0;
  567. interface_crc:=0;
  568. unitcount:=1;
  569. recompile_reason:=rr_unknown;
  570. end;
  571. constructor tmodule.create(const s:string;_is_unit:boolean);
  572. var
  573. p : dirstr;
  574. n : namestr;
  575. e : extstr;
  576. begin
  577. FSplit(s,p,n,e);
  578. { Programs have the name 'Program' to don't conflict with dup id's }
  579. if _is_unit then
  580. inherited create(n)
  581. else
  582. inherited create('Program');
  583. mainsource:=stringdup(s);
  584. { Dos has the famous 8.3 limit :( }
  585. {$ifdef SHORTASMprefix}
  586. asmprefix:=stringdup(FixFileName('as'));
  587. {$else}
  588. asmprefix:=stringdup(FixFileName(n));
  589. {$endif}
  590. setfilename(p+n,true);
  591. localunitsearchpath:=TSearchPathList.Create;
  592. localobjectsearchpath:=TSearchPathList.Create;
  593. localincludesearchpath:=TSearchPathList.Create;
  594. locallibrarysearchpath:=TSearchPathList.Create;
  595. used_units:=TLinkedList.Create;
  596. dependent_units:=TLinkedList.Create;
  597. resourcefiles:=TStringList.Create;
  598. linkunitofiles:=TLinkContainer.Create;
  599. linkunitstaticlibs:=TLinkContainer.Create;
  600. linkunitsharedlibs:=TLinkContainer.Create;
  601. linkotherofiles:=TLinkContainer.Create;
  602. linkotherstaticlibs:=TLinkContainer.Create;
  603. linkothersharedlibs:=TLinkContainer.Create;
  604. ppufile:=nil;
  605. scanner:=nil;
  606. map:=nil;
  607. globalsymtable:=nil;
  608. localsymtable:=nil;
  609. loaded_from:=nil;
  610. flags:=0;
  611. crc:=0;
  612. interface_crc:=0;
  613. do_reload:=false;
  614. unitcount:=1;
  615. do_compile:=false;
  616. sources_avail:=true;
  617. sources_checked:=false;
  618. compiled:=false;
  619. recompile_reason:=rr_unknown;
  620. in_second_load:=false;
  621. in_compile:=false;
  622. in_second_compile:=false;
  623. in_implementation:=false;
  624. in_global:=true;
  625. is_unit:=_is_unit;
  626. islibrary:=false;
  627. uses_imports:=false;
  628. imports:=TLinkedList.Create;
  629. _exports:=TLinkedList.Create;
  630. externals:=TLinkedList.Create;
  631. { search the PPU file if it is an unit }
  632. if is_unit then
  633. begin
  634. { use the realmodulename so we can also find a case sensitive
  635. source filename }
  636. search_unit(realmodulename^,false);
  637. { it the sources_available is changed then we know that
  638. the sources aren't available }
  639. if not sources_avail then
  640. sources_checked:=true;
  641. end;
  642. end;
  643. destructor tmodule.Destroy;
  644. {$ifdef MEMDEBUG}
  645. var
  646. d : tmemdebug;
  647. {$endif}
  648. begin
  649. if assigned(map) then
  650. dispose(map);
  651. if assigned(ppufile) then
  652. dispose(ppufile,done);
  653. ppufile:=nil;
  654. if assigned(imports) then
  655. imports.free;
  656. imports:=nil;
  657. if assigned(_exports) then
  658. _exports.free;
  659. _exports:=nil;
  660. if assigned(externals) then
  661. externals.free;
  662. externals:=nil;
  663. if assigned(scanner) then
  664. tscannerfile(scanner).invalid:=true;
  665. used_units.free;
  666. dependent_units.free;
  667. resourcefiles.Free;
  668. linkunitofiles.Free;
  669. linkunitstaticlibs.Free;
  670. linkunitsharedlibs.Free;
  671. linkotherofiles.Free;
  672. linkotherstaticlibs.Free;
  673. linkothersharedlibs.Free;
  674. stringdispose(objfilename);
  675. stringdispose(asmfilename);
  676. stringdispose(ppufilename);
  677. stringdispose(staticlibfilename);
  678. stringdispose(sharedlibfilename);
  679. stringdispose(exefilename);
  680. stringdispose(outputpath);
  681. stringdispose(path);
  682. stringdispose(modulename);
  683. stringdispose(realmodulename);
  684. stringdispose(mainsource);
  685. stringdispose(asmprefix);
  686. localunitsearchpath.Free;
  687. localobjectsearchpath.free;
  688. localincludesearchpath.free;
  689. locallibrarysearchpath.free;
  690. {$ifdef MEMDEBUG}
  691. d.init('symtable');
  692. {$endif}
  693. if assigned(globalsymtable) then
  694. globalsymtable.free;
  695. globalsymtable:=nil;
  696. if assigned(localsymtable) then
  697. localsymtable.free;
  698. localsymtable:=nil;
  699. {$ifdef MEMDEBUG}
  700. d.free;
  701. {$endif}
  702. inherited Destroy;
  703. end;
  704. {****************************************************************************
  705. TUSED_UNIT
  706. ****************************************************************************}
  707. constructor tused_unit.create(_u : tmodule;intface:boolean);
  708. begin
  709. u:=_u;
  710. in_interface:=intface;
  711. in_uses:=false;
  712. is_stab_written:=false;
  713. loaded:=true;
  714. name:=stringdup(_u.modulename^);
  715. checksum:=_u.crc;
  716. interface_checksum:=_u.interface_crc;
  717. unitid:=0;
  718. end;
  719. constructor tused_unit.create_to_load(const n:string;c,intfc:longint;intface:boolean);
  720. begin
  721. u:=nil;
  722. in_interface:=intface;
  723. in_uses:=false;
  724. is_stab_written:=false;
  725. loaded:=false;
  726. name:=stringdup(n);
  727. checksum:=c;
  728. interface_checksum:=intfc;
  729. unitid:=0;
  730. end;
  731. destructor tused_unit.destroy;
  732. begin
  733. stringdispose(name);
  734. inherited destroy;
  735. end;
  736. {****************************************************************************
  737. TDENPENDENT_UNIT
  738. ****************************************************************************}
  739. constructor tdependent_unit.create(_u : tmodule);
  740. begin
  741. u:=_u;
  742. end;
  743. end.
  744. {
  745. $Log$
  746. Revision 1.13 2001-04-18 22:01:53 peter
  747. * registration of targets and assemblers
  748. Revision 1.12 2001/04/13 18:08:37 peter
  749. * scanner object to class
  750. Revision 1.11 2001/04/13 01:22:07 peter
  751. * symtable change to classes
  752. * range check generation and errors fixed, make cycle DEBUG=1 works
  753. * memory leaks fixed
  754. Revision 1.10 2001/04/02 21:20:29 peter
  755. * resulttype rewrite
  756. Revision 1.9 2001/03/13 18:45:06 peter
  757. * fixed some memory leaks
  758. Revision 1.8 2001/03/06 18:28:02 peter
  759. * patch from Pavel with a new and much faster DLL Scanner for
  760. automatic importing so $linklib works for DLLs. Thanks Pavel!
  761. Revision 1.7 2001/02/20 21:41:15 peter
  762. * new fixfilename, findfile for unix. Look first for lowercase, then
  763. NormalCase and last for UPPERCASE names.
  764. Revision 1.6 2000/12/25 00:07:25 peter
  765. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  766. tlinkedlist objects)
  767. Revision 1.5 2000/11/07 20:48:33 peter
  768. * removed ref_count from pinputfile it's not used
  769. Revision 1.4 2000/10/31 22:02:46 peter
  770. * symtable splitted, no real code changes
  771. Revision 1.3 2000/10/15 07:47:51 peter
  772. * unit names and procedure names are stored mixed case
  773. Revision 1.2 2000/09/24 15:06:16 peter
  774. * use defines.inc
  775. Revision 1.1 2000/08/27 16:11:50 peter
  776. * moved some util functions from globals,cobjects to cutils
  777. * splitted files into finput,fmodule
  778. }