files.pas 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393
  1. {
  2. $Id$
  3. Copyright (c) 1996-98 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. interface
  24. uses
  25. globtype,
  26. cobjects,globals,ppu;
  27. const
  28. {$ifdef FPC}
  29. maxunits = 1024;
  30. InputFileBufSize=32*1024;
  31. linebufincrease=512;
  32. {$else}
  33. maxunits = 128;
  34. InputFileBufSize=1024;
  35. linebufincrease=64;
  36. {$endif}
  37. type
  38. {$ifdef FPC}
  39. tlongintarr = array[0..1000000] of longint;
  40. {$else}
  41. tlongintarr = array[0..16000] of longint;
  42. {$endif}
  43. plongintarr = ^tlongintarr;
  44. pinputfile = ^tinputfile;
  45. tinputfile = object
  46. path,name : pstring; { path and filename }
  47. next : pinputfile; { next file for reading }
  48. f : file; { current file handle }
  49. is_macro,
  50. endoffile, { still bytes left to read }
  51. closed : boolean; { is the file closed }
  52. buf : pchar; { buffer }
  53. bufstart, { buffer start position in the file }
  54. bufsize, { amount of bytes in the buffer }
  55. maxbufsize : longint; { size in memory for the buffer }
  56. saveinputpointer : pchar; { save fields for scanner variables }
  57. savelastlinepos,
  58. saveline_no : longint;
  59. linebuf : plongintarr; { line buffer to retrieve lines }
  60. maxlinebuf : longint;
  61. ref_count : longint; { to handle the browser refs }
  62. ref_index : longint;
  63. ref_next : pinputfile;
  64. constructor init(const fn:string);
  65. destructor done;
  66. procedure setpos(l:longint);
  67. procedure seekbuf(fpos:longint);
  68. procedure readbuf;
  69. function open:boolean;
  70. procedure close;
  71. procedure tempclose;
  72. function tempopen:boolean;
  73. procedure setmacro(p:pchar;len:longint);
  74. procedure setline(line,linepos:longint);
  75. function getlinestr(l:longint):string;
  76. end;
  77. pfilemanager = ^tfilemanager;
  78. tfilemanager = object
  79. files : pinputfile;
  80. last_ref_index : longint;
  81. constructor init;
  82. destructor done;
  83. procedure register_file(f : pinputfile);
  84. procedure inverse_register_indexes;
  85. function get_file(l:longint) : pinputfile;
  86. function get_file_name(l :longint):string;
  87. function get_file_path(l :longint):string;
  88. end;
  89. type
  90. {$ifndef NEWMAP}
  91. tunitmap = array[0..maxunits-1] of pointer;
  92. punitmap = ^tunitmap;
  93. pmodule = ^tmodule;
  94. {$else NEWMAP}
  95. pmodule = ^tmodule;
  96. tunitmap = array[0..maxunits-1] of pmodule;
  97. punitmap = ^tunitmap;
  98. {$endif NEWMAP}
  99. tmodule = object(tlinkedlist_item)
  100. ppufile : pppufile; { the PPU file }
  101. crc,
  102. flags : longint; { the PPU flags }
  103. compiled, { unit is already compiled }
  104. do_assemble, { only assemble the object, don't recompile }
  105. do_compile, { need to compile the sources }
  106. sources_avail, { if all sources are reachable }
  107. is_unit,
  108. in_second_compile, { is this unit being compiled for the 2nd time? }
  109. in_implementation, { processing the implementation part? }
  110. in_global : boolean; { allow global settings }
  111. islibrary : boolean; { if it is a library (win32 dll) }
  112. map : punitmap; { mapping of all used units }
  113. unitcount : word; { local unit counter }
  114. unit_index : word; { global counter for browser }
  115. globalsymtable, { pointer to the local/static symtable of this unit }
  116. localsymtable : pointer; { pointer to the psymtable of this unit }
  117. scanner : pointer; { scanner object used }
  118. loaded_from : pmodule;
  119. uses_imports : boolean; { Set if the module imports from DLL's.}
  120. imports : plinkedlist;
  121. _exports : plinkedlist;
  122. sourcefiles : pfilemanager;
  123. linksharedlibs,
  124. linkstaticlibs,
  125. linkofiles : tstringcontainer;
  126. used_units : tlinkedlist;
  127. path, { path where the module is find/created }
  128. outpath,
  129. modulename, { name of the module in uppercase }
  130. objfilename, { fullname of the objectfile }
  131. asmfilename, { fullname of the assemblerfile }
  132. ppufilename, { fullname of the ppufile }
  133. staticlibfilename, { fullname of the static libraryfile }
  134. sharedlibfilename, { fullname of the shared libraryfile }
  135. exefilename, { fullname of the exefile }
  136. asmprefix, { prefix for the smartlink asmfiles }
  137. mainsource : pstring; { name of the main sourcefile }
  138. constructor init(const s:string;_is_unit:boolean);
  139. destructor done;virtual;
  140. procedure reset;
  141. procedure setfilename(const fn:string;allowoutput:boolean);
  142. function openppu:boolean;
  143. function search_unit(const n : string;onlysource:boolean):boolean;
  144. end;
  145. pused_unit = ^tused_unit;
  146. tused_unit = object(tlinkedlist_item)
  147. unitid : word;
  148. name : pstring;
  149. checksum : longint;
  150. loaded : boolean;
  151. in_uses,
  152. in_interface,
  153. is_stab_written : boolean;
  154. u : pmodule;
  155. constructor init(_u : pmodule;intface:boolean);
  156. constructor init_to_load(const n:string;c:longint;intface:boolean);
  157. destructor done;virtual;
  158. end;
  159. var
  160. main_module : pmodule; { Main module of the program }
  161. current_module : pmodule; { Current module which is compiled }
  162. current_ppu : pppufile; { Current ppufile which is read }
  163. global_unit_count : word;
  164. usedunits : tlinkedlist; { Used units for this program }
  165. loaded_units : tlinkedlist; { All loaded units }
  166. implementation
  167. uses
  168. dos,verbose,systems
  169. {$ifndef VER0_99_8}
  170. ,symtable,scanner
  171. {$endif}
  172. ;
  173. {****************************************************************************
  174. TINPUTFILE
  175. ****************************************************************************}
  176. constructor tinputfile.init(const fn:string);
  177. var
  178. p:dirstr;
  179. n:namestr;
  180. e:extstr;
  181. begin
  182. FSplit(fn,p,n,e);
  183. name:=stringdup(n+e);
  184. path:=stringdup(p);
  185. next:=nil;
  186. { file info }
  187. is_macro:=false;
  188. endoffile:=false;
  189. closed:=true;
  190. buf:=nil;
  191. bufstart:=0;
  192. bufsize:=0;
  193. maxbufsize:=InputFileBufSize;
  194. { save fields }
  195. saveinputpointer:=nil;
  196. saveline_no:=0;
  197. savelastlinepos:=0;
  198. { indexing refs }
  199. ref_next:=nil;
  200. ref_count:=0;
  201. ref_index:=0;
  202. { line buffer }
  203. linebuf:=nil;
  204. maxlinebuf:=0;
  205. end;
  206. destructor tinputfile.done;
  207. begin
  208. if not closed then
  209. close;
  210. stringdispose(path);
  211. stringdispose(name);
  212. { free memory }
  213. if assigned(linebuf) then
  214. freemem(linebuf,maxlinebuf shl 2);
  215. end;
  216. procedure tinputfile.setpos(l:longint);
  217. begin
  218. bufstart:=l;
  219. end;
  220. procedure tinputfile.seekbuf(fpos:longint);
  221. begin
  222. if closed then
  223. exit;
  224. seek(f,fpos);
  225. bufstart:=fpos;
  226. bufsize:=0;
  227. end;
  228. procedure tinputfile.readbuf;
  229. {$ifdef TP}
  230. var
  231. w : word;
  232. {$endif}
  233. begin
  234. if is_macro then
  235. endoffile:=true;
  236. if closed then
  237. exit;
  238. inc(bufstart,bufsize);
  239. {$ifdef TP}
  240. blockread(f,buf^,maxbufsize-1,w);
  241. bufsize:=w;
  242. {$else}
  243. blockread(f,buf^,maxbufsize-1,bufsize);
  244. {$endif}
  245. buf[bufsize]:=#0;
  246. endoffile:=not(bufsize=maxbufsize-1);
  247. end;
  248. function tinputfile.open:boolean;
  249. var
  250. ofm : byte;
  251. begin
  252. open:=false;
  253. if not closed then
  254. Close;
  255. ofm:=filemode;
  256. filemode:=0;
  257. Assign(f,path^+name^);
  258. {$I-}
  259. reset(f,1);
  260. {$I+}
  261. filemode:=ofm;
  262. if ioresult<>0 then
  263. exit;
  264. { file }
  265. endoffile:=false;
  266. closed:=false;
  267. Getmem(buf,MaxBufsize);
  268. bufstart:=0;
  269. bufsize:=0;
  270. open:=true;
  271. end;
  272. procedure tinputfile.close;
  273. var
  274. i : word;
  275. begin
  276. if is_macro then
  277. begin
  278. if assigned(buf) then
  279. Freemem(buf,maxbufsize);
  280. buf:=nil;
  281. {is_macro:=false;
  282. still needed for dispose in scanner PM }
  283. closed:=true;
  284. exit;
  285. end;
  286. if not closed then
  287. begin
  288. {$I-}
  289. system.close(f);
  290. {$I+}
  291. i:=ioresult;
  292. closed:=true;
  293. end;
  294. if assigned(buf) then
  295. begin
  296. Freemem(buf,maxbufsize);
  297. buf:=nil;
  298. end;
  299. bufstart:=0;
  300. end;
  301. procedure tinputfile.tempclose;
  302. var
  303. i : word;
  304. begin
  305. if is_macro then
  306. exit;
  307. if not closed then
  308. begin
  309. {$I-}
  310. system.close(f);
  311. {$I+}
  312. i:=ioresult;
  313. Freemem(buf,maxbufsize);
  314. buf:=nil;
  315. closed:=true;
  316. end;
  317. end;
  318. function tinputfile.tempopen:boolean;
  319. var
  320. ofm : byte;
  321. begin
  322. tempopen:=false;
  323. if is_macro then
  324. begin
  325. tempopen:=true;
  326. exit;
  327. end;
  328. if not closed then
  329. exit;
  330. ofm:=filemode;
  331. filemode:=0;
  332. Assign(f,path^+name^);
  333. {$I-}
  334. reset(f,1);
  335. {$I+}
  336. filemode:=ofm;
  337. if ioresult<>0 then
  338. exit;
  339. closed:=false;
  340. { get new mem }
  341. Getmem(buf,maxbufsize);
  342. { restore state }
  343. seek(f,BufStart);
  344. bufsize:=0;
  345. readbuf;
  346. tempopen:=true;
  347. end;
  348. procedure tinputfile.setmacro(p:pchar;len:longint);
  349. begin
  350. { create new buffer }
  351. getmem(buf,len+1);
  352. move(p^,buf^,len);
  353. buf[len]:=#0;
  354. { reset }
  355. bufstart:=0;
  356. bufsize:=len;
  357. maxbufsize:=len+1;
  358. is_macro:=true;
  359. endoffile:=true;
  360. closed:=true;
  361. end;
  362. procedure tinputfile.setline(line,linepos:longint);
  363. var
  364. oldlinebuf : plongintarr;
  365. begin
  366. if line<1 then
  367. exit;
  368. while (line>=maxlinebuf) do
  369. begin
  370. oldlinebuf:=linebuf;
  371. { create new linebuf and move old info }
  372. getmem(linebuf,(maxlinebuf+linebufincrease) shl 2);
  373. if assigned(oldlinebuf) then
  374. begin
  375. move(oldlinebuf^,linebuf^,maxlinebuf shl 2);
  376. freemem(oldlinebuf,maxlinebuf shl 2);
  377. end;
  378. fillchar(linebuf^[maxlinebuf],linebufincrease shl 2,0);
  379. inc(maxlinebuf,linebufincrease);
  380. end;
  381. linebuf^[line]:=linepos;
  382. end;
  383. function tinputfile.getlinestr(l:longint):string;
  384. var
  385. c : char;
  386. i,
  387. fpos : longint;
  388. p : pchar;
  389. begin
  390. getlinestr:='';
  391. if l<maxlinebuf then
  392. begin
  393. fpos:=linebuf^[l];
  394. { fpos is set negativ if the line was already written }
  395. { but we still know the correct value }
  396. if fpos<0 then
  397. fpos:=-fpos+1;
  398. if closed then
  399. open;
  400. { in current buf ? }
  401. if (fpos<bufstart) or (fpos>bufstart+bufsize) then
  402. begin
  403. seekbuf(fpos);
  404. readbuf;
  405. end;
  406. { the begin is in the buf now simply read until #13,#10 }
  407. i:=0;
  408. p:=@buf[fpos-bufstart];
  409. repeat
  410. c:=p^;
  411. if c=#0 then
  412. begin
  413. if endoffile then
  414. break;
  415. readbuf;
  416. p:=buf;
  417. c:=p^;
  418. end;
  419. if c in [#10,#13] then
  420. break;
  421. inc(i);
  422. getlinestr[i]:=c;
  423. inc(longint(p));
  424. until (i=255);
  425. {$ifndef TP}
  426. {$ifopt H+}
  427. setlength(getlinestr,i);
  428. {$else}
  429. getlinestr[0]:=chr(i);
  430. {$endif}
  431. {$else}
  432. getlinestr[0]:=chr(i);
  433. {$endif}
  434. end;
  435. end;
  436. {****************************************************************************
  437. TFILEMANAGER
  438. ****************************************************************************}
  439. constructor tfilemanager.init;
  440. begin
  441. files:=nil;
  442. last_ref_index:=0;
  443. end;
  444. destructor tfilemanager.done;
  445. var
  446. hp : pinputfile;
  447. begin
  448. hp:=files;
  449. while assigned(hp) do
  450. begin
  451. files:=files^.ref_next;
  452. dispose(hp,done);
  453. hp:=files;
  454. end;
  455. last_ref_index:=0;
  456. end;
  457. procedure tfilemanager.register_file(f : pinputfile);
  458. begin
  459. inc(last_ref_index);
  460. f^.ref_next:=files;
  461. f^.ref_index:=last_ref_index;
  462. files:=f;
  463. {$ifdef FPC}
  464. {$ifdef heaptrc}
  465. writeln(stderr,f^.name^,' index ',current_module^.unit_index*100000+f^.ref_index);
  466. {$endif heaptrc}
  467. {$endif FPC}
  468. end;
  469. { this procedure is necessary after loading the
  470. sources files from a PPU file PM }
  471. procedure tfilemanager.inverse_register_indexes;
  472. var
  473. f : pinputfile;
  474. begin
  475. f:=files;
  476. while assigned(f) do
  477. begin
  478. f^.ref_index:=last_ref_index-f^.ref_index+1;
  479. f:=f^.ref_next;
  480. end;
  481. end;
  482. function tfilemanager.get_file(l :longint) : pinputfile;
  483. var
  484. ff : pinputfile;
  485. begin
  486. ff:=files;
  487. while assigned(ff) and (ff^.ref_index<>l) do
  488. ff:=ff^.ref_next;
  489. get_file:=ff;
  490. end;
  491. function tfilemanager.get_file_name(l :longint):string;
  492. var
  493. hp : pinputfile;
  494. begin
  495. hp:=get_file(l);
  496. if assigned(hp) then
  497. get_file_name:=hp^.name^
  498. else
  499. get_file_name:='';
  500. end;
  501. function tfilemanager.get_file_path(l :longint):string;
  502. var
  503. hp : pinputfile;
  504. begin
  505. hp:=get_file(l);
  506. if assigned(hp) then
  507. get_file_path:=hp^.path^
  508. else
  509. get_file_path:='';
  510. end;
  511. {****************************************************************************
  512. TMODULE
  513. ****************************************************************************}
  514. procedure tmodule.setfilename(const fn:string;allowoutput:boolean);
  515. var
  516. p : dirstr;
  517. n : NameStr;
  518. e : ExtStr;
  519. begin
  520. stringdispose(objfilename);
  521. stringdispose(asmfilename);
  522. stringdispose(ppufilename);
  523. stringdispose(staticlibfilename);
  524. stringdispose(sharedlibfilename);
  525. stringdispose(exefilename);
  526. stringdispose(outpath);
  527. stringdispose(path);
  528. { Create names }
  529. fsplit(fn,p,n,e);
  530. n:=FixFileName(n);
  531. { set path }
  532. path:=stringdup(FixPath(p,false));
  533. { obj,asm,ppu names }
  534. p:=path^;
  535. if AllowOutput then
  536. begin
  537. if (OutputUnitDir<>'') then
  538. p:=OutputUnitDir
  539. else
  540. if (OutputExeDir<>'') then
  541. p:=OutputExeDir;
  542. end;
  543. outpath:=stringdup(p);
  544. objfilename:=stringdup(p+n+target_info.objext);
  545. asmfilename:=stringdup(p+n+target_info.asmext);
  546. ppufilename:=stringdup(p+n+target_info.unitext);
  547. { lib and exe could be loaded with a file specified with -o }
  548. if AllowOutput and (OutputFile<>'') then
  549. n:=OutputFile;
  550. staticlibfilename:=stringdup(p+target_os.libprefix+n+target_os.staticlibext);
  551. if target_info.target=target_i386_WIN32 then
  552. sharedlibfilename:=stringdup(p+n+target_os.sharedlibext)
  553. else
  554. sharedlibfilename:=stringdup(p+target_os.libprefix+n+target_os.sharedlibext);
  555. { output dir of exe can be specified separatly }
  556. if AllowOutput and (OutputExeDir<>'') then
  557. p:=OutputExeDir
  558. else
  559. p:=path^;
  560. exefilename:=stringdup(p+n+target_os.exeext);
  561. end;
  562. function tmodule.openppu:boolean;
  563. var
  564. objfiletime,
  565. ppufiletime,
  566. asmfiletime : longint;
  567. begin
  568. openppu:=false;
  569. Message1(unit_t_ppu_loading,ppufilename^);
  570. { Get ppufile time (also check if the file exists) }
  571. ppufiletime:=getnamedfiletime(ppufilename^);
  572. if ppufiletime=-1 then
  573. exit;
  574. { Open the ppufile }
  575. Message1(unit_u_ppu_name,ppufilename^);
  576. ppufile:=new(pppufile,init(ppufilename^));
  577. ppufile^.change_endian:=source_os.endian<>target_os.endian;
  578. if not ppufile^.open then
  579. begin
  580. dispose(ppufile,done);
  581. Message(unit_u_ppu_file_too_short);
  582. exit;
  583. end;
  584. { check for a valid PPU file }
  585. if not ppufile^.CheckPPUId then
  586. begin
  587. dispose(ppufile,done);
  588. Message(unit_u_ppu_invalid_header);
  589. exit;
  590. end;
  591. { check for allowed PPU versions }
  592. if not (ppufile^.GetPPUVersion = 15) then
  593. begin
  594. dispose(ppufile,done);
  595. Message1(unit_u_ppu_invalid_version,tostr(ppufile^.GetPPUVersion));
  596. exit;
  597. end;
  598. { check the target processor }
  599. if ttargetcpu(ppufile^.header.cpu)<>target_cpu then
  600. begin
  601. dispose(ppufile,done);
  602. Message(unit_u_ppu_invalid_processor);
  603. exit;
  604. end;
  605. { check target }
  606. if ttarget(ppufile^.header.target)<>target_info.target then
  607. begin
  608. dispose(ppufile,done);
  609. Message(unit_u_ppu_invalid_target);
  610. exit;
  611. end;
  612. { Load values to be access easier }
  613. flags:=ppufile^.header.flags;
  614. crc:=ppufile^.header.checksum;
  615. { Show Debug info }
  616. Message1(unit_u_ppu_time,filetimestring(ppufiletime));
  617. Message1(unit_u_ppu_flags,tostr(flags));
  618. Message1(unit_u_ppu_crc,tostr(ppufile^.header.checksum));
  619. { check the object and assembler file to see if we need only to
  620. assemble, only if it's not in a library }
  621. do_compile:=false;
  622. if (flags and uf_in_library)=0 then
  623. begin
  624. if ((flags and uf_static_linked)<>0) or
  625. ((flags and uf_smartlink)<>0) then
  626. begin
  627. objfiletime:=getnamedfiletime(staticlibfilename^);
  628. Message2(unit_u_check_time,staticlibfilename^,filetimestring(objfiletime));
  629. if (ppufiletime<0) or (objfiletime<0) or (ppufiletime>objfiletime) then
  630. begin
  631. Message(unit_u_recompile_staticlib_is_older);
  632. do_compile:=true;
  633. exit;
  634. end;
  635. end
  636. else
  637. if (flags and uf_shared_linked)<>0 then
  638. begin
  639. objfiletime:=getnamedfiletime(sharedlibfilename^);
  640. Message2(unit_u_check_time,sharedlibfilename^,filetimestring(objfiletime));
  641. if (ppufiletime<0) or (objfiletime<0) or (ppufiletime>objfiletime) then
  642. begin
  643. Message(unit_u_recompile_sharedlib_is_older);
  644. do_compile:=true;
  645. exit;
  646. end;
  647. end
  648. else
  649. begin
  650. { the objectfile should be newer than the ppu file }
  651. objfiletime:=getnamedfiletime(objfilename^);
  652. Message2(unit_u_check_time,objfilename^,filetimestring(objfiletime));
  653. if (ppufiletime<0) or (objfiletime<0) or (ppufiletime>objfiletime) then
  654. begin
  655. { check if assembler file is older than ppu file }
  656. asmfileTime:=GetNamedFileTime(asmfilename^);
  657. Message2(unit_u_check_time,asmfilename^,filetimestring(asmfiletime));
  658. if (asmfiletime<0) or (ppufiletime>asmfiletime) then
  659. begin
  660. Message(unit_u_recompile_obj_and_asm_older);
  661. do_compile:=true;
  662. exit;
  663. end
  664. else
  665. begin
  666. Message(unit_u_recompile_obj_older_than_asm);
  667. if not(cs_asm_extern in aktglobalswitches) then
  668. begin
  669. do_compile:=true;
  670. exit;
  671. end;
  672. end;
  673. end;
  674. end;
  675. end;
  676. openppu:=true;
  677. end;
  678. function tmodule.search_unit(const n : string;onlysource:boolean):boolean;
  679. var
  680. ext : string[8];
  681. singlepathstring,
  682. unitPath,
  683. filename : string;
  684. found : boolean;
  685. start,i : longint;
  686. Function UnitExists(const ext:string):boolean;
  687. begin
  688. Message1(unit_t_unitsearch,Singlepathstring+filename+ext);
  689. UnitExists:=FileExists(Singlepathstring+FileName+ext);
  690. end;
  691. begin
  692. start:=1;
  693. filename:=FixFileName(n);
  694. unitpath:=UnitSearchPath;
  695. Found:=false;
  696. repeat
  697. { Create current path to check }
  698. i:=pos(';',unitpath);
  699. if i=0 then
  700. i:=length(unitpath)+1;
  701. singlepathstring:=FixPath(copy(unitpath,start,i-start),false);
  702. delete(unitpath,start,i-start+1);
  703. if not onlysource then
  704. begin
  705. { Check for PPL file }
  706. if not Found then
  707. begin
  708. Found:=UnitExists(target_info.unitlibext);
  709. if Found then
  710. Begin
  711. SetFileName(SinglePathString+FileName,false);
  712. Found:=OpenPPU;
  713. End;
  714. end;
  715. { Check for PPU file }
  716. if not Found then
  717. begin
  718. Found:=UnitExists(target_info.unitext);
  719. if Found then
  720. Begin
  721. SetFileName(SinglePathString+FileName,false);
  722. Found:=OpenPPU;
  723. End;
  724. end;
  725. end;
  726. { Check for Sources }
  727. if not Found then
  728. begin
  729. ppufile:=nil;
  730. do_compile:=true;
  731. {Check for .pp file}
  732. Found:=UnitExists(target_os.sourceext);
  733. if Found then
  734. Ext:=target_os.sourceext
  735. else
  736. begin
  737. {Check for .pas}
  738. Found:=UnitExists(target_os.pasext);
  739. if Found then
  740. Ext:=target_os.pasext;
  741. end;
  742. stringdispose(mainsource);
  743. if Found then
  744. begin
  745. sources_avail:=true;
  746. {Load Filenames when found}
  747. mainsource:=StringDup(SinglePathString+FileName+Ext);
  748. SetFileName(SinglePathString+FileName,false);
  749. end
  750. else
  751. sources_avail:=false;
  752. end;
  753. until Found or (unitpath='');
  754. search_unit:=Found;
  755. end;
  756. procedure tmodule.reset;
  757. begin
  758. {$ifndef VER0_99_8}
  759. if assigned(scanner) then
  760. pscannerfile(scanner)^.invalid:=true;
  761. if assigned(globalsymtable) then
  762. begin
  763. dispose(punitsymtable(globalsymtable),done);
  764. globalsymtable:=nil;
  765. end;
  766. if assigned(localsymtable) then
  767. begin
  768. dispose(punitsymtable(localsymtable),done);
  769. localsymtable:=nil;
  770. end;
  771. {$endif}
  772. if assigned(map) then
  773. begin
  774. dispose(map);
  775. map:=nil;
  776. end;
  777. if assigned(ppufile) then
  778. begin
  779. dispose(ppufile,done);
  780. ppufile:=nil;
  781. end;
  782. sourcefiles^.done;
  783. sourcefiles^.init;
  784. imports^.done;
  785. imports^.init;
  786. _exports^.done;
  787. _exports^.init;
  788. used_units.done;
  789. used_units.init;
  790. linkofiles.done;
  791. linkofiles.init_no_double;
  792. linkstaticlibs.done;
  793. linkstaticlibs.init_no_double;
  794. linksharedlibs.done;
  795. linksharedlibs.init_no_double;
  796. uses_imports:=false;
  797. do_assemble:=false;
  798. do_compile:=false;
  799. { sources_avail:=true;
  800. should not be changed PM }
  801. compiled:=false;
  802. in_implementation:=false;
  803. in_global:=true;
  804. loaded_from:=nil;
  805. flags:=0;
  806. crc:=0;
  807. unitcount:=1;
  808. end;
  809. constructor tmodule.init(const s:string;_is_unit:boolean);
  810. var
  811. p : dirstr;
  812. n : namestr;
  813. e : extstr;
  814. begin
  815. FSplit(s,p,n,e);
  816. { Programs have the name program to don't conflict with dup id's }
  817. if _is_unit then
  818. modulename:=stringdup(Upper(n))
  819. else
  820. modulename:=stringdup('PROGRAM');
  821. mainsource:=stringdup(s);
  822. ppufilename:=nil;
  823. objfilename:=nil;
  824. asmfilename:=nil;
  825. staticlibfilename:=nil;
  826. sharedlibfilename:=nil;
  827. exefilename:=nil;
  828. outpath:=nil;
  829. { Dos has the famous 8.3 limit :( }
  830. {$ifdef tp}
  831. asmprefix:=stringdup(FixFileName('as'));
  832. {$else}
  833. {$ifdef go32v2}
  834. asmprefix:=stringdup(FixFileName('as'));
  835. {$else}
  836. {$ifdef OS2}
  837. {Allthough OS/2 supports long filenames I play it safe and
  838. use 8.3 filenames, because this allows the compiler to run
  839. on a FAT partition. (DM)}
  840. asmprefix:=stringdup(FixFileName('as'));
  841. {$else}
  842. asmprefix:=stringdup(FixFileName(n));
  843. {$endif}
  844. {$endif}
  845. {$endif tp}
  846. path:=nil;
  847. setfilename(p+n,true);
  848. used_units.init;
  849. new(sourcefiles,init);
  850. linkofiles.init_no_double;
  851. linkstaticlibs.init_no_double;
  852. linksharedlibs.init_no_double;
  853. ppufile:=nil;
  854. scanner:=nil;
  855. map:=nil;
  856. globalsymtable:=nil;
  857. localsymtable:=nil;
  858. loaded_from:=nil;
  859. flags:=0;
  860. crc:=0;
  861. unitcount:=1;
  862. inc(global_unit_count);
  863. unit_index:=global_unit_count;
  864. do_assemble:=false;
  865. do_compile:=false;
  866. sources_avail:=true;
  867. compiled:=false;
  868. in_second_compile:=false;
  869. in_implementation:=false;
  870. in_global:=true;
  871. is_unit:=_is_unit;
  872. islibrary:=false;
  873. uses_imports:=false;
  874. imports:=new(plinkedlist,init);
  875. _exports:=new(plinkedlist,init);
  876. { search the PPU file if it is an unit }
  877. if is_unit then
  878. begin
  879. if (not search_unit(modulename^,false)) and (length(modulename^)>8) then
  880. search_unit(copy(modulename^,1,8),false);
  881. end;
  882. end;
  883. destructor tmodule.done;
  884. begin
  885. if assigned(map) then
  886. dispose(map);
  887. if assigned(ppufile) then
  888. dispose(ppufile,done);
  889. ppufile:=nil;
  890. if assigned(imports) then
  891. dispose(imports,done);
  892. imports:=nil;
  893. if assigned(_exports) then
  894. dispose(_exports,done);
  895. _exports:=nil;
  896. {$ifndef VER0_99_8}
  897. if assigned(scanner) then
  898. pscannerfile(scanner)^.invalid:=true;
  899. {$endif}
  900. if assigned(sourcefiles) then
  901. dispose(sourcefiles,done);
  902. sourcefiles:=nil;
  903. used_units.done;
  904. linkofiles.done;
  905. linkstaticlibs.done;
  906. linksharedlibs.done;
  907. stringdispose(objfilename);
  908. stringdispose(asmfilename);
  909. stringdispose(ppufilename);
  910. stringdispose(staticlibfilename);
  911. stringdispose(sharedlibfilename);
  912. stringdispose(exefilename);
  913. stringdispose(outpath);
  914. stringdispose(path);
  915. stringdispose(modulename);
  916. stringdispose(mainsource);
  917. stringdispose(asmprefix);
  918. {$ifndef VER0_99_8}
  919. if assigned(globalsymtable) then
  920. dispose(punitsymtable(globalsymtable),done);
  921. globalsymtable:=nil;
  922. if assigned(localsymtable) then
  923. dispose(punitsymtable(localsymtable),done);
  924. localsymtable:=nil;
  925. {$endif}
  926. inherited done;
  927. end;
  928. {****************************************************************************
  929. TUSED_UNIT
  930. ****************************************************************************}
  931. constructor tused_unit.init(_u : pmodule;intface:boolean);
  932. begin
  933. u:=_u;
  934. in_interface:=intface;
  935. in_uses:=false;
  936. is_stab_written:=false;
  937. loaded:=true;
  938. name:=stringdup(_u^.modulename^);
  939. checksum:=_u^.crc;
  940. unitid:=0;
  941. end;
  942. constructor tused_unit.init_to_load(const n:string;c:longint;intface:boolean);
  943. begin
  944. u:=nil;
  945. in_interface:=intface;
  946. in_uses:=false;
  947. is_stab_written:=false;
  948. loaded:=false;
  949. name:=stringdup(n);
  950. checksum:=c;
  951. unitid:=0;
  952. end;
  953. destructor tused_unit.done;
  954. begin
  955. stringdispose(name);
  956. inherited done;
  957. end;
  958. end.
  959. {
  960. $Log$
  961. Revision 1.79 1998-12-11 00:03:14 peter
  962. + globtype,tokens,version unit splitted from globals
  963. Revision 1.78 1998/12/04 10:18:07 florian
  964. * some stuff for procedures of object added
  965. * bug with overridden virtual constructors fixed (reported by Italo Gomes)
  966. Revision 1.77 1998/12/02 16:23:37 jonas
  967. * changed "if longintvar in set" to case or "if () or () .." statements
  968. * tree.pas: changed inlinenumber (and associated constructor/vars) to a byte
  969. Revision 1.76 1998/12/01 12:51:19 peter
  970. * fixed placing of ppas.sh and link.res when using -FE
  971. Revision 1.75 1998/11/16 15:41:40 peter
  972. * tp7 didn't like my ifopt H+ :(
  973. Revision 1.74 1998/11/16 12:18:01 peter
  974. * H+ fixes
  975. Revision 1.73 1998/11/16 11:28:58 pierre
  976. * stackcheck removed for i386_win32
  977. * exportlist does not crash at least !!
  978. (was need for tests dir !)z
  979. Revision 1.72 1998/11/15 16:32:35 florian
  980. * some stuff of Pavel implement (win32 dll creation)
  981. * bug with ansistring function results fixed
  982. Revision 1.71 1998/11/06 09:45:40 pierre
  983. * bug on errors (file used after dispose !) fixed
  984. Revision 1.70 1998/11/03 11:33:14 peter
  985. + search_unit arg to only search for sources
  986. Revision 1.69 1998/10/29 11:35:44 florian
  987. * some dll support for win32
  988. * fixed assembler writing for PalmOS
  989. Revision 1.68 1998/10/27 10:22:34 florian
  990. + First things for win32 export sections
  991. Revision 1.67 1998/10/26 22:23:29 peter
  992. + fixpath() has an extra option to allow a ./ as path
  993. Revision 1.66 1998/10/19 18:07:11 peter
  994. + external dll_name name func support for linux
  995. Revision 1.65 1998/10/15 12:22:25 pierre
  996. * close include files immediately after end reading
  997. instead of waiting until unit compilation ended !
  998. Revision 1.64 1998/10/14 13:38:19 peter
  999. * fixed path with staticlib/objects in ppufiles
  1000. Revision 1.63 1998/10/14 11:02:49 daniel
  1001. * Stupid typo fixed.
  1002. Revision 1.62 1998/10/14 10:59:37 daniel
  1003. * Staticlibfilename now doesn't include path.
  1004. Revision 1.61 1998/10/14 10:57:25 daniel
  1005. * Dirstr, namestr, extstr.
  1006. * $V+ to prevent Peter from forgetting this.
  1007. * OS/2 compiler uses 8.3 filenames to support running the compiler on an old
  1008. DOS FAT partition.
  1009. Revision 1.60 1998/10/14 10:45:07 pierre
  1010. * ppu problems for m68k fixed (at least in cross compiling)
  1011. * one last memory leak for sysamiga fixed
  1012. * the amiga RTL compiles now completely !!
  1013. Revision 1.59 1998/10/13 14:01:07 peter
  1014. * fixed -al
  1015. Revision 1.58 1998/10/12 11:59:00 peter
  1016. + show name and date of .o and .s files which the compiler checks
  1017. Revision 1.57 1998/10/09 16:36:03 pierre
  1018. * some memory leaks specific to usebrowser define fixed
  1019. * removed tmodule.implsymtable (was like tmodule.localsymtable)
  1020. Revision 1.56 1998/10/09 08:56:26 pierre
  1021. * several memory leaks fixed
  1022. Revision 1.55 1998/10/08 23:28:54 peter
  1023. * -vu shows unit info, -vt shows tried/used files
  1024. Revision 1.54 1998/10/08 17:17:19 pierre
  1025. * current_module old scanner tagged as invalid if unit is recompiled
  1026. + added ppheap for better info on tracegetmem of heaptrc
  1027. (adds line column and file index)
  1028. * several memory leaks removed ith help of heaptrc !!
  1029. Revision 1.53 1998/10/08 13:48:43 peter
  1030. * fixed memory leaks for do nothing source
  1031. * fixed unit interdependency
  1032. Revision 1.52 1998/10/06 22:09:48 peter
  1033. * fixed for compiling with 0.99.8 due circular units
  1034. Revision 1.51 1998/10/06 17:16:47 pierre
  1035. * some memory leaks fixed (thanks to Peter for heaptrc !)
  1036. Revision 1.50 1998/09/30 16:43:34 peter
  1037. * fixed unit interdependency with circular uses
  1038. Revision 1.49 1998/09/28 16:57:20 pierre
  1039. * changed all length(p^.value_str^) into str_length(p)
  1040. to get it work with and without ansistrings
  1041. * changed sourcefiles field of tmodule to a pointer
  1042. Revision 1.48 1998/09/24 23:46:34 peter
  1043. + outputdir support
  1044. Revision 1.47 1998/09/22 17:13:43 pierre
  1045. + browsing updated and developed
  1046. records and objects fields are also stored
  1047. Revision 1.46 1998/09/21 08:45:10 pierre
  1048. + added vmt_offset in tobjectdef.write for fututre use
  1049. (first steps to have objects without vmt if no virtual !!)
  1050. + added fpu_used field for tabstractprocdef :
  1051. sets this level to 2 if the functions return with value in FPU
  1052. (is then set to correct value at parsing of implementation)
  1053. THIS MIGHT refuse some code with FPU expression too complex
  1054. that were accepted before and even in some cases
  1055. that don't overflow in fact
  1056. ( like if f : float; is a forward that finally in implementation
  1057. only uses one fpu register !!)
  1058. Nevertheless I think that it will improve security on
  1059. FPU operations !!
  1060. * most other changes only for UseBrowser code
  1061. (added symtable references for record and objects)
  1062. local switch for refs to args and local of each function
  1063. (static symtable still missing)
  1064. UseBrowser still not stable and probably broken by
  1065. the definition hash array !!
  1066. Revision 1.45 1998/09/18 09:58:51 peter
  1067. * -s doesn't require the .o to be available, this allows compiling of
  1068. everything on other platforms (profiling the windows.pp loading ;)
  1069. Revision 1.44 1998/09/10 13:51:32 peter
  1070. * tp compiler also uses 'as' as asmprefix
  1071. Revision 1.43 1998/09/03 17:08:45 pierre
  1072. * better lines for stabs
  1073. (no scroll back to if before else part
  1074. no return to case line at jump outside case)
  1075. + source lines also if not in order
  1076. Revision 1.42 1998/09/03 11:24:00 peter
  1077. * moved more inputfile things from tscannerfile to tinputfile
  1078. * changed ifdef Sourceline to cs_asm_source
  1079. Revision 1.41 1998/08/26 15:35:30 peter
  1080. * fixed scannerfiles for macros
  1081. + $I %<environment>%
  1082. Revision 1.40 1998/08/26 10:08:48 peter
  1083. * fixed problem with libprefix at the wrong place
  1084. * fixed lib generation with smartlinking and no -CS used
  1085. Revision 1.39 1998/08/25 16:44:16 pierre
  1086. * openppu was true even if the object file is missing
  1087. this lead to trying to open a filename without extension
  1088. and prevented the 'make cycle' to work for win32
  1089. Revision 1.38 1998/08/19 10:06:12 peter
  1090. * fixed filenames and removedir which supports slash at the end
  1091. Revision 1.37 1998/08/18 20:52:19 peter
  1092. * renamed in_main to in_global which is more logical
  1093. Revision 1.36 1998/08/17 10:10:07 peter
  1094. - removed OLDPPU
  1095. Revision 1.35 1998/08/17 09:17:44 peter
  1096. * static/shared linking updates
  1097. Revision 1.34 1998/08/14 21:56:31 peter
  1098. * setting the outputfile using -o works now to create static libs
  1099. Revision 1.33 1998/08/11 14:09:08 peter
  1100. * fixed some messages and smaller msgtxt.inc
  1101. Revision 1.32 1998/08/10 14:49:58 peter
  1102. + localswitches, moduleswitches, globalswitches splitting
  1103. Revision 1.31 1998/07/14 14:46:48 peter
  1104. * released NEWINPUT
  1105. Revision 1.30 1998/07/07 11:19:55 peter
  1106. + NEWINPUT for a better inputfile and scanner object
  1107. Revision 1.29 1998/06/25 10:51:00 pierre
  1108. * removed a remaining ifndef NEWPPU
  1109. replaced by ifdef OLDPPU
  1110. * added uf_finalize to ppu unit
  1111. Revision 1.28 1998/06/25 08:48:12 florian
  1112. * first version of rtti support
  1113. Revision 1.27 1998/06/24 14:48:34 peter
  1114. * ifdef newppu -> ifndef oldppu
  1115. Revision 1.26 1998/06/17 14:36:19 peter
  1116. * forgot an $ifndef OLDPPU :(
  1117. Revision 1.25 1998/06/17 14:10:11 peter
  1118. * small os2 fixes
  1119. * fixed interdependent units with newppu (remake3 under linux works now)
  1120. Revision 1.24 1998/06/16 08:56:20 peter
  1121. + targetcpu
  1122. * cleaner pmodules for newppu
  1123. Revision 1.23 1998/06/15 14:44:36 daniel
  1124. * BP updates.
  1125. Revision 1.22 1998/06/14 18:25:41 peter
  1126. * small fix with crc in newppu
  1127. Revision 1.21 1998/06/13 00:10:05 peter
  1128. * working browser and newppu
  1129. * some small fixes against crashes which occured in bp7 (but not in
  1130. fpc?!)
  1131. Revision 1.20 1998/06/12 14:50:48 peter
  1132. * removed the tree dependency to types.pas
  1133. * long_fil.pas support (not fully tested yet)
  1134. Revision 1.19 1998/06/12 10:32:26 pierre
  1135. * column problem hopefully solved
  1136. + C vars declaration changed
  1137. Revision 1.18 1998/06/11 13:58:07 peter
  1138. * small fix to let newppu compile
  1139. Revision 1.17 1998/06/09 16:01:40 pierre
  1140. + added procedure directive parsing for procvars
  1141. (accepted are popstack cdecl and pascal)
  1142. + added C vars with the following syntax
  1143. var C calias 'true_c_name';(can be followed by external)
  1144. reason is that you must add the Cprefix
  1145. which is target dependent
  1146. Revision 1.16 1998/06/04 10:42:19 pierre
  1147. * small bug fix in load_ppu or openppu
  1148. Revision 1.15 1998/05/28 14:37:53 peter
  1149. * default programname is PROGRAM (like TP7) to avoid dup id's
  1150. Revision 1.14 1998/05/27 19:45:02 peter
  1151. * symtable.pas splitted into includefiles
  1152. * symtable adapted for $ifndef OLDPPU
  1153. Revision 1.13 1998/05/23 01:21:05 peter
  1154. + aktasmmode, aktoptprocessor, aktoutputformat
  1155. + smartlink per module $SMARTLINK-/+ (like MMX) and moved to aktswitches
  1156. + $LIBNAME to set the library name where the unit will be put in
  1157. * splitted cgi386 a bit (codeseg to large for bp7)
  1158. * nasm, tasm works again. nasm moved to ag386nsm.pas
  1159. Revision 1.12 1998/05/20 09:42:33 pierre
  1160. + UseTokenInfo now default
  1161. * unit in interface uses and implementation uses gives error now
  1162. * only one error for unknown symbol (uses lastsymknown boolean)
  1163. the problem came from the label code !
  1164. + first inlined procedures and function work
  1165. (warning there might be allowed cases were the result is still wrong !!)
  1166. * UseBrower updated gives a global list of all position of all used symbols
  1167. with switch -gb
  1168. Revision 1.11 1998/05/12 10:46:59 peter
  1169. * moved printstatus to verb_def
  1170. + V_Normal which is between V_Error and V_Warning and doesn't have a
  1171. prefix like error: warning: and is included in V_Default
  1172. * fixed some messages
  1173. * first time parameter scan is only for -v and -T
  1174. - removed old style messages
  1175. Revision 1.10 1998/05/11 13:07:53 peter
  1176. + $ifndef OLDPPU for the new ppuformat
  1177. + $define GDB not longer required
  1178. * removed all warnings and stripped some log comments
  1179. * no findfirst/findnext anymore to remove smartlink *.o files
  1180. Revision 1.9 1998/05/06 15:04:20 pierre
  1181. + when trying to find source files of a ppufile
  1182. check the includepathlist for included files
  1183. the main file must still be in the same directory
  1184. Revision 1.8 1998/05/04 17:54:25 peter
  1185. + smartlinking works (only case jumptable left todo)
  1186. * redesign of systems.pas to support assemblers and linkers
  1187. + Unitname is now also in the PPU-file, increased version to 14
  1188. Revision 1.7 1998/05/01 16:38:44 florian
  1189. * handling of private and protected fixed
  1190. + change_keywords_to_tp implemented to remove
  1191. keywords which aren't supported by tp
  1192. * break and continue are now symbols of the system unit
  1193. + widestring, longstring and ansistring type released
  1194. Revision 1.6 1998/05/01 07:43:53 florian
  1195. + basics for rtti implemented
  1196. + switch $m (generate rtti for published sections)
  1197. Revision 1.5 1998/04/30 15:59:40 pierre
  1198. * GDB works again better :
  1199. correct type info in one pass
  1200. + UseTokenInfo for better source position
  1201. * fixed one remaining bug in scanner for line counts
  1202. * several little fixes
  1203. Revision 1.4 1998/04/29 10:33:52 pierre
  1204. + added some code for ansistring (not complete nor working yet)
  1205. * corrected operator overloading
  1206. * corrected nasm output
  1207. + started inline procedures
  1208. + added starstarn : use ** for exponentiation (^ gave problems)
  1209. + started UseTokenInfo cond to get accurate positions
  1210. Revision 1.3 1998/04/27 23:10:28 peter
  1211. + new scanner
  1212. * $makelib -> if smartlink
  1213. * small filename fixes pmodule.setfilename
  1214. * moved import from files.pas -> import.pas
  1215. Revision 1.2 1998/04/21 10:16:47 peter
  1216. * patches from strasbourg
  1217. * objects is not used anymore in the fpc compiled version
  1218. }