fmodule.pas 29 KB

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