globals.pas 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552
  1. {
  2. $Id$
  3. Copyright (C) 1993-98 by Florian Klaempfl
  4. This unit implements some support functions and global variables
  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. {$ifdef tp}
  19. {$E+,N+}
  20. {$endif}
  21. unit globals;
  22. interface
  23. uses
  24. {$ifdef win32}
  25. windows,
  26. {$endif}
  27. {$ifdef linux}
  28. linux,
  29. {$endif}
  30. {$ifdef Delphi4}
  31. dmisc,
  32. sysutils,
  33. {$else}
  34. strings,dos,
  35. {$endif}
  36. {$ifdef TP}
  37. objects,
  38. {$endif}
  39. globtype,version,tokens,systems,cobjects;
  40. const
  41. {$ifdef linux}
  42. DirSep = '/';
  43. {$else}
  44. {$ifdef amiga}
  45. DirSep = '/';
  46. {$else}
  47. DirSep = '\';
  48. {$endif}
  49. {$endif}
  50. {$ifdef Splitheap}
  51. testsplit : boolean = false;
  52. {$endif Splitheap}
  53. delphimodeswitches : tmodeswitches=
  54. [m_delphi,m_tp,m_all,m_class,m_objpas,m_result,m_string_pchar,
  55. m_pointer_2_procedure,m_autoderef,m_tp_procvar,m_initfinal];
  56. fpcmodeswitches : tmodeswitches=
  57. [m_fpc,m_all,m_string_pchar,m_nested_comment,m_repeat_forward,
  58. m_cvar_support,m_initfinal,m_add_pointer];
  59. objfpcmodeswitches : tmodeswitches=
  60. [m_objfpc,m_fpc,m_all,m_class,m_objpas,m_result,m_string_pchar,m_nested_comment,
  61. m_repeat_forward,m_cvar_support,m_initfinal,m_add_pointer];
  62. tpmodeswitches : tmodeswitches=
  63. [m_tp,m_all,m_tp_procvar];
  64. gpcmodeswitches : tmodeswitches=
  65. [m_gpc,m_all];
  66. type
  67. TSearchPathList = object(TStringQueue)
  68. procedure AddPath(s:string;addfirst:boolean);
  69. procedure AddList(list:TSearchPathList;addfirst:boolean);
  70. function FindFile(const f : string;var b : boolean) : string;
  71. end;
  72. var
  73. { specified inputfile }
  74. inputdir : dirstr;
  75. inputfile : namestr;
  76. inputextension : extstr;
  77. { specified outputfile with -o parameter }
  78. outputfile : namestr;
  79. { specified with -FE or -FU }
  80. outputexedir : dirstr;
  81. outputunitdir : dirstr;
  82. { things specified with parameters }
  83. paralinkoptions,
  84. paradynamiclinker : string;
  85. parapreprocess : boolean;
  86. { directory where the utils can be found (options -FD) }
  87. utilsdirectory : dirstr;
  88. { some flags for global compiler switches }
  89. do_build,
  90. do_make : boolean;
  91. not_unit_proc : boolean;
  92. { path for searching units, different paths can be seperated by ; }
  93. exepath : dirstr; { Path to ppc }
  94. librarysearchpath,
  95. unitsearchpath,
  96. objectsearchpath,
  97. includesearchpath : TSearchPathList;
  98. { deffile }
  99. usewindowapi : boolean;
  100. description : string;
  101. dllversion : string;
  102. { current position }
  103. token, { current token being parsed }
  104. idtoken : ttoken; { holds the token if the pattern is a known word }
  105. tokenpos, { last postion of the read token }
  106. aktfilepos : tfileposinfo; { current position }
  107. { type of currently parsed block }
  108. { isn't full implemented (FK) }
  109. block_type : tblock_type;
  110. in_args : boolean; { arguments must be checked especially }
  111. parsing_para_level : longint; { parameter level, used to convert
  112. proc calls to proc loads in firstcalln }
  113. { Must_be_valid : boolean; should the variable already have a value
  114. obsolete replace by set_varstate function }
  115. compile_level : word;
  116. make_ref : boolean;
  117. resolving_forward : boolean; { used to add forward reference as second ref }
  118. use_esp_stackframe : boolean; { to test for call with ESP as stack frame }
  119. {$ifdef TP}
  120. use_big : boolean;
  121. {$endif}
  122. { commandline values }
  123. initdefines : tlinkedlist;
  124. initglobalswitches : tglobalswitches;
  125. initmoduleswitches : tmoduleswitches;
  126. initlocalswitches : tlocalswitches;
  127. initmodeswitches : tmodeswitches;
  128. initpackenum : longint;
  129. initpackrecords : tpackrecords;
  130. initoutputformat : tasm;
  131. initoptprocessor : tprocessors;
  132. initasmmode : tasmmode;
  133. { current state values }
  134. aktglobalswitches : tglobalswitches;
  135. aktmoduleswitches : tmoduleswitches;
  136. aktlocalswitches : tlocalswitches;
  137. aktmodeswitches : tmodeswitches;
  138. aktpackenum : longint;
  139. aktpackrecords : tpackrecords;
  140. aktoutputformat : tasm;
  141. aktoptprocessor : tprocessors;
  142. aktasmmode : tasmmode;
  143. { Memory sizes }
  144. heapsize,
  145. maxheapsize,
  146. stacksize : longint;
  147. {$Ifdef EXTDEBUG}
  148. total_of_firstpass,
  149. firstpass_several : longint;
  150. {$ifdef FPC}
  151. EntryMemUsed : longint;
  152. {$endif FPC}
  153. { parameter switches }
  154. debugstop,
  155. only_one_pass : boolean;
  156. {$EndIf EXTDEBUG}
  157. { windows application type }
  158. apptype : tapptype;
  159. const
  160. RelocSection : boolean = true;
  161. RelocSectionSetExplicitly : boolean = false;
  162. DLLsource : boolean = false;
  163. DLLImageBase : pstring = nil;
  164. UseDeffileForExport : boolean = true;
  165. ForceDeffileForExport : boolean = false;
  166. { used to set all registers used for each global function
  167. this should dramatically decrease the number of
  168. recompilations needed PM }
  169. simplify_ppu : boolean = false;
  170. { should we allow non static members ? }
  171. allow_only_static : boolean = false;
  172. Inside_asm_statement : boolean = false;
  173. { for error info in pp.pas }
  174. const
  175. parser_current_file : string = '';
  176. {$ifdef debug}
  177. { if the pointer don't point to the heap then write an error }
  178. function assigned(p : pointer) : boolean;
  179. {$endif}
  180. function min(a,b : longint) : longint;
  181. function max(a,b : longint) : longint;
  182. function align(i,a:longint):longint;
  183. procedure Replace(var s:string;s1:string;const s2:string);
  184. procedure ReplaceCase(var s:string;const s1,s2:string);
  185. function upper(const s : string) : string;
  186. function lower(const s : string) : string;
  187. function trimspace(const s:string):string;
  188. {$ifdef FPC}
  189. function tostru(i:cardinal) : string;
  190. {$else}
  191. function tostru(i:longint) : string;
  192. {$endif}
  193. procedure uppervar(var s : string);
  194. function tostr(i : longint) : string;
  195. function tostr_with_plus(i : longint) : string;
  196. procedure valint(S : string;var V : longint;var code : integer);
  197. function is_number(const s : string) : boolean;
  198. function ispowerof2(value : longint;var power : longint) : boolean;
  199. { enable ansistring comparison }
  200. function compareansistrings(p1,p2 : pchar;length1,length2 : longint) : longint;
  201. function concatansistrings(p1,p2 : pchar;length1,length2 : longint) : pchar;
  202. function bstoslash(const s : string) : string;
  203. procedure abstract;
  204. function getdatestr:string;
  205. function gettimestr:string;
  206. function filetimestring( t : longint) : string;
  207. procedure DefaultReplacements(var s:string);
  208. function path_absolute(const s : string) : boolean;
  209. Function FileExists ( Const F : String) : Boolean;
  210. Function RemoveFile(const f:string):boolean;
  211. Function RemoveDir(d:string):boolean;
  212. Function GetFileTime ( Var F : File) : Longint;
  213. Function GetNamedFileTime ( Const F : String) : Longint;
  214. Function SplitFileName(const s:string):string;
  215. Function SplitName(const s:string):string;
  216. Function SplitExtension(Const HStr:String):String;
  217. Function AddExtension(Const HStr,ext:String):String;
  218. Function ForceExtension(Const HStr,ext:String):String;
  219. Function FixPath(s:string;allowdot:boolean):string;
  220. function FixFileName(const s:string):string;
  221. procedure SplitBinCmd(const s:string;var bstr,cstr:string);
  222. procedure SynchronizeFileTime(const fn1,fn2:string);
  223. function FindFile(const f : string;path : string;var b : boolean) : string;
  224. function FindExe(bin:string;var found:boolean):string;
  225. function GetShortName(const n:string):string;
  226. Procedure Shell(const command:string);
  227. function GetEnvPChar(const envname:string):pchar;
  228. procedure FreeEnvPChar(p:pchar);
  229. procedure InitGlobals;
  230. procedure DoneGlobals;
  231. implementation
  232. uses
  233. comphook;
  234. procedure abstract;
  235. begin
  236. do_internalerror(255);
  237. end;
  238. function ngraphsearchvalue(const s1,s2 : string) : double;
  239. const
  240. n = 3;
  241. var
  242. equals,i,j : longint;
  243. hs : string;
  244. begin
  245. equals:=0;
  246. { is the string long enough ? }
  247. if min(length(s1),length(s2))-n+1<1 then
  248. begin
  249. ngraphsearchvalue:=0.0;
  250. exit;
  251. end;
  252. for i:=1 to length(s1)-n+1 do
  253. begin
  254. hs:=copy(s1,i,n);
  255. for j:=1 to length(s2)-n+1 do
  256. if hs=copy(s2,j,n) then
  257. inc(equals);
  258. end;
  259. {$ifdef fpc}
  260. ngraphsearchvalue:=equals/double(max(length(s1),length(s2))-n+1);
  261. {$else}
  262. ngraphsearchvalue:=equals/(max(length(s1),length(s2))-n+1);
  263. {$endif}
  264. end;
  265. function bstoslash(const s : string) : string;
  266. {
  267. return string s with all \ changed into /
  268. }
  269. var
  270. i : longint;
  271. begin
  272. for i:=1to length(s) do
  273. if s[i]='\' then
  274. bstoslash[i]:='/'
  275. else
  276. bstoslash[i]:=s[i];
  277. {$ifndef TP}
  278. {$ifopt H+}
  279. setlength(bstoslash,length(s));
  280. {$else}
  281. bstoslash[0]:=s[0];
  282. {$endif}
  283. {$else}
  284. bstoslash[0]:=s[0];
  285. {$endif}
  286. end;
  287. {$ifdef debug}
  288. function assigned(p : pointer) : boolean;
  289. {$ifndef FPC}
  290. {$ifndef DPMI}
  291. type
  292. ptrrec = record
  293. ofs,seg : word;
  294. end;
  295. var
  296. lp : longint;
  297. {$endif DPMI}
  298. {$endif FPC}
  299. begin
  300. {$ifdef FPC}
  301. { Assigned is used for procvar and
  302. stack stored temp records !! PM }
  303. (* if (p<>nil) {and
  304. ((p<heaporg) or
  305. (p>heapptr))} then
  306. do_internalerror(230); *)
  307. {$else}
  308. {$ifdef DPMI}
  309. assigned:=(p<>nil);
  310. exit;
  311. {$else DPMI}
  312. if p=nil then
  313. lp:=0
  314. else
  315. lp:=longint(ptrrec(p).seg)*16+longint(ptrrec(p).ofs);
  316. if (lp<>0) and
  317. ((lp<longint(seg(heaporg^))*16+longint(ofs(heaporg^))) or
  318. (lp>longint(seg(heapptr^))*16+longint(ofs(heapptr^)))) then
  319. do_internalerror(230);
  320. {$endif DPMI}
  321. {$endif FPC}
  322. assigned:=(p<>nil);
  323. end;
  324. {$endif}
  325. function min(a,b : longint) : longint;
  326. {
  327. return the minimal of a and b
  328. }
  329. begin
  330. if a>b then
  331. min:=b
  332. else
  333. min:=a;
  334. end;
  335. function max(a,b : longint) : longint;
  336. {
  337. return the maximum of a and b
  338. }
  339. begin
  340. if a<b then
  341. max:=b
  342. else
  343. max:=a;
  344. end;
  345. function align(i,a:longint):longint;
  346. {
  347. return value <i> aligned <a> boundary
  348. }
  349. begin
  350. align:=(i+a-1) and not(a-1);
  351. end;
  352. procedure Replace(var s:string;s1:string;const s2:string);
  353. var
  354. last,
  355. i : longint;
  356. begin
  357. s1:=upper(s1);
  358. last:=0;
  359. repeat
  360. i:=pos(s1,upper(s));
  361. if i=last then
  362. i:=0;
  363. if (i>0) then
  364. begin
  365. Delete(s,i,length(s1));
  366. Insert(s2,s,i);
  367. last:=i;
  368. end;
  369. until (i=0);
  370. end;
  371. procedure ReplaceCase(var s:string;const s1,s2:string);
  372. var
  373. last,
  374. i : longint;
  375. begin
  376. last:=0;
  377. repeat
  378. i:=pos(s1,s);
  379. if i=last then
  380. i:=0;
  381. if (i>0) then
  382. begin
  383. Delete(s,i,length(s1));
  384. Insert(s2,s,i);
  385. last:=i;
  386. end;
  387. until (i=0);
  388. end;
  389. function upper(const s : string) : string;
  390. {
  391. return uppercased string of s
  392. }
  393. var
  394. i : longint;
  395. begin
  396. for i:=1 to length(s) do
  397. if s[i] in ['a'..'z'] then
  398. upper[i]:=char(byte(s[i])-32)
  399. else
  400. upper[i]:=s[i];
  401. upper[0]:=s[0];
  402. end;
  403. function lower(const s : string) : string;
  404. {
  405. return lowercased string of s
  406. }
  407. var
  408. i : longint;
  409. begin
  410. for i:=1 to length(s) do
  411. if s[i] in ['A'..'Z'] then
  412. lower[i]:=char(byte(s[i])+32)
  413. else
  414. lower[i]:=s[i];
  415. lower[0]:=s[0];
  416. end;
  417. procedure uppervar(var s : string);
  418. {
  419. uppercase string s
  420. }
  421. var
  422. i : longint;
  423. begin
  424. for i:=1 to length(s) do
  425. if s[i] in ['a'..'z'] then
  426. s[i]:=char(byte(s[i])-32);
  427. end;
  428. {$ifdef FPC}
  429. function tostru(i:cardinal):string;
  430. {
  431. return string of value i, but for cardinals
  432. }
  433. var
  434. hs : string;
  435. begin
  436. str(i,hs);
  437. tostru:=hs;
  438. end;
  439. {$else FPC}
  440. function tostru(i:longint):string;
  441. begin
  442. tostru:=tostr(i);
  443. end;
  444. {$endif FPC}
  445. function trimspace(const s:string):string;
  446. {
  447. return s with all leading and ending spaces and tabs removed
  448. }
  449. var
  450. i,j : longint;
  451. begin
  452. i:=length(s);
  453. while (i>0) and (s[i] in [#9,' ']) do
  454. dec(i);
  455. j:=1;
  456. while (j<i) and (s[j] in [#9,' ']) do
  457. inc(j);
  458. trimspace:=Copy(s,j,i-j+1);
  459. end;
  460. function tostr(i : longint) : string;
  461. {
  462. return string of value i
  463. }
  464. var
  465. hs : string;
  466. begin
  467. str(i,hs);
  468. tostr:=hs;
  469. end;
  470. function tostr_with_plus(i : longint) : string;
  471. {
  472. return string of value i, but always include a + when i>=0
  473. }
  474. var
  475. hs : string;
  476. begin
  477. str(i,hs);
  478. if i>=0 then
  479. tostr_with_plus:='+'+hs
  480. else
  481. tostr_with_plus:=hs;
  482. end;
  483. procedure valint(S : string;var V : longint;var code : integer);
  484. {
  485. val() with support for octal, which is not supported under tp7
  486. }
  487. {$ifndef FPC}
  488. var
  489. vs : longint;
  490. c : byte;
  491. begin
  492. if s[1]='%' then
  493. begin
  494. vs:=0;
  495. longint(v):=0;
  496. for c:=2 to length(s) do
  497. begin
  498. if s[c]='0' then
  499. vs:=vs shl 1
  500. else
  501. if s[c]='1' then
  502. vs:=vs shl 1+1
  503. else
  504. begin
  505. code:=c;
  506. exit;
  507. end;
  508. end;
  509. code:=0;
  510. longint(v):=vs;
  511. end
  512. else
  513. system.val(S,V,code);
  514. end;
  515. {$else not FPC}
  516. begin
  517. system.val(S,V,code);
  518. end;
  519. {$endif not FPC}
  520. function is_number(const s : string) : boolean;
  521. {
  522. is string a correct number ?
  523. }
  524. var
  525. w : integer;
  526. l : longint;
  527. begin
  528. valint(s,l,w);
  529. is_number:=(w=0);
  530. end;
  531. function ispowerof2(value : longint;var power : longint) : boolean;
  532. {
  533. return if value is a power of 2. And if correct return the power
  534. }
  535. var
  536. hl : longint;
  537. i : longint;
  538. begin
  539. hl:=1;
  540. ispowerof2:=true;
  541. for i:=0 to 31 do
  542. begin
  543. if hl=value then
  544. begin
  545. power:=i;
  546. exit;
  547. end;
  548. hl:=hl shl 1;
  549. end;
  550. ispowerof2:=false;
  551. end;
  552. { enable ansistring comparison }
  553. { 0 means equal }
  554. { 1 means p1 > p2 }
  555. { -1 means p1 < p2 }
  556. function compareansistrings(p1,p2 : pchar;length1,length2 : longint) : longint;
  557. var
  558. i,j : longint;
  559. begin
  560. compareansistrings:=0;
  561. j:=min(length1,length2);
  562. i:=0;
  563. while (i<j) do
  564. begin
  565. if p1[i]>p2[i] then
  566. begin
  567. compareansistrings:=1;
  568. exit;
  569. end
  570. else
  571. if p1[i]<p2[i] then
  572. begin
  573. compareansistrings:=-1;
  574. exit;
  575. end;
  576. inc(i);
  577. end;
  578. if length1>length2 then
  579. compareansistrings:=1
  580. else
  581. if length1<length2 then
  582. compareansistrings:=-1;
  583. end;
  584. function concatansistrings(p1,p2 : pchar;length1,length2 : longint) : pchar;
  585. var
  586. p : pchar;
  587. begin
  588. getmem(p,length1+length2+1);
  589. move(p1[0],p[0],length1);
  590. move(p2[0],p[length1],length2+1);
  591. concatansistrings:=p;
  592. end;
  593. {****************************************************************************
  594. Time Handling
  595. ****************************************************************************}
  596. Function L0(l:longint):string;
  597. {
  598. return the string of value l, if l<10 then insert a zero, so
  599. the string is always at least 2 chars '01','02',etc
  600. }
  601. var
  602. s : string;
  603. begin
  604. Str(l,s);
  605. if l<10 then
  606. s:='0'+s;
  607. L0:=s;
  608. end;
  609. function gettimestr:string;
  610. {
  611. get the current time in a string HH:MM:SS
  612. }
  613. var
  614. hour,min,sec,hsec : word;
  615. begin
  616. {$ifdef delphi}
  617. dmisc.gettime(hour,min,sec,hsec);
  618. {$else delphi}
  619. dos.gettime(hour,min,sec,hsec);
  620. {$endif delphi}
  621. gettimestr:=L0(Hour)+':'+L0(min)+':'+L0(sec);
  622. end;
  623. function getdatestr:string;
  624. {
  625. get the current date in a string YY/MM/DD
  626. }
  627. var
  628. Year,Month,Day,Wday : Word;
  629. begin
  630. {$ifdef delphi}
  631. dmisc.getdate(year,month,day,wday);
  632. {$else}
  633. dos.getdate(year,month,day,wday);
  634. {$endif}
  635. getdatestr:=L0(Year)+'/'+L0(Month)+'/'+L0(Day);
  636. end;
  637. function filetimestring( t : longint) : string;
  638. {
  639. convert dos datetime t to a string YY/MM/DD HH:MM:SS
  640. }
  641. var
  642. {$ifndef linux}
  643. DT : DateTime;
  644. {$endif}
  645. Year,Month,Day,Hour,Min,Sec : Word;
  646. begin
  647. if t=-1 then
  648. begin
  649. FileTimeString:='Not Found';
  650. exit;
  651. end;
  652. {$ifndef linux}
  653. unpacktime(t,DT);
  654. Year:=dT.year;month:=dt.month;day:=dt.day;
  655. Hour:=dt.hour;min:=dt.min;sec:=dt.sec;
  656. {$else}
  657. EpochToLocal (t,year,month,day,hour,min,sec);
  658. {$endif}
  659. filetimestring:=L0(Year)+'/'+L0(Month)+'/'+L0(Day)+' '+L0(Hour)+':'+L0(min)+':'+L0(sec);
  660. end;
  661. {****************************************************************************
  662. Default Macro Handling
  663. ****************************************************************************}
  664. procedure DefaultReplacements(var s:string);
  665. begin
  666. { Replace some macro's }
  667. Replace(s,'$FPCVER',full_version_string);
  668. Replace(s,'$FPCDATE',date_string);
  669. Replace(s,'$FPCTARGET',target_cpu_string);
  670. Replace(s,'$FPCCPU',target_cpu_string);
  671. Replace(s,'$TARGET',target_path);
  672. Replace(s,'$FPCOS',target_path);
  673. end;
  674. {****************************************************************************
  675. File Handling
  676. ****************************************************************************}
  677. function path_absolute(const s : string) : boolean;
  678. {
  679. is path s an absolute path?
  680. }
  681. begin
  682. path_absolute:=false;
  683. {$ifdef linux}
  684. if (length(s)>0) and (s[1]='/') then
  685. path_absolute:=true;
  686. {$else linux}
  687. {$ifdef amiga}
  688. if ((length(s)>0) and ((s[1]='\') or (s[1]='/'))) or (Pos(':',s) = length(s)) then
  689. path_absolute:=true;
  690. {$else}
  691. if ((length(s)>0) and ((s[1]='\') or (s[1]='/'))) or
  692. ((length(s)>2) and (s[2]=':') and ((s[3]='\') or (s[3]='/'))) then
  693. path_absolute:=true;
  694. {$endif amiga}
  695. {$endif linux}
  696. end;
  697. {$ifndef FPC}
  698. Procedure FindClose(var Info : SearchRec);
  699. Begin
  700. End;
  701. {$endif not FPC}
  702. {$ifdef delphi}
  703. Function FileExists ( Const F : String) : Boolean;
  704. begin
  705. FileExists:=sysutils.FileExists(f);
  706. end;
  707. {$else}
  708. Function FileExists ( Const F : String) : Boolean;
  709. Var
  710. {$ifdef linux}
  711. Info : Stat;
  712. {$else}
  713. Info : SearchRec;
  714. {$endif}
  715. begin
  716. {$ifdef linux}
  717. FileExists:=FStat(F,info);
  718. {$else}
  719. findfirst(F,readonly+archive+hidden,info);
  720. FileExists:=(doserror=0);
  721. findclose(Info);
  722. {$endif}
  723. end;
  724. {$endif}
  725. Function RemoveFile(const f:string):boolean;
  726. var
  727. g : file;
  728. begin
  729. assign(g,f);
  730. {$I-}
  731. erase(g);
  732. {$I+}
  733. RemoveFile:=(ioresult=0);
  734. end;
  735. Function RemoveDir(d:string):boolean;
  736. begin
  737. if d[length(d)]=DirSep then
  738. Delete(d,length(d),1);
  739. {$I-}
  740. rmdir(d);
  741. {$I+}
  742. RemoveDir:=(ioresult=0);
  743. end;
  744. Function SplitFileName(const s:string):string;
  745. var
  746. p : dirstr;
  747. n : namestr;
  748. e : extstr;
  749. begin
  750. FSplit(s,p,n,e);
  751. SplitFileName:=n+e;
  752. end;
  753. Function SplitName(const s:string):string;
  754. var
  755. i,j : longint;
  756. begin
  757. i:=Length(s);
  758. j:=Length(s);
  759. while (i>0) and not(s[i] in ['/','\']) do
  760. dec(i);
  761. while (j>0) and (s[j]<>'.') do
  762. dec(j);
  763. if j<=i then
  764. j:=255;
  765. SplitName:=Copy(s,i+1,j-(i+1));
  766. end;
  767. Function SplitExtension(Const HStr:String):String;
  768. var
  769. j : longint;
  770. begin
  771. j:=length(Hstr);
  772. while (j>0) and (Hstr[j]<>'.') do
  773. begin
  774. if hstr[j]=DirSep then
  775. j:=0
  776. else
  777. dec(j);
  778. end;
  779. if j=0 then
  780. j:=254;
  781. SplitExtension:=Copy(Hstr,j,255);
  782. end;
  783. Function AddExtension(Const HStr,ext:String):String;
  784. begin
  785. if (Ext<>'') and (SplitExtension(HStr)='') then
  786. AddExtension:=Hstr+Ext
  787. else
  788. AddExtension:=Hstr;
  789. end;
  790. Function ForceExtension(Const HStr,ext:String):String;
  791. var
  792. j : longint;
  793. begin
  794. j:=length(Hstr);
  795. while (j>0) and (Hstr[j]<>'.') do
  796. dec(j);
  797. if j=0 then
  798. j:=255;
  799. ForceExtension:=Copy(Hstr,1,j-1)+Ext;
  800. end;
  801. Function FixPath(s:string;allowdot:boolean):string;
  802. var
  803. i : longint;
  804. begin
  805. { Fix separator }
  806. for i:=1 to length(s) do
  807. if s[i] in ['/','\'] then
  808. s[i]:=DirSep;
  809. { Fix ending / }
  810. if (length(s)>0) and (s[length(s)]<>DirSep) and
  811. (s[length(s)]<>':') then
  812. s:=s+DirSep;
  813. { Remove ./ }
  814. if (not allowdot) and (s='.'+DirSep) then
  815. s:='';
  816. { return }
  817. FixPath:=s;
  818. end;
  819. function FixFileName(const s:string):string;
  820. var
  821. i : longint;
  822. {$ifdef Linux}
  823. NoPath : boolean;
  824. {$endif Linux}
  825. begin
  826. {$ifdef Linux}
  827. NoPath:=true;
  828. {$endif Linux}
  829. for i:=length(s) downto 1 do
  830. begin
  831. case s[i] of
  832. {$ifdef Linux}
  833. '/','\' : begin
  834. FixFileName[i]:='/';
  835. NoPath:=false; {Skip lowercasing path: 'X11'<>'x11' }
  836. end;
  837. 'A'..'Z' : if NoPath then
  838. FixFileName[i]:=char(byte(s[i])+32)
  839. else
  840. FixFileName[i]:=s[i];
  841. {$else}
  842. '/' : FixFileName[i]:='\';
  843. 'A'..'Z' : FixFileName[i]:=char(byte(s[i])+32);
  844. {$endif}
  845. else
  846. FixFileName[i]:=s[i];
  847. end;
  848. end;
  849. {$ifndef TP}
  850. {$ifopt H+}
  851. SetLength(FixFileName,length(s));
  852. {$else}
  853. FixFileName[0]:=s[0];
  854. {$endif}
  855. {$else}
  856. FixFileName[0]:=s[0];
  857. {$endif}
  858. end;
  859. procedure SplitBinCmd(const s:string;var bstr,cstr:string);
  860. var
  861. i : longint;
  862. begin
  863. i:=pos(' ',s);
  864. if i>0 then
  865. begin
  866. bstr:=Copy(s,1,i-1);
  867. cstr:=Copy(s,i+1,length(s)-i);
  868. end
  869. else
  870. begin
  871. bstr:='';
  872. cstr:='';
  873. end;
  874. end;
  875. procedure TSearchPathList.AddPath(s:string;addfirst:boolean);
  876. var
  877. j : longint;
  878. CurrentDir,
  879. CurrPath : string;
  880. hp : PStringQueueItem;
  881. begin
  882. if s='' then
  883. exit;
  884. { Support default macro's }
  885. DefaultReplacements(s);
  886. { get current dir }
  887. GetDir(0,CurrentDir);
  888. CurrentDir:=FixPath(CurrentDir,false);
  889. repeat
  890. j:=Pos(';',s);
  891. if j=0 then
  892. j:=255;
  893. {Get Pathname}
  894. CurrPath:=FixPath(Copy(s,1,j-1),false);
  895. if CurrPath='' then
  896. CurrPath:='.'+DirSep
  897. else
  898. begin
  899. CurrPath:=FixPath(FExpand(CurrPath),false);
  900. if (Copy(CurrPath,1,length(CurrentDir))=CurrentDir) then
  901. CurrPath:='.'+DirSep+Copy(CurrPath,length(CurrentDir)+1,255);
  902. end;
  903. System.Delete(s,1,j);
  904. if addfirst then
  905. begin
  906. Delete(currPath);
  907. Insert(currPath);
  908. end
  909. else
  910. begin
  911. { Check if already in path, then we don't add it }
  912. hp:=Find(currPath);
  913. if not assigned(hp) then
  914. Concat(currPath);
  915. end;
  916. until (s='');
  917. end;
  918. procedure TSearchPathList.AddList(list:TSearchPathList;addfirst:boolean);
  919. var
  920. s : string;
  921. hl : TSearchPathList;
  922. hp,hp2 : PStringQueueItem;
  923. begin
  924. if list.empty then
  925. exit;
  926. { create temp and reverse the list }
  927. if addfirst then
  928. begin
  929. hl.Init;
  930. hp:=list.first;
  931. while assigned(hp) do
  932. begin
  933. hl.insert(hp^.data^);
  934. hp:=hp^.next;
  935. end;
  936. while not hl.empty do
  937. begin
  938. s:=hl.Get;
  939. Delete(s);
  940. Insert(s);
  941. end;
  942. hl.done;
  943. end
  944. else
  945. begin
  946. hp:=list.first;
  947. while assigned(hp) do
  948. begin
  949. hp2:=Find(hp^.data^);
  950. { Check if already in path, then we don't add it }
  951. if not assigned(hp2) then
  952. Concat(hp^.data^);
  953. hp:=hp^.next;
  954. end;
  955. end;
  956. end;
  957. function TSearchPathList.FindFile(const f : string;var b : boolean) : string;
  958. Var
  959. p : PStringQueueItem;
  960. begin
  961. FindFile:='';
  962. b:=false;
  963. p:=first;
  964. while assigned(p) do
  965. begin
  966. If FileExists(p^.data^+f) then
  967. begin
  968. FindFile:=p^.data^;
  969. b:=true;
  970. exit;
  971. end;
  972. p:=p^.next;
  973. end;
  974. end;
  975. Function GetFileTime ( Var F : File) : Longint;
  976. Var
  977. {$ifdef linux}
  978. Info : Stat;
  979. {$endif}
  980. L : longint;
  981. begin
  982. {$ifdef linux}
  983. FStat (F,Info);
  984. L:=Info.Mtime;
  985. {$else}
  986. GetFTime(f,l);
  987. {$endif}
  988. GetFileTime:=L;
  989. end;
  990. Function GetNamedFileTime (Const F : String) : Longint;
  991. var
  992. L : Longint;
  993. {$ifndef linux}
  994. info : SearchRec;
  995. {$else}
  996. info : stat;
  997. {$endif}
  998. begin
  999. l:=-1;
  1000. {$ifdef linux}
  1001. if FStat (F,Info) then
  1002. L:=info.mtime;
  1003. {$else}
  1004. {$ifdef delphi}
  1005. dmisc.FindFirst (F,archive+readonly+hidden,info);
  1006. {$else delphi}
  1007. FindFirst (F,archive+readonly+hidden,info);
  1008. {$endif delphi}
  1009. if DosError=0 then
  1010. l:=info.time;
  1011. {$ifdef Linux}
  1012. FindClose(info);
  1013. {$endif}
  1014. {$ifdef Win32}
  1015. FindClose(info);
  1016. {$endif}
  1017. {$endif}
  1018. GetNamedFileTime:=l;
  1019. end;
  1020. {Touch Assembler and object time to ppu time is there is a ppufilename}
  1021. procedure SynchronizeFileTime(const fn1,fn2:string);
  1022. var
  1023. f : file;
  1024. l : longint;
  1025. begin
  1026. Assign(f,fn1);
  1027. {$I-}
  1028. reset(f,1);
  1029. {$I+}
  1030. if ioresult=0 then
  1031. begin
  1032. getftime(f,l);
  1033. close(f);
  1034. assign(f,fn2);
  1035. {$I-}
  1036. reset(f,1);
  1037. {$I+}
  1038. if ioresult=0 then
  1039. begin
  1040. setftime(f,l);
  1041. close(f);
  1042. end;
  1043. end;
  1044. end;
  1045. function FindFile(const f : string;path : string;var b : boolean) : string;
  1046. Var
  1047. singlepathstring : string;
  1048. i : longint;
  1049. begin
  1050. {$ifdef linux}
  1051. for i:=1 to length(path) do
  1052. if path[i]=':' then
  1053. path[i]:=';';
  1054. {$endif}
  1055. b:=false;
  1056. FindFile:='';
  1057. repeat
  1058. i:=pos(';',path);
  1059. if i=0 then
  1060. i:=255;
  1061. singlepathstring:=FixPath(copy(path,1,i-1),false);
  1062. delete(path,1,i);
  1063. If FileExists (singlepathstring+f) then
  1064. begin
  1065. FindFile:=singlepathstring;
  1066. b:=true;
  1067. exit;
  1068. end;
  1069. until path='';
  1070. end;
  1071. function FindExe(bin:string;var found:boolean):string;
  1072. begin
  1073. bin:=FixFileName(bin)+source_os.exeext;
  1074. {$ifdef delphi}
  1075. FindExe:=FindFile(bin,'.;'+exepath+';'+dmisc.getenv('PATH'),found)+bin;
  1076. {$else delphi}
  1077. FindExe:=FindFile(bin,'.;'+exepath+';'+dos.getenv('PATH'),found)+bin;
  1078. {$endif delphi}
  1079. end;
  1080. function GetShortName(const n:string):string;
  1081. {$ifdef win32}
  1082. var
  1083. hs,hs2 : string;
  1084. {$endif}
  1085. {$ifdef go32v2}
  1086. var
  1087. hs : string;
  1088. {$endif}
  1089. begin
  1090. GetShortName:=n;
  1091. {$ifdef win32}
  1092. hs:=n+#0;
  1093. Windows.GetShortPathName(@hs[1],@hs2[1],high(hs2));
  1094. hs2[0]:=chr(strlen(@hs2[1]));
  1095. GetShortName:=hs2;
  1096. {$endif}
  1097. {$ifdef go32v2}
  1098. hs:=n;
  1099. if Dos.GetShortName(hs) then
  1100. GetShortName:=hs;
  1101. {$endif}
  1102. end;
  1103. {****************************************************************************
  1104. OS Dependent things
  1105. ****************************************************************************}
  1106. function GetEnvPChar(const envname:string):pchar;
  1107. {$ifdef win32}
  1108. var
  1109. s : string;
  1110. i,len : longint;
  1111. hp,p,p2 : pchar;
  1112. {$endif}
  1113. begin
  1114. {$ifdef linux}
  1115. GetEnvPchar:=Linux.Getenv(envname);
  1116. {$define GETENVOK}
  1117. {$endif}
  1118. {$ifdef win32}
  1119. GetEnvPchar:=nil;
  1120. p:=GetEnvironmentStrings;
  1121. hp:=p;
  1122. while hp^<>#0 do
  1123. begin
  1124. s:=strpas(hp);
  1125. i:=pos('=',s);
  1126. len:=strlen(hp);
  1127. if upcase(copy(s,1,i-1))=upcase(envname) then
  1128. begin
  1129. GetMem(p2,len-length(envname));
  1130. Move(hp[i],p2^,len-length(envname));
  1131. GetEnvPchar:=p2;
  1132. break;
  1133. end;
  1134. { next string entry}
  1135. hp:=hp+len+1;
  1136. end;
  1137. FreeEnvironmentStrings(p);
  1138. {$define GETENVOK}
  1139. {$endif}
  1140. {$ifdef GETENVOK}
  1141. {$undef GETENVOK}
  1142. {$else}
  1143. GetEnvPchar:=StrPNew(Dos.Getenv(envname));
  1144. {$endif}
  1145. end;
  1146. procedure FreeEnvPChar(p:pchar);
  1147. begin
  1148. {$ifndef linux}
  1149. StrDispose(p);
  1150. {$endif}
  1151. end;
  1152. Procedure Shell(const command:string);
  1153. { This is already defined in the linux.ppu for linux, need for the *
  1154. expansion under linux }
  1155. {$ifdef linux}
  1156. begin
  1157. Linux.Shell(command);
  1158. end;
  1159. {$else}
  1160. var
  1161. comspec : string;
  1162. begin
  1163. comspec:=getenv('COMSPEC');
  1164. Exec(comspec,' /C '+command);
  1165. end;
  1166. {$endif}
  1167. {****************************************************************************
  1168. Init
  1169. ****************************************************************************}
  1170. procedure get_exepath;
  1171. var
  1172. hs1 : namestr;
  1173. hs2 : extstr;
  1174. begin
  1175. {$ifdef delphi}
  1176. exepath:=dmisc.getenv('PPC_EXEC_PATH');
  1177. {$else delphi}
  1178. exepath:=dos.getenv('PPC_EXEC_PATH');
  1179. {$endif delphi}
  1180. if exepath='' then
  1181. fsplit(FixFileName(paramstr(0)),exepath,hs1,hs2);
  1182. {$ifdef linux}
  1183. if exepath='' then
  1184. fsearch(hs1,dos.getenv('PATH'));
  1185. {$endif}
  1186. exepath:=FixPath(exepath,false);
  1187. end;
  1188. procedure DoneGlobals;
  1189. begin
  1190. initdefines.done;
  1191. if assigned(DLLImageBase) then
  1192. StringDispose(DLLImageBase);
  1193. RelocSection:=true;
  1194. RelocSectionSetExplicitly:=false;
  1195. DLLsource:=false;
  1196. UseDeffileForExport:=true;
  1197. librarysearchpath.Done;
  1198. unitsearchpath.Done;
  1199. objectsearchpath.Done;
  1200. includesearchpath.Done;
  1201. end;
  1202. procedure InitGlobals;
  1203. begin
  1204. { set global switches }
  1205. do_build:=false;
  1206. do_make:=true;
  1207. {$ifdef tp}
  1208. use_big:=false;
  1209. {$endif tp}
  1210. compile_level:=0;
  1211. { Output }
  1212. OutputFile:='';
  1213. OutputExeDir:='';
  1214. OutputUnitDir:='';
  1215. { Utils directory }
  1216. utilsdirectory:='';
  1217. { Search Paths }
  1218. librarysearchpath.Init;
  1219. unitsearchpath.Init;
  1220. includesearchpath.Init;
  1221. objectsearchpath.Init;
  1222. { Def file }
  1223. usewindowapi:=false;
  1224. description:='Compiled by FPC '+version_string+' - '+target_cpu_string;
  1225. dllversion:='';
  1226. { Init values }
  1227. initmodeswitches:=fpcmodeswitches;
  1228. initlocalswitches:=[cs_check_io];
  1229. initmoduleswitches:=[cs_extsyntax,cs_browser];
  1230. initglobalswitches:=[cs_check_unit_name,cs_link_static];
  1231. {$ifdef i386}
  1232. initoptprocessor:=Class386;
  1233. initpackenum:=4;
  1234. initpackrecords:=packrecord_2;
  1235. initoutputformat:=target_asm.id;
  1236. initasmmode:=asmmode_i386_att;
  1237. {$else not i386}
  1238. {$ifdef m68k}
  1239. initoptprocessor:=MC68000;
  1240. include(initmoduleswitches,cs_fp_emulation);
  1241. initpackenum:=4;
  1242. initpackrecords:=packrecord_2;
  1243. initoutputformat:=as_m68k_as;
  1244. initasmmode:=asmmode_m68k_mot;
  1245. {$endif m68k}
  1246. {$endif i386}
  1247. initdefines.init;
  1248. { memory sizes, will be overriden by parameter or default for target
  1249. in options or init_parser }
  1250. stacksize:=0;
  1251. heapsize:=0;
  1252. maxheapsize:=0;
  1253. { compile state }
  1254. in_args:=false;
  1255. { must_be_valid:=true; obsolete PM }
  1256. not_unit_proc:=true;
  1257. apptype:=at_cui;
  1258. end;
  1259. begin
  1260. get_exepath;
  1261. {$ifdef EXTDEBUG}
  1262. {$ifdef FPC}
  1263. EntryMemUsed:=system.HeapSize-MemAvail;
  1264. {$endif FPC}
  1265. {$endif}
  1266. end.
  1267. {
  1268. $Log$
  1269. Revision 1.40 1999-12-20 21:42:34 pierre
  1270. + dllversion global variable
  1271. * FPC_USE_CPREFIX code removed, not necessary anymore
  1272. as we use .edata direct writing by default now.
  1273. Revision 1.39 1999/12/08 10:40:00 pierre
  1274. + allow use of unit var in exports of DLL for win32
  1275. by using direct export writing by default instead of use of DEFFILE
  1276. that does not allow assembler labels that do not
  1277. start with an underscore.
  1278. Use -WD to force use of Deffile for Win32 DLL
  1279. Revision 1.38 1999/12/06 18:21:03 peter
  1280. * support !ENVVAR for long commandlines
  1281. * win32/go32v2 write short pathnames to link.res so c:\Program Files\ is
  1282. finally supported as installdir.
  1283. Revision 1.37 1999/12/02 17:34:34 peter
  1284. * preprocessor support. But it fails on the caret in type blocks
  1285. Revision 1.36 1999/11/18 15:34:45 pierre
  1286. * Notes/Hints for local syms changed to
  1287. Set_varstate function
  1288. Revision 1.35 1999/11/17 17:04:59 pierre
  1289. * Notes/hints changes
  1290. Revision 1.34 1999/11/15 17:42:41 pierre
  1291. * -g disables reloc section for win32
  1292. Revision 1.33 1999/11/12 11:03:50 peter
  1293. * searchpaths changed to stringqueue object
  1294. Revision 1.32 1999/11/09 23:34:46 pierre
  1295. + resolving_forward boolean used for references
  1296. Revision 1.31 1999/11/09 13:00:38 peter
  1297. * define FPC_DELPHI,FPC_OBJFPC,FPC_TP,FPC_GPC
  1298. * initial support for ansistring default with modes
  1299. Revision 1.30 1999/11/08 16:27:20 pierre
  1300. + Reset AnsiStrings to clean up memory
  1301. Revision 1.29 1999/11/06 14:34:20 peter
  1302. * truncated log to 20 revs
  1303. Revision 1.28 1999/11/04 10:55:31 peter
  1304. * TSearchPathList for the string type of the searchpaths, which is
  1305. ansistring under FPC/Delphi
  1306. Revision 1.27 1999/10/26 12:30:41 peter
  1307. * const parameter is now checked
  1308. * better and generic check if a node can be used for assigning
  1309. * export fixes
  1310. * procvar equal works now (it never had worked at least from 0.99.8)
  1311. * defcoll changed to linkedlist with pparaitem so it can easily be
  1312. walked both directions
  1313. Revision 1.26 1999/10/21 14:29:34 peter
  1314. * redesigned linker object
  1315. + library support for linux (only procedures can be exported)
  1316. Revision 1.25 1999/09/10 18:48:02 florian
  1317. * some bug fixes (e.g. must_be_valid and procinfo.funcret_is_valid)
  1318. * most things for stored properties fixed
  1319. Revision 1.24 1999/09/08 16:05:31 peter
  1320. * pointer add/sub is now as expected and the same results as inc/dec
  1321. Revision 1.23 1999/09/07 15:11:00 pierre
  1322. * use do_internalerror insetead of runerror
  1323. Revision 1.22 1999/08/30 10:17:56 peter
  1324. * fixed crash in psub
  1325. * ansistringcompare fixed
  1326. * support for #$0b8
  1327. Revision 1.21 1999/08/27 10:45:00 pierre
  1328. options -Ca sets simply_ppu to true
  1329. Revision 1.20 1999/08/19 13:02:12 pierre
  1330. + label faillabel added for _FAIL support
  1331. Revision 1.19 1999/08/16 15:35:21 pierre
  1332. * fix for DLL relocation problems
  1333. * external bss vars had wrong stabs for pecoff
  1334. + -WB11000000 to specify default image base, allows to
  1335. load several DLLs with debugging info included
  1336. (relocatable DLL are stripped because the relocation
  1337. of the .Stab section is misplaced by ldw)
  1338. Revision 1.18 1999/08/11 17:26:32 peter
  1339. * tlinker object is now inherited for win32 and dos
  1340. * postprocessexecutable is now a method of tlinker
  1341. Revision 1.17 1999/08/10 12:51:14 pierre
  1342. * bind_win32_dll removed (Relocsection used instead)
  1343. * now relocsection is true by default ! (needs dlltool
  1344. for DLL generation)
  1345. Revision 1.16 1999/08/05 20:54:19 daniel
  1346. * Changes for new symtable.
  1347. Revision 1.15 1999/08/03 17:09:35 florian
  1348. * the alpha compiler can be compiled now
  1349. Revision 1.14 1999/07/23 16:05:19 peter
  1350. * alignment is now saved in the symtable
  1351. * C alignment added for records
  1352. * PPU version increased to solve .12 <-> .13 probs
  1353. Revision 1.13 1999/07/18 10:19:52 florian
  1354. * made it compilable with Dlephi 4 again
  1355. + fixed problem with large stack allocations on win32
  1356. Revision 1.12 1999/07/13 19:14:44 michael
  1357. + Defaultreplacemens now more logical
  1358. Revision 1.11 1999/07/10 10:26:18 peter
  1359. * merged
  1360. Revision 1.8.2.2 1999/07/10 10:03:04 peter
  1361. * fixed initialization/finalization in fpc mode
  1362. * allow $TARGET also in search paths
  1363. Revision 1.8.2.1 1999/07/07 07:53:21 michael
  1364. + Merged patches from florian
  1365. }