fmodule.pas 29 KB

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