fmodule.pas 29 KB

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