globals.pas 38 KB

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