files.pas 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl
  4. This unit implements an extended file management and the first loading
  5. and searching of the modules (ppufiles)
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. ****************************************************************************
  18. }
  19. unit files;
  20. {$ifdef TP}
  21. {$V+}
  22. {$endif}
  23. {$ifdef TP}
  24. {$define SHORTASMPREFIX}
  25. {$endif}
  26. {$ifdef go32v1}
  27. {$define SHORTASMPREFIX}
  28. {$endif}
  29. {$ifdef go32v2}
  30. {$define SHORTASMPREFIX}
  31. {$endif}
  32. {$ifdef OS2}
  33. { Allthough OS/2 supports long filenames I play it safe and
  34. use 8.3 filenames, because this allows the compiler to run
  35. on a FAT partition. (DM) }
  36. {$define SHORTASMPREFIX}
  37. {$endif}
  38. interface
  39. uses
  40. globtype,cobjects,globals,ppu
  41. {$IFDEF NEWST},objects{$ENDIF};
  42. const
  43. {$ifdef FPC}
  44. maxunits = 1024;
  45. InputFileBufSize=32*1024;
  46. linebufincrease=512;
  47. {$else}
  48. maxunits = 128;
  49. InputFileBufSize=1024;
  50. linebufincrease=64;
  51. {$endif}
  52. type
  53. trecompile_reason = (rr_unknown,rr_noppu,rr_sourcenewer,
  54. rr_build,rr_libolder,rr_objolder,rr_asmolder,rr_crcchanged);
  55. {$ifdef FPC}
  56. tlongintarr = array[0..1000000] of longint;
  57. {$else}
  58. tlongintarr = array[0..16000] of longint;
  59. {$endif}
  60. plongintarr = ^tlongintarr;
  61. pinputfile = ^tinputfile;
  62. tinputfile = object
  63. path,name : pstring; { path and filename }
  64. next : pinputfile; { next file for reading }
  65. f : file; { current file handle }
  66. is_macro,
  67. endoffile, { still bytes left to read }
  68. closed : boolean; { is the file closed }
  69. buf : pchar; { buffer }
  70. bufstart, { buffer start position in the file }
  71. bufsize, { amount of bytes in the buffer }
  72. maxbufsize : longint; { size in memory for the buffer }
  73. saveinputpointer : pchar; { save fields for scanner variables }
  74. savelastlinepos,
  75. saveline_no : longint;
  76. linebuf : plongintarr; { line buffer to retrieve lines }
  77. maxlinebuf : longint;
  78. ref_count : longint; { to handle the browser refs }
  79. ref_index : longint;
  80. ref_next : pinputfile;
  81. constructor init(const fn:string);
  82. destructor done;
  83. procedure setpos(l:longint);
  84. procedure seekbuf(fpos:longint);
  85. procedure readbuf;
  86. function open:boolean;
  87. procedure close;
  88. procedure tempclose;
  89. function tempopen:boolean;
  90. procedure setmacro(p:pchar;len:longint);
  91. procedure setline(line,linepos:longint);
  92. function getlinestr(l:longint):string;
  93. end;
  94. pfilemanager = ^tfilemanager;
  95. tfilemanager = object
  96. files : pinputfile;
  97. last_ref_index : longint;
  98. cacheindex : longint;
  99. cacheinputfile : pinputfile;
  100. constructor init;
  101. destructor done;
  102. procedure register_file(f : pinputfile);
  103. procedure inverse_register_indexes;
  104. function get_file(l:longint) : pinputfile;
  105. function get_file_name(l :longint):string;
  106. function get_file_path(l :longint):string;
  107. end;
  108. {$IFDEF NEWST}
  109. Plinkitem=^Tlinkitem;
  110. Tlinkitem=object(Tobject)
  111. data : pstring;
  112. needlink : longint;
  113. constructor init(const s:string;m:longint);
  114. destructor done;virtual;
  115. end;
  116. {$ELSE}
  117. plinkcontaineritem=^tlinkcontaineritem;
  118. tlinkcontaineritem=object(tcontaineritem)
  119. data : pstring;
  120. needlink : longint;
  121. constructor init(const s:string;m:longint);
  122. destructor done;virtual;
  123. end;
  124. plinkcontainer=^tlinkcontainer;
  125. tlinkcontainer=object(tcontainer)
  126. constructor Init;
  127. procedure insert(const s : string;m:longint);
  128. function get(var m:longint) : string;
  129. function getusemask(mask:longint) : string;
  130. function find(const s:string):boolean;
  131. end;
  132. {$ENDIF NEWST}
  133. {$ifndef NEWMAP}
  134. tunitmap = array[0..maxunits-1] of pointer;
  135. punitmap = ^tunitmap;
  136. pmodule = ^tmodule;
  137. {$else NEWMAP}
  138. pmodule = ^tmodule;
  139. tunitmap = array[0..maxunits-1] of pmodule;
  140. punitmap = ^tunitmap;
  141. {$endif NEWMAP}
  142. tmodule = object(tlinkedlist_item)
  143. ppufile : pppufile; { the PPU file }
  144. crc,
  145. interface_crc,
  146. flags : longint; { the PPU flags }
  147. compiled, { unit is already compiled }
  148. do_reload, { force reloading of the unit }
  149. do_assemble, { only assemble the object, don't recompile }
  150. do_compile, { need to compile the sources }
  151. sources_avail, { if all sources are reachable }
  152. is_unit,
  153. in_compile, { is it being compiled ?? }
  154. in_second_compile, { is this unit being compiled for the 2nd time? }
  155. in_second_load, { is this unit PPU loaded a 2nd time? }
  156. in_implementation, { processing the implementation part? }
  157. in_global : boolean; { allow global settings }
  158. recompile_reason : trecompile_reason; { the reason why the unit should be recompiled }
  159. islibrary : boolean; { if it is a library (win32 dll) }
  160. map : punitmap; { mapping of all used units }
  161. unitcount : word; { local unit counter }
  162. unit_index : word; { global counter for browser }
  163. globalsymtable, { pointer to the local/static symtable of this unit }
  164. localsymtable : pointer; { pointer to the psymtable of this unit }
  165. scanner : pointer; { scanner object used }
  166. loaded_from : pmodule;
  167. uses_imports : boolean; { Set if the module imports from DLL's.}
  168. imports : plinkedlist;
  169. _exports : plinkedlist;
  170. sourcefiles : pfilemanager;
  171. resourcefiles : tstringcontainer;
  172. {$IFDEF NEWST}
  173. linkunitofiles,
  174. linkunitstaticlibs,
  175. linkunitsharedlibs,
  176. linkotherofiles, { objects,libs loaded from the source }
  177. linkothersharedlibs, { using $L or $LINKLIB or import lib (for linux) }
  178. linkotherstaticlibs : Tcollection;
  179. {$ELSE}
  180. linkunitofiles,
  181. linkunitstaticlibs,
  182. linkunitsharedlibs,
  183. linkotherofiles, { objects,libs loaded from the source }
  184. linkothersharedlibs, { using $L or $LINKLIB or import lib (for linux) }
  185. linkotherstaticlibs : tlinkcontainer;
  186. {$ENDIF NEWST}
  187. used_units : tlinkedlist;
  188. dependent_units : tlinkedlist;
  189. localunitsearchpath, { local searchpaths }
  190. localobjectsearchpath,
  191. localincludesearchpath,
  192. locallibrarysearchpath : TSearchPathList;
  193. path, { path where the module is find/created }
  194. outputpath, { path where the .s / .o / exe are created }
  195. modulename, { name of the module in uppercase }
  196. objfilename, { fullname of the objectfile }
  197. asmfilename, { fullname of the assemblerfile }
  198. ppufilename, { fullname of the ppufile }
  199. staticlibfilename, { fullname of the static libraryfile }
  200. sharedlibfilename, { fullname of the shared libraryfile }
  201. exefilename, { fullname of the exefile }
  202. asmprefix, { prefix for the smartlink asmfiles }
  203. mainsource : pstring; { name of the main sourcefile }
  204. {$ifdef Test_Double_checksum}
  205. crc_array : pointer;
  206. crc_size : longint;
  207. crc_array2 : pointer;
  208. crc_size2 : longint;
  209. {$endif def Test_Double_checksum}
  210. constructor init(const s:string;_is_unit:boolean);
  211. destructor done;virtual;
  212. procedure reset;
  213. procedure setfilename(const fn:string;allowoutput:boolean);
  214. function openppu:boolean;
  215. function search_unit(const n : string;onlysource:boolean):boolean;
  216. end;
  217. pused_unit = ^tused_unit;
  218. tused_unit = object(tlinkedlist_item)
  219. unitid : word;
  220. name : pstring;
  221. checksum,
  222. interface_checksum : longint;
  223. loaded : boolean;
  224. in_uses,
  225. in_interface,
  226. is_stab_written : boolean;
  227. u : pmodule;
  228. constructor init(_u : pmodule;intface:boolean);
  229. constructor init_to_load(const n:string;c,intfc:longint;intface:boolean);
  230. destructor done;virtual;
  231. end;
  232. pdependent_unit = ^tdependent_unit;
  233. tdependent_unit = object(tlinkedlist_item)
  234. u : pmodule;
  235. constructor init(_u : pmodule);
  236. end;
  237. var
  238. main_module : pmodule; { Main module of the program }
  239. current_module : pmodule; { Current module which is compiled or loaded }
  240. compiled_module : pmodule; { Current module which is compiled }
  241. current_ppu : pppufile; { Current ppufile which is read }
  242. global_unit_count : word;
  243. usedunits : tlinkedlist; { Used units for this program }
  244. loaded_units : tlinkedlist; { All loaded units }
  245. SmartLinkOFiles : TStringContainer; { List of .o files which are generated,
  246. used to delete them after linking }
  247. function get_source_file(moduleindex,fileindex : word) : pinputfile;
  248. implementation
  249. uses
  250. {$ifdef Delphi}
  251. dmisc,
  252. {$else Delphi}
  253. dos,
  254. {$endif Delphi}
  255. verbose,systems,
  256. symtable,scanner{$IFDEF NEWST},symtablt{$ENDIF};
  257. {****************************************************************************
  258. TINPUTFILE
  259. ****************************************************************************}
  260. constructor tinputfile.init(const fn:string);
  261. var
  262. p:dirstr;
  263. n:namestr;
  264. e:extstr;
  265. begin
  266. FSplit(fn,p,n,e);
  267. name:=stringdup(n+e);
  268. path:=stringdup(p);
  269. next:=nil;
  270. { file info }
  271. is_macro:=false;
  272. endoffile:=false;
  273. closed:=true;
  274. buf:=nil;
  275. bufstart:=0;
  276. bufsize:=0;
  277. maxbufsize:=InputFileBufSize;
  278. { save fields }
  279. saveinputpointer:=nil;
  280. saveline_no:=0;
  281. savelastlinepos:=0;
  282. { indexing refs }
  283. ref_next:=nil;
  284. ref_count:=0;
  285. ref_index:=0;
  286. { line buffer }
  287. linebuf:=nil;
  288. maxlinebuf:=0;
  289. end;
  290. destructor tinputfile.done;
  291. begin
  292. if not closed then
  293. close;
  294. stringdispose(path);
  295. stringdispose(name);
  296. { free memory }
  297. if assigned(linebuf) then
  298. freemem(linebuf,maxlinebuf shl 2);
  299. end;
  300. procedure tinputfile.setpos(l:longint);
  301. begin
  302. bufstart:=l;
  303. end;
  304. procedure tinputfile.seekbuf(fpos:longint);
  305. begin
  306. if closed then
  307. exit;
  308. seek(f,fpos);
  309. bufstart:=fpos;
  310. bufsize:=0;
  311. end;
  312. procedure tinputfile.readbuf;
  313. {$ifdef TP}
  314. var
  315. w : word;
  316. {$endif}
  317. begin
  318. if is_macro then
  319. endoffile:=true;
  320. if closed then
  321. exit;
  322. inc(bufstart,bufsize);
  323. {$ifdef VER70}
  324. blockread(f,buf^,maxbufsize-1,w);
  325. bufsize:=w;
  326. {$else}
  327. blockread(f,buf^,maxbufsize-1,bufsize);
  328. {$endif}
  329. buf[bufsize]:=#0;
  330. endoffile:=eof(f);
  331. end;
  332. function tinputfile.open:boolean;
  333. var
  334. ofm : byte;
  335. begin
  336. open:=false;
  337. if not closed then
  338. Close;
  339. ofm:=filemode;
  340. filemode:=0;
  341. Assign(f,path^+name^);
  342. {$I-}
  343. reset(f,1);
  344. {$I+}
  345. filemode:=ofm;
  346. if ioresult<>0 then
  347. exit;
  348. { file }
  349. endoffile:=false;
  350. closed:=false;
  351. Getmem(buf,MaxBufsize);
  352. bufstart:=0;
  353. bufsize:=0;
  354. open:=true;
  355. end;
  356. procedure tinputfile.close;
  357. begin
  358. if is_macro then
  359. begin
  360. if assigned(buf) then
  361. Freemem(buf,maxbufsize);
  362. buf:=nil;
  363. {is_macro:=false;
  364. still needed for dispose in scanner PM }
  365. closed:=true;
  366. exit;
  367. end;
  368. if not closed then
  369. begin
  370. {$I-}
  371. system.close(f);
  372. {$I+}
  373. if ioresult<>0 then;
  374. closed:=true;
  375. end;
  376. if assigned(buf) then
  377. begin
  378. Freemem(buf,maxbufsize);
  379. buf:=nil;
  380. end;
  381. bufstart:=0;
  382. end;
  383. procedure tinputfile.tempclose;
  384. begin
  385. if is_macro then
  386. exit;
  387. if not closed then
  388. begin
  389. {$I-}
  390. system.close(f);
  391. {$I+}
  392. if ioresult<>0 then;
  393. Freemem(buf,maxbufsize);
  394. buf:=nil;
  395. closed:=true;
  396. end;
  397. end;
  398. function tinputfile.tempopen:boolean;
  399. var
  400. ofm : byte;
  401. begin
  402. tempopen:=false;
  403. if is_macro then
  404. begin
  405. { seek buffer postion to bufstart }
  406. if bufstart>0 then
  407. begin
  408. move(buf[bufstart],buf[0],bufsize-bufstart+1);
  409. bufstart:=0;
  410. end;
  411. tempopen:=true;
  412. exit;
  413. end;
  414. if not closed then
  415. exit;
  416. ofm:=filemode;
  417. filemode:=0;
  418. Assign(f,path^+name^);
  419. {$I-}
  420. reset(f,1);
  421. {$I+}
  422. filemode:=ofm;
  423. if ioresult<>0 then
  424. exit;
  425. closed:=false;
  426. { get new mem }
  427. Getmem(buf,maxbufsize);
  428. { restore state }
  429. seek(f,BufStart);
  430. bufsize:=0;
  431. readbuf;
  432. tempopen:=true;
  433. end;
  434. procedure tinputfile.setmacro(p:pchar;len:longint);
  435. begin
  436. { create new buffer }
  437. getmem(buf,len+1);
  438. move(p^,buf^,len);
  439. buf[len]:=#0;
  440. { reset }
  441. bufstart:=0;
  442. bufsize:=len;
  443. maxbufsize:=len+1;
  444. is_macro:=true;
  445. endoffile:=true;
  446. closed:=true;
  447. end;
  448. procedure tinputfile.setline(line,linepos:longint);
  449. var
  450. oldlinebuf : plongintarr;
  451. begin
  452. if line<1 then
  453. exit;
  454. while (line>=maxlinebuf) do
  455. begin
  456. oldlinebuf:=linebuf;
  457. { create new linebuf and move old info }
  458. getmem(linebuf,(maxlinebuf+linebufincrease) shl 2);
  459. if assigned(oldlinebuf) then
  460. begin
  461. move(oldlinebuf^,linebuf^,maxlinebuf shl 2);
  462. freemem(oldlinebuf,maxlinebuf shl 2);
  463. end;
  464. fillchar(linebuf^[maxlinebuf],linebufincrease shl 2,0);
  465. inc(maxlinebuf,linebufincrease);
  466. end;
  467. linebuf^[line]:=linepos;
  468. end;
  469. function tinputfile.getlinestr(l:longint):string;
  470. var
  471. c : char;
  472. i,
  473. fpos : longint;
  474. p : pchar;
  475. begin
  476. getlinestr:='';
  477. if l<maxlinebuf then
  478. begin
  479. fpos:=linebuf^[l];
  480. { fpos is set negativ if the line was already written }
  481. { but we still know the correct value }
  482. if fpos<0 then
  483. fpos:=-fpos+1;
  484. if closed then
  485. open;
  486. { in current buf ? }
  487. if (fpos<bufstart) or (fpos>bufstart+bufsize) then
  488. begin
  489. seekbuf(fpos);
  490. readbuf;
  491. end;
  492. { the begin is in the buf now simply read until #13,#10 }
  493. i:=0;
  494. p:=@buf[fpos-bufstart];
  495. repeat
  496. c:=p^;
  497. if c=#0 then
  498. begin
  499. if endoffile then
  500. break;
  501. readbuf;
  502. p:=buf;
  503. c:=p^;
  504. end;
  505. if c in [#10,#13] then
  506. break;
  507. inc(i);
  508. getlinestr[i]:=c;
  509. inc(longint(p));
  510. until (i=255);
  511. {$ifndef TP}
  512. {$ifopt H+}
  513. setlength(getlinestr,i);
  514. {$else}
  515. getlinestr[0]:=chr(i);
  516. {$endif}
  517. {$else}
  518. getlinestr[0]:=chr(i);
  519. {$endif}
  520. end;
  521. end;
  522. {****************************************************************************
  523. TFILEMANAGER
  524. ****************************************************************************}
  525. constructor tfilemanager.init;
  526. begin
  527. files:=nil;
  528. last_ref_index:=0;
  529. cacheindex:=0;
  530. cacheinputfile:=nil;
  531. end;
  532. destructor tfilemanager.done;
  533. var
  534. hp : pinputfile;
  535. begin
  536. hp:=files;
  537. while assigned(hp) do
  538. begin
  539. files:=files^.ref_next;
  540. dispose(hp,done);
  541. hp:=files;
  542. end;
  543. last_ref_index:=0;
  544. end;
  545. procedure tfilemanager.register_file(f : pinputfile);
  546. begin
  547. { don't register macro's }
  548. if f^.is_macro then
  549. exit;
  550. inc(last_ref_index);
  551. f^.ref_next:=files;
  552. f^.ref_index:=last_ref_index;
  553. files:=f;
  554. { update cache }
  555. cacheindex:=last_ref_index;
  556. cacheinputfile:=f;
  557. {$ifdef FPC}
  558. {$ifdef heaptrc}
  559. writeln(stderr,f^.name^,' index ',current_module^.unit_index*100000+f^.ref_index);
  560. {$endif heaptrc}
  561. {$endif FPC}
  562. end;
  563. { this procedure is necessary after loading the
  564. sources files from a PPU file PM }
  565. procedure tfilemanager.inverse_register_indexes;
  566. var
  567. f : pinputfile;
  568. begin
  569. f:=files;
  570. while assigned(f) do
  571. begin
  572. f^.ref_index:=last_ref_index-f^.ref_index+1;
  573. f:=f^.ref_next;
  574. end;
  575. { reset cache }
  576. cacheindex:=0;
  577. cacheinputfile:=nil;
  578. end;
  579. function tfilemanager.get_file(l :longint) : pinputfile;
  580. var
  581. ff : pinputfile;
  582. begin
  583. { check cache }
  584. if (l=cacheindex) and assigned(cacheinputfile) then
  585. begin
  586. get_file:=cacheinputfile;
  587. exit;
  588. end;
  589. ff:=files;
  590. while assigned(ff) and (ff^.ref_index<>l) do
  591. ff:=ff^.ref_next;
  592. get_file:=ff;
  593. end;
  594. function tfilemanager.get_file_name(l :longint):string;
  595. var
  596. hp : pinputfile;
  597. begin
  598. hp:=get_file(l);
  599. if assigned(hp) then
  600. get_file_name:=hp^.name^
  601. else
  602. get_file_name:='';
  603. end;
  604. function tfilemanager.get_file_path(l :longint):string;
  605. var
  606. hp : pinputfile;
  607. begin
  608. hp:=get_file(l);
  609. if assigned(hp) then
  610. get_file_path:=hp^.path^
  611. else
  612. get_file_path:='';
  613. end;
  614. function get_source_file(moduleindex,fileindex : word) : pinputfile;
  615. var
  616. hp : pmodule;
  617. f : pinputfile;
  618. begin
  619. hp:=pmodule(loaded_units.first);
  620. while assigned(hp) and (hp^.unit_index<>moduleindex) do
  621. hp:=pmodule(hp^.next);
  622. get_source_file:=nil;
  623. if not assigned(hp) then
  624. exit;
  625. f:=pinputfile(hp^.sourcefiles^.files);
  626. while assigned(f) do
  627. begin
  628. if f^.ref_index=fileindex then
  629. begin
  630. get_source_file:=f;
  631. exit;
  632. end;
  633. f:=pinputfile(f^.ref_next);
  634. end;
  635. end;
  636. {****************************************************************************
  637. TLinkContainerItem
  638. ****************************************************************************}
  639. {$IFDEF NEWST}
  640. constructor TLinkItem.Init(const s:string;m:longint);
  641. begin
  642. inherited Init;
  643. data:=stringdup(s);
  644. needlink:=m;
  645. end;
  646. destructor TLinkItem.Done;
  647. begin
  648. stringdispose(data);
  649. end;
  650. {$ELSE}
  651. constructor TLinkContainerItem.Init(const s:string;m:longint);
  652. begin
  653. inherited Init;
  654. data:=stringdup(s);
  655. needlink:=m;
  656. end;
  657. destructor TLinkContainerItem.Done;
  658. begin
  659. stringdispose(data);
  660. end;
  661. {$ENDIF NEWST}
  662. {****************************************************************************
  663. TLinkContainer
  664. ****************************************************************************}
  665. {$IFNDEF NEWST}
  666. constructor TLinkContainer.Init;
  667. begin
  668. inherited init;
  669. end;
  670. procedure TLinkContainer.insert(const s : string;m:longint);
  671. var
  672. newnode : plinkcontaineritem;
  673. begin
  674. {if find(s) then
  675. exit; }
  676. new(newnode,init(s,m));
  677. inherited insert(newnode);
  678. end;
  679. function TLinkContainer.get(var m:longint) : string;
  680. var
  681. p : plinkcontaineritem;
  682. begin
  683. p:=plinkcontaineritem(inherited get);
  684. if p=nil then
  685. begin
  686. get:='';
  687. m:=0;
  688. exit;
  689. end;
  690. get:=p^.data^;
  691. m:=p^.needlink;
  692. dispose(p,done);
  693. end;
  694. function TLinkContainer.getusemask(mask:longint) : string;
  695. var
  696. p : plinkcontaineritem;
  697. found : boolean;
  698. begin
  699. found:=false;
  700. repeat
  701. p:=plinkcontaineritem(inherited get);
  702. if p=nil then
  703. begin
  704. getusemask:='';
  705. exit;
  706. end;
  707. getusemask:=p^.data^;
  708. found:=(p^.needlink and mask)<>0;
  709. dispose(p,done);
  710. until found;
  711. end;
  712. function TLinkContainer.find(const s:string):boolean;
  713. var
  714. newnode : plinkcontaineritem;
  715. begin
  716. find:=false;
  717. newnode:=plinkcontaineritem(root);
  718. while assigned(newnode) do
  719. begin
  720. if newnode^.data^=s then
  721. begin
  722. find:=true;
  723. exit;
  724. end;
  725. newnode:=plinkcontaineritem(newnode^.next);
  726. end;
  727. end;
  728. {$ENDIF NEWST}
  729. {****************************************************************************
  730. TMODULE
  731. ****************************************************************************}
  732. procedure tmodule.setfilename(const fn:string;allowoutput:boolean);
  733. var
  734. p : dirstr;
  735. n : NameStr;
  736. e : ExtStr;
  737. begin
  738. stringdispose(objfilename);
  739. stringdispose(asmfilename);
  740. stringdispose(ppufilename);
  741. stringdispose(staticlibfilename);
  742. stringdispose(sharedlibfilename);
  743. stringdispose(exefilename);
  744. stringdispose(outputpath);
  745. stringdispose(path);
  746. { Create names }
  747. fsplit(fn,p,n,e);
  748. n:=FixFileName(n);
  749. { set path }
  750. path:=stringdup(FixPath(p,false));
  751. { obj,asm,ppu names }
  752. p:=path^;
  753. if AllowOutput then
  754. begin
  755. if (OutputUnitDir<>'') then
  756. p:=OutputUnitDir
  757. else
  758. if (OutputExeDir<>'') then
  759. p:=OutputExeDir;
  760. end;
  761. outputpath:=stringdup(p);
  762. objfilename:=stringdup(p+n+target_info.objext);
  763. asmfilename:=stringdup(p+n+target_info.asmext);
  764. ppufilename:=stringdup(p+n+target_info.unitext);
  765. { lib and exe could be loaded with a file specified with -o }
  766. if AllowOutput and (OutputFile<>'') then
  767. n:=OutputFile;
  768. staticlibfilename:=stringdup(p+target_os.libprefix+n+target_os.staticlibext);
  769. if target_info.target=target_i386_WIN32 then
  770. sharedlibfilename:=stringdup(p+n+target_os.sharedlibext)
  771. else
  772. sharedlibfilename:=stringdup(p+target_os.libprefix+n+target_os.sharedlibext);
  773. { output dir of exe can be specified separatly }
  774. if AllowOutput and (OutputExeDir<>'') then
  775. p:=OutputExeDir
  776. else
  777. p:=path^;
  778. exefilename:=stringdup(p+n+target_info.exeext);
  779. end;
  780. function tmodule.openppu:boolean;
  781. var
  782. objfiletime,
  783. ppufiletime,
  784. asmfiletime : longint;
  785. begin
  786. openppu:=false;
  787. Message1(unit_t_ppu_loading,ppufilename^);
  788. { Get ppufile time (also check if the file exists) }
  789. ppufiletime:=getnamedfiletime(ppufilename^);
  790. if ppufiletime=-1 then
  791. exit;
  792. { Open the ppufile }
  793. Message1(unit_u_ppu_name,ppufilename^);
  794. ppufile:=new(pppufile,init(ppufilename^));
  795. ppufile^.change_endian:=source_os.endian<>target_os.endian;
  796. if not ppufile^.open then
  797. begin
  798. dispose(ppufile,done);
  799. Message(unit_u_ppu_file_too_short);
  800. exit;
  801. end;
  802. { check for a valid PPU file }
  803. if not ppufile^.CheckPPUId then
  804. begin
  805. dispose(ppufile,done);
  806. Message(unit_u_ppu_invalid_header);
  807. exit;
  808. end;
  809. { check for allowed PPU versions }
  810. if not (ppufile^.GetPPUVersion = CurrentPPUVersion) then
  811. begin
  812. dispose(ppufile,done);
  813. Message1(unit_u_ppu_invalid_version,tostr(ppufile^.GetPPUVersion));
  814. exit;
  815. end;
  816. { check the target processor }
  817. if ttargetcpu(ppufile^.header.cpu)<>target_cpu then
  818. begin
  819. dispose(ppufile,done);
  820. Message(unit_u_ppu_invalid_processor);
  821. exit;
  822. end;
  823. { check target }
  824. if ttarget(ppufile^.header.target)<>target_info.target then
  825. begin
  826. dispose(ppufile,done);
  827. Message(unit_u_ppu_invalid_target);
  828. exit;
  829. end;
  830. { Load values to be access easier }
  831. flags:=ppufile^.header.flags;
  832. crc:=ppufile^.header.checksum;
  833. interface_crc:=ppufile^.header.interface_checksum;
  834. { Show Debug info }
  835. Message1(unit_u_ppu_time,filetimestring(ppufiletime));
  836. Message1(unit_u_ppu_flags,tostr(flags));
  837. Message1(unit_u_ppu_crc,tostr(ppufile^.header.checksum));
  838. Message1(unit_u_ppu_crc,tostr(ppufile^.header.interface_checksum)+' (intfc)');
  839. { check the object and assembler file to see if we need only to
  840. assemble, only if it's not in a library }
  841. do_compile:=false;
  842. if (flags and uf_in_library)=0 then
  843. begin
  844. if (flags and uf_smart_linked)<>0 then
  845. begin
  846. objfiletime:=getnamedfiletime(staticlibfilename^);
  847. Message2(unit_u_check_time,staticlibfilename^,filetimestring(objfiletime));
  848. if (ppufiletime<0) or (objfiletime<0) or (ppufiletime>objfiletime) then
  849. begin
  850. recompile_reason:=rr_libolder;
  851. Message(unit_u_recompile_staticlib_is_older);
  852. do_compile:=true;
  853. exit;
  854. end;
  855. end;
  856. if (flags and uf_static_linked)<>0 then
  857. begin
  858. { the objectfile should be newer than the ppu file }
  859. objfiletime:=getnamedfiletime(objfilename^);
  860. Message2(unit_u_check_time,objfilename^,filetimestring(objfiletime));
  861. if (ppufiletime<0) or (objfiletime<0) or (ppufiletime>objfiletime) then
  862. begin
  863. { check if assembler file is older than ppu file }
  864. asmfileTime:=GetNamedFileTime(asmfilename^);
  865. Message2(unit_u_check_time,asmfilename^,filetimestring(asmfiletime));
  866. if (asmfiletime<0) or (ppufiletime>asmfiletime) then
  867. begin
  868. Message(unit_u_recompile_obj_and_asm_older);
  869. recompile_reason:=rr_objolder;
  870. do_compile:=true;
  871. exit;
  872. end
  873. else
  874. begin
  875. Message(unit_u_recompile_obj_older_than_asm);
  876. if not(cs_asm_extern in aktglobalswitches) then
  877. begin
  878. do_compile:=true;
  879. recompile_reason:=rr_asmolder;
  880. exit;
  881. end;
  882. end;
  883. end;
  884. end;
  885. end;
  886. openppu:=true;
  887. end;
  888. function tmodule.search_unit(const n : string;onlysource:boolean):boolean;
  889. var
  890. singlepathstring,
  891. filename : string;
  892. Function UnitExists(const ext:string):boolean;
  893. begin
  894. Message1(unit_t_unitsearch,Singlepathstring+filename+ext);
  895. UnitExists:=FileExists(Singlepathstring+FileName+ext);
  896. end;
  897. Function SearchPath(const s:string):boolean;
  898. var
  899. found : boolean;
  900. ext : string[8];
  901. begin
  902. Found:=false;
  903. singlepathstring:=FixPath(s,false);
  904. if not onlysource then
  905. begin
  906. {$ifdef CHECKPPL}
  907. { Check for PPL file }
  908. if not Found then
  909. begin
  910. Found:=UnitExists(target_info.unitlibext);
  911. if Found then
  912. Begin
  913. SetFileName(SinglePathString+FileName,false);
  914. Found:=OpenPPU;
  915. End;
  916. end;
  917. {$endif CHECKPPL}
  918. { Check for PPU file }
  919. if not Found then
  920. begin
  921. Found:=UnitExists(target_info.unitext);
  922. if Found then
  923. Begin
  924. SetFileName(SinglePathString+FileName,false);
  925. Found:=OpenPPU;
  926. End;
  927. end;
  928. end;
  929. { Check for Sources }
  930. if not Found then
  931. begin
  932. ppufile:=nil;
  933. do_compile:=true;
  934. recompile_reason:=rr_noppu;
  935. {Check for .pp file}
  936. Found:=UnitExists(target_os.sourceext);
  937. if Found then
  938. Ext:=target_os.sourceext
  939. else
  940. begin
  941. {Check for .pas}
  942. Found:=UnitExists(target_os.pasext);
  943. if Found then
  944. Ext:=target_os.pasext;
  945. end;
  946. stringdispose(mainsource);
  947. if Found then
  948. begin
  949. sources_avail:=true;
  950. {Load Filenames when found}
  951. mainsource:=StringDup(SinglePathString+FileName+Ext);
  952. SetFileName(SinglePathString+FileName,false);
  953. end
  954. else
  955. sources_avail:=false;
  956. end;
  957. SearchPath:=Found;
  958. end;
  959. Function SearchPathList(list:TSearchPathList):boolean;
  960. var
  961. {$IFDEF NEWST}
  962. hp : PStringItem;
  963. {$ELSE NEWST}
  964. hp : PStringQueueItem;
  965. {$ENDIF NEWST}
  966. found : boolean;
  967. begin
  968. found:=false;
  969. hp:=list.First;
  970. while assigned(hp) do
  971. begin
  972. found:=SearchPath(hp^.data^);
  973. if found then
  974. break;
  975. hp:=hp^.next;
  976. end;
  977. SearchPathList:=found;
  978. end;
  979. var
  980. fnd : boolean;
  981. begin
  982. filename:=FixFileName(n);
  983. { try to find unit
  984. 1. cwd
  985. 2. local unit path
  986. 3. global unit path }
  987. fnd:=SearchPath('.');
  988. if (not fnd) then
  989. fnd:=SearchPathList(current_module^.LocalUnitSearchPath);
  990. if (not fnd) then
  991. fnd:=SearchPathList(UnitSearchPath);
  992. { try to find a file with the first 8 chars of the modulename, like
  993. dos }
  994. if (not fnd) and (length(filename)>8) then
  995. begin
  996. filename:=copy(filename,1,8);
  997. fnd:=SearchPath('.');
  998. if (not fnd) then
  999. fnd:=SearchPathList(current_module^.LocalUnitSearchPath);
  1000. if not fnd then
  1001. fnd:=SearchPathList(UnitSearchPath);
  1002. end;
  1003. search_unit:=fnd;
  1004. end;
  1005. procedure tmodule.reset;
  1006. var
  1007. pm : pdependent_unit;
  1008. begin
  1009. if assigned(scanner) then
  1010. pscannerfile(scanner)^.invalid:=true;
  1011. if assigned(globalsymtable) then
  1012. begin
  1013. dispose(punitsymtable(globalsymtable),done);
  1014. globalsymtable:=nil;
  1015. end;
  1016. if assigned(localsymtable) then
  1017. begin
  1018. dispose(punitsymtable(localsymtable),done);
  1019. localsymtable:=nil;
  1020. end;
  1021. if assigned(map) then
  1022. begin
  1023. dispose(map);
  1024. map:=nil;
  1025. end;
  1026. if assigned(ppufile) then
  1027. begin
  1028. dispose(ppufile,done);
  1029. ppufile:=nil;
  1030. end;
  1031. sourcefiles^.done;
  1032. sourcefiles^.init;
  1033. imports^.done;
  1034. imports^.init;
  1035. _exports^.done;
  1036. _exports^.init;
  1037. used_units.done;
  1038. used_units.init;
  1039. { all units that depend on this one must be recompiled ! }
  1040. pm:=pdependent_unit(dependent_units.first);
  1041. while assigned(pm) do
  1042. begin
  1043. if pm^.u^.in_second_compile then
  1044. Comment(v_debug,'No reload already in second compile: '+pm^.u^.modulename^)
  1045. else
  1046. begin
  1047. pm^.u^.do_reload:=true;
  1048. Comment(v_debug,'Reloading '+pm^.u^.modulename^+' needed because '+modulename^+' is reloaded');
  1049. end;
  1050. pm:=pdependent_unit(pm^.next);
  1051. end;
  1052. dependent_units.done;
  1053. dependent_units.init;
  1054. resourcefiles.done;
  1055. resourcefiles.init;
  1056. linkunitofiles.done;
  1057. linkunitofiles.init{$IFDEF NEWST}(8,4){$ENDIF};
  1058. linkunitstaticlibs.done;
  1059. linkunitstaticlibs.init{$IFDEF NEWST}(8,4){$ENDIF};
  1060. linkunitsharedlibs.done;
  1061. linkunitsharedlibs.init{$IFDEF NEWST}(8,4){$ENDIF};
  1062. linkotherofiles.done;
  1063. linkotherofiles.init{$IFDEF NEWST}(8,4){$ENDIF};
  1064. linkotherstaticlibs.done;
  1065. linkotherstaticlibs.init{$IFDEF NEWST}(8,4){$ENDIF};
  1066. linkothersharedlibs.done;
  1067. linkothersharedlibs.init{$IFDEF NEWST}(8,4){$ENDIF};
  1068. uses_imports:=false;
  1069. do_assemble:=false;
  1070. do_compile:=false;
  1071. { sources_avail:=true;
  1072. should not be changed PM }
  1073. compiled:=false;
  1074. in_implementation:=false;
  1075. in_global:=true;
  1076. {loaded_from:=nil;
  1077. should not be changed PFV }
  1078. flags:=0;
  1079. crc:=0;
  1080. interface_crc:=0;
  1081. unitcount:=1;
  1082. recompile_reason:=rr_unknown;
  1083. end;
  1084. constructor tmodule.init(const s:string;_is_unit:boolean);
  1085. var
  1086. p : dirstr;
  1087. n : namestr;
  1088. e : extstr;
  1089. begin
  1090. FSplit(s,p,n,e);
  1091. { Programs have the name program to don't conflict with dup id's }
  1092. if _is_unit then
  1093. {$ifdef UNITALIASES}
  1094. modulename:=stringdup(GetUnitAlias(Upper(n)))
  1095. {$else}
  1096. modulename:=stringdup(Upper(n))
  1097. {$endif}
  1098. else
  1099. modulename:=stringdup('PROGRAM');
  1100. mainsource:=stringdup(s);
  1101. ppufilename:=nil;
  1102. objfilename:=nil;
  1103. asmfilename:=nil;
  1104. staticlibfilename:=nil;
  1105. sharedlibfilename:=nil;
  1106. exefilename:=nil;
  1107. { Dos has the famous 8.3 limit :( }
  1108. {$ifdef SHORTASMPREFIX}
  1109. asmprefix:=stringdup(FixFileName('as'));
  1110. {$else}
  1111. asmprefix:=stringdup(FixFileName(n));
  1112. {$endif}
  1113. outputpath:=nil;
  1114. path:=nil;
  1115. setfilename(p+n,true);
  1116. localunitsearchpath.init;
  1117. localobjectsearchpath.init;
  1118. localincludesearchpath.init;
  1119. locallibrarysearchpath.init;
  1120. used_units.init;
  1121. dependent_units.init;
  1122. new(sourcefiles,init);
  1123. resourcefiles.init;
  1124. linkunitofiles.init{$IFDEF NEWST}(8,4){$ENDIF};
  1125. linkunitstaticlibs.init{$IFDEF NEWST}(8,4){$ENDIF};
  1126. linkunitsharedlibs.init{$IFDEF NEWST}(8,4){$ENDIF};
  1127. linkotherofiles.init{$IFDEF NEWST}(8,4){$ENDIF};
  1128. linkotherstaticlibs.init{$IFDEF NEWST}(8,4){$ENDIF};
  1129. linkothersharedlibs.init{$IFDEF NEWST}(8,4){$ENDIF};
  1130. ppufile:=nil;
  1131. scanner:=nil;
  1132. map:=nil;
  1133. globalsymtable:=nil;
  1134. localsymtable:=nil;
  1135. loaded_from:=nil;
  1136. flags:=0;
  1137. crc:=0;
  1138. interface_crc:=0;
  1139. do_reload:=false;
  1140. unitcount:=1;
  1141. inc(global_unit_count);
  1142. unit_index:=global_unit_count;
  1143. do_assemble:=false;
  1144. do_compile:=false;
  1145. sources_avail:=true;
  1146. compiled:=false;
  1147. recompile_reason:=rr_unknown;
  1148. in_second_load:=false;
  1149. in_compile:=false;
  1150. in_second_compile:=false;
  1151. in_implementation:=false;
  1152. in_global:=true;
  1153. is_unit:=_is_unit;
  1154. islibrary:=false;
  1155. uses_imports:=false;
  1156. imports:=new(plinkedlist,init);
  1157. _exports:=new(plinkedlist,init);
  1158. { search the PPU file if it is an unit }
  1159. if is_unit then
  1160. search_unit(modulename^,false);
  1161. end;
  1162. destructor tmodule.done;
  1163. {$ifdef MEMDEBUG}
  1164. var
  1165. d : tmemdebug;
  1166. {$endif}
  1167. begin
  1168. if assigned(map) then
  1169. dispose(map);
  1170. if assigned(ppufile) then
  1171. dispose(ppufile,done);
  1172. ppufile:=nil;
  1173. if assigned(imports) then
  1174. dispose(imports,done);
  1175. imports:=nil;
  1176. if assigned(_exports) then
  1177. dispose(_exports,done);
  1178. _exports:=nil;
  1179. if assigned(scanner) then
  1180. pscannerfile(scanner)^.invalid:=true;
  1181. if assigned(sourcefiles) then
  1182. dispose(sourcefiles,done);
  1183. sourcefiles:=nil;
  1184. used_units.done;
  1185. dependent_units.done;
  1186. resourcefiles.done;
  1187. linkunitofiles.done;
  1188. linkunitstaticlibs.done;
  1189. linkunitsharedlibs.done;
  1190. linkotherofiles.done;
  1191. linkotherstaticlibs.done;
  1192. linkothersharedlibs.done;
  1193. stringdispose(objfilename);
  1194. stringdispose(asmfilename);
  1195. stringdispose(ppufilename);
  1196. stringdispose(staticlibfilename);
  1197. stringdispose(sharedlibfilename);
  1198. stringdispose(exefilename);
  1199. stringdispose(outputpath);
  1200. stringdispose(path);
  1201. stringdispose(modulename);
  1202. stringdispose(mainsource);
  1203. stringdispose(asmprefix);
  1204. localunitsearchpath.done;
  1205. localobjectsearchpath.done;
  1206. localincludesearchpath.done;
  1207. locallibrarysearchpath.done;
  1208. {$ifdef MEMDEBUG}
  1209. d.init('symtable');
  1210. {$endif}
  1211. if assigned(globalsymtable) then
  1212. dispose(punitsymtable(globalsymtable),done);
  1213. globalsymtable:=nil;
  1214. if assigned(localsymtable) then
  1215. dispose(punitsymtable(localsymtable),done);
  1216. localsymtable:=nil;
  1217. {$ifdef MEMDEBUG}
  1218. d.done;
  1219. {$endif}
  1220. inherited done;
  1221. end;
  1222. {****************************************************************************
  1223. TUSED_UNIT
  1224. ****************************************************************************}
  1225. constructor tused_unit.init(_u : pmodule;intface:boolean);
  1226. begin
  1227. u:=_u;
  1228. in_interface:=intface;
  1229. in_uses:=false;
  1230. is_stab_written:=false;
  1231. loaded:=true;
  1232. name:=stringdup(_u^.modulename^);
  1233. checksum:=_u^.crc;
  1234. interface_checksum:=_u^.interface_crc;
  1235. unitid:=0;
  1236. end;
  1237. constructor tused_unit.init_to_load(const n:string;c,intfc:longint;intface:boolean);
  1238. begin
  1239. u:=nil;
  1240. in_interface:=intface;
  1241. in_uses:=false;
  1242. is_stab_written:=false;
  1243. loaded:=false;
  1244. name:=stringdup(n);
  1245. checksum:=c;
  1246. interface_checksum:=intfc;
  1247. unitid:=0;
  1248. end;
  1249. destructor tused_unit.done;
  1250. begin
  1251. stringdispose(name);
  1252. inherited done;
  1253. end;
  1254. {****************************************************************************
  1255. TDENPENDENT_UNIT
  1256. ****************************************************************************}
  1257. constructor tdependent_unit.init(_u : pmodule);
  1258. begin
  1259. u:=_u;
  1260. end;
  1261. end.
  1262. {
  1263. $Log$
  1264. Revision 1.117 2000-02-28 17:23:56 daniel
  1265. * Current work of symtable integration committed. The symtable can be
  1266. activated by defining 'newst', but doesn't compile yet. Changes in type
  1267. checking and oop are completed. What is left is to write a new
  1268. symtablestack and adapt the parser to use it.
  1269. Revision 1.116 2000/02/24 18:41:38 peter
  1270. * removed warnings/notes
  1271. Revision 1.115 2000/02/10 16:00:23 peter
  1272. * dont' check for ppl files as they aren't used atm.
  1273. Revision 1.114 2000/02/09 13:22:52 peter
  1274. * log truncated
  1275. Revision 1.113 2000/01/11 09:52:06 peter
  1276. * fixed placing of .sl directories
  1277. * use -b again for base-file selection
  1278. * fixed group writing for linux with smartlinking
  1279. Revision 1.112 2000/01/07 01:14:27 peter
  1280. * updated copyright to 2000
  1281. Revision 1.111 1999/12/08 01:01:11 peter
  1282. * fixed circular unit reference checking. loaded_from was reset after
  1283. reseting a unit, so no loaded_from info was available anymore.
  1284. Revision 1.110 1999/11/16 23:39:04 peter
  1285. * use outputexedir for link.res location
  1286. Revision 1.109 1999/11/12 11:03:50 peter
  1287. * searchpaths changed to stringqueue object
  1288. Revision 1.108 1999/11/06 14:34:20 peter
  1289. * truncated log to 20 revs
  1290. Revision 1.107 1999/11/04 23:13:25 peter
  1291. * moved unit alias support into ifdef
  1292. Revision 1.106 1999/11/04 10:54:02 peter
  1293. + -Ua<oldname>=<newname> unit alias support
  1294. Revision 1.105 1999/10/28 13:14:00 pierre
  1295. * allow doubles in TLinkContainer needed for double libraries
  1296. Revision 1.104 1999/09/27 23:40:12 peter
  1297. * fixed macro within macro endless-loop
  1298. Revision 1.103 1999/09/16 08:00:50 pierre
  1299. + compiled_module to avoid wrong file info when load PPU files
  1300. Revision 1.102 1999/08/31 15:51:10 pierre
  1301. * in_second_compile cleaned up, in_compile and in_second_load added
  1302. Revision 1.101 1999/08/27 10:43:20 pierre
  1303. + interface CRC check with ifdef Test_double_checksum added
  1304. Revision 1.100 1999/08/24 13:14:01 peter
  1305. * MEMDEBUG to see the sizes of asmlist,asmsymbols,symtables
  1306. }