cutils.pas 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. This unit implements some support functions
  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
  7. by 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. {# This unit contains some generic support functions which are used
  19. in the different parts of the compiler.
  20. }
  21. unit cutils;
  22. {$i fpcdefs.inc}
  23. interface
  24. type
  25. pstring = ^string;
  26. {# Returns the minimal value between @var(a) and @var(b) }
  27. function min(a,b : longint) : longint;
  28. {# Returns the maximum value between @var(a) and @var(b) }
  29. function max(a,b : longint) : longint;
  30. {# Returns the value in @var(x) swapped to different endian }
  31. function SwapLong(x : longint): longint;
  32. {# Returns the value in @va(x) swapped to different endian }
  33. function SwapWord(x : word): word;
  34. {# Return value @var(i) aligned on @var(a) boundary }
  35. function align(i,a:longint):longint;
  36. function used_align(varalign,minalign,maxalign:longint):longint;
  37. function size_2_align(len : longint) : longint;
  38. procedure Replace(var s:string;s1:string;const s2:string);
  39. procedure ReplaceCase(var s:string;const s1,s2:string);
  40. function upper(const s : string) : string;
  41. function lower(const s : string) : string;
  42. function trimbspace(const s:string):string;
  43. function trimspace(const s:string):string;
  44. function space (b : longint): string;
  45. function PadSpace(const s:string;len:longint):string;
  46. function GetToken(var s:string;endchar:char):string;
  47. procedure uppervar(var s : string);
  48. function hexstr(val : cardinal;cnt : cardinal) : string;
  49. function tostru(i:cardinal) : string;
  50. function tostr(i : longint) : string;
  51. function int64tostr(i : int64) : string;
  52. function tostr_with_plus(i : longint) : string;
  53. function DStr(l:longint):string;
  54. procedure valint(S : string;var V : longint;var code : integer);
  55. {# Returns true if the string s is a number }
  56. function is_number(const s : string) : boolean;
  57. {# Returns true if value is a power of 2, the actual
  58. exponent value is returned in power.
  59. }
  60. function ispowerof2(value : int64;var power : longint) : boolean;
  61. function maybequoted(const s:string):string;
  62. function CompareText(S1, S2: string): longint;
  63. { releases the string p and assignes nil to p }
  64. { if p=nil then freemem isn't called }
  65. procedure stringdispose(var p : pstring);
  66. { allocates mem for a copy of s, copies s to this mem and returns }
  67. { a pointer to this mem }
  68. function stringdup(const s : string) : pstring;
  69. {# Allocates memory for the string @var(s) and copies s as zero
  70. terminated string to that allocated memory and returns a pointer
  71. to that mem
  72. }
  73. function strpnew(const s : string) : pchar;
  74. procedure strdispose(var p : pchar);
  75. {# makes the character @var(c) lowercase, with spanish, french and german
  76. character set
  77. }
  78. function lowercase(c : char) : char;
  79. { makes zero terminated string to a pascal string }
  80. { the data in p is modified and p is returned }
  81. function pchar2pstring(p : pchar) : pstring;
  82. { ambivalent to pchar2pstring }
  83. function pstring2pchar(p : pstring) : pchar;
  84. { Speed/Hash value }
  85. Function GetSpeedValue(Const s:String):cardinal;
  86. { Ansistring (pchar+length) support }
  87. procedure ansistringdispose(var p : pchar;length : longint);
  88. function compareansistrings(p1,p2 : pchar;length1,length2 : longint) : longint;
  89. function concatansistrings(p1,p2 : pchar;length1,length2 : longint) : pchar;
  90. {*****************************************************************************
  91. File Functions
  92. *****************************************************************************}
  93. function DeleteFile(const fn:string):boolean;
  94. implementation
  95. uses
  96. {$ifdef delphi}
  97. sysutils
  98. {$else}
  99. strings
  100. {$endif}
  101. ;
  102. var
  103. uppertbl,
  104. lowertbl : array[char] of char;
  105. function min(a,b : longint) : longint;
  106. {
  107. return the minimal of a and b
  108. }
  109. begin
  110. if a>b then
  111. min:=b
  112. else
  113. min:=a;
  114. end;
  115. function max(a,b : longint) : longint;
  116. {
  117. return the maximum of a and b
  118. }
  119. begin
  120. if a<b then
  121. max:=b
  122. else
  123. max:=a;
  124. end;
  125. Function SwapLong(x : longint): longint;
  126. var
  127. y : word;
  128. z : word;
  129. Begin
  130. y := (x shr 16) and $FFFF;
  131. y := ((y shl 8) and $FFFF) or ((y shr 8) and $ff);
  132. z := x and $FFFF;
  133. z := ((z shl 8) and $FFFF) or ((z shr 8) and $ff);
  134. SwapLong := (longint(z) shl 16) or longint(y);
  135. End;
  136. Function SwapWord(x : word): word;
  137. var
  138. z : byte;
  139. Begin
  140. z := (x shr 8) and $ff;
  141. x := x and $ff;
  142. x := (x shl 8);
  143. SwapWord := x or z;
  144. End;
  145. function align(i,a:longint):longint;
  146. {
  147. return value <i> aligned <a> boundary
  148. }
  149. begin
  150. { for 0 and 1 no aligning is needed }
  151. if a<=1 then
  152. align:=i
  153. else
  154. align:=((i+a-1) div a) * a;
  155. end;
  156. function size_2_align(len : longint) : longint;
  157. begin
  158. if len>16 then
  159. size_2_align:=32
  160. else if len>8 then
  161. size_2_align:=16
  162. else if len>4 then
  163. size_2_align:=8
  164. else if len>2 then
  165. size_2_align:=4
  166. else if len>1 then
  167. size_2_align:=2
  168. else
  169. size_2_align:=1;
  170. end;
  171. function used_align(varalign,minalign,maxalign:longint):longint;
  172. begin
  173. { varalign : minimum alignment required for the variable
  174. minalign : Minimum alignment of this structure, 0 = undefined
  175. maxalign : Maximum alignment of this structure, 0 = undefined }
  176. if (minalign>0) and
  177. (varalign<minalign) then
  178. used_align:=minalign
  179. else
  180. begin
  181. if (maxalign>0) and
  182. (varalign>maxalign) then
  183. used_align:=maxalign
  184. else
  185. used_align:=varalign;
  186. end;
  187. end;
  188. procedure Replace(var s:string;s1:string;const s2:string);
  189. var
  190. last,
  191. i : longint;
  192. begin
  193. s1:=upper(s1);
  194. last:=0;
  195. repeat
  196. i:=pos(s1,upper(s));
  197. if i=last then
  198. i:=0;
  199. if (i>0) then
  200. begin
  201. Delete(s,i,length(s1));
  202. Insert(s2,s,i);
  203. last:=i;
  204. end;
  205. until (i=0);
  206. end;
  207. procedure ReplaceCase(var s:string;const s1,s2:string);
  208. var
  209. last,
  210. i : longint;
  211. begin
  212. last:=0;
  213. repeat
  214. i:=pos(s1,s);
  215. if i=last then
  216. i:=0;
  217. if (i>0) then
  218. begin
  219. Delete(s,i,length(s1));
  220. Insert(s2,s,i);
  221. last:=i;
  222. end;
  223. until (i=0);
  224. end;
  225. function upper(const s : string) : string;
  226. {
  227. return uppercased string of s
  228. }
  229. var
  230. i : longint;
  231. begin
  232. for i:=1 to length(s) do
  233. upper[i]:=uppertbl[s[i]];
  234. upper[0]:=s[0];
  235. end;
  236. function lower(const s : string) : string;
  237. {
  238. return lowercased string of s
  239. }
  240. var
  241. i : longint;
  242. begin
  243. for i:=1 to length(s) do
  244. lower[i]:=lowertbl[s[i]];
  245. lower[0]:=s[0];
  246. end;
  247. procedure uppervar(var s : string);
  248. {
  249. uppercase string s
  250. }
  251. var
  252. i : longint;
  253. begin
  254. for i:=1 to length(s) do
  255. s[i]:=uppertbl[s[i]];
  256. end;
  257. procedure initupperlower;
  258. var
  259. c : char;
  260. begin
  261. for c:=#0 to #255 do
  262. begin
  263. lowertbl[c]:=c;
  264. uppertbl[c]:=c;
  265. case c of
  266. 'A'..'Z' :
  267. lowertbl[c]:=char(byte(c)+32);
  268. 'a'..'z' :
  269. uppertbl[c]:=char(byte(c)-32);
  270. end;
  271. end;
  272. end;
  273. function hexstr(val : cardinal;cnt : cardinal) : string;
  274. const
  275. HexTbl : array[0..15] of char='0123456789ABCDEF';
  276. var
  277. i,j : cardinal;
  278. begin
  279. { calculate required length }
  280. i:=0;
  281. j:=val;
  282. while (j>0) do
  283. begin
  284. inc(i);
  285. j:=j shr 4;
  286. end;
  287. { generate fillers }
  288. j:=0;
  289. while (i+j<cnt) do
  290. begin
  291. inc(j);
  292. hexstr[j]:='0';
  293. end;
  294. { generate hex }
  295. inc(j,i);
  296. hexstr[0]:=chr(j);
  297. while (val>0) do
  298. begin
  299. hexstr[j]:=hextbl[val and $f];
  300. dec(j);
  301. val:=val shr 4;
  302. end;
  303. end;
  304. function tostru(i:cardinal):string;
  305. {
  306. return string of value i, but for cardinals
  307. }
  308. var
  309. hs : string;
  310. begin
  311. str(i,hs);
  312. tostru:=hs;
  313. end;
  314. function DStr(l:longint):string;
  315. var
  316. TmpStr : string[32];
  317. i : longint;
  318. begin
  319. Str(l,TmpStr);
  320. i:=Length(TmpStr);
  321. while (i>3) do
  322. begin
  323. dec(i,3);
  324. if TmpStr[i]<>'-' then
  325. insert('.',TmpStr,i+1);
  326. end;
  327. DStr:=TmpStr;
  328. end;
  329. function trimbspace(const s:string):string;
  330. {
  331. return s with all leading spaces and tabs removed
  332. }
  333. var
  334. i,j : longint;
  335. begin
  336. j:=1;
  337. i:=length(s);
  338. while (j<i) and (s[j] in [#9,' ']) do
  339. inc(j);
  340. trimbspace:=Copy(s,j,i-j+1);
  341. end;
  342. function trimspace(const s:string):string;
  343. {
  344. return s with all leading and ending spaces and tabs removed
  345. }
  346. var
  347. i,j : longint;
  348. begin
  349. i:=length(s);
  350. while (i>0) and (s[i] in [#9,' ']) do
  351. dec(i);
  352. j:=1;
  353. while (j<i) and (s[j] in [#9,' ']) do
  354. inc(j);
  355. trimspace:=Copy(s,j,i-j+1);
  356. end;
  357. function space (b : longint): string;
  358. var
  359. s: string;
  360. begin
  361. space[0] := chr(b);
  362. s[0] := chr(b);
  363. FillChar (S[1],b,' ');
  364. space:=s;
  365. end;
  366. function PadSpace(const s:string;len:longint):string;
  367. {
  368. return s with spaces add to the end
  369. }
  370. begin
  371. if length(s)<len then
  372. PadSpace:=s+Space(len-length(s))
  373. else
  374. PadSpace:=s;
  375. end;
  376. function GetToken(var s:string;endchar:char):string;
  377. var
  378. i : longint;
  379. begin
  380. GetToken:='';
  381. s:=TrimSpace(s);
  382. if s[1]='''' then
  383. begin
  384. i:=1;
  385. while (i<length(s)) do
  386. begin
  387. inc(i);
  388. if s[i]='''' then
  389. begin
  390. { Remove double quote }
  391. if (i<length(s)) and
  392. (s[i+1]='''') then
  393. begin
  394. Delete(s,i,1);
  395. inc(i);
  396. end
  397. else
  398. begin
  399. GetToken:=Copy(s,2,i-2);
  400. Delete(s,1,i);
  401. exit;
  402. end;
  403. end;
  404. end;
  405. GetToken:=s;
  406. s:='';
  407. end
  408. else
  409. begin
  410. i:=pos(EndChar,s);
  411. if i=0 then
  412. begin
  413. GetToken:=s;
  414. s:='';
  415. exit;
  416. end
  417. else
  418. begin
  419. GetToken:=Copy(s,1,i-1);
  420. Delete(s,1,i);
  421. exit;
  422. end;
  423. end;
  424. end;
  425. function tostr(i : longint) : string;
  426. {
  427. return string of value i
  428. }
  429. begin
  430. str(i,result);
  431. end;
  432. function int64tostr(i : int64) : string;
  433. {
  434. return string of value i
  435. }
  436. var
  437. hs : string;
  438. begin
  439. str(i,hs);
  440. int64tostr:=hs;
  441. end;
  442. function tostr_with_plus(i : longint) : string;
  443. {
  444. return string of value i, but always include a + when i>=0
  445. }
  446. var
  447. hs : string;
  448. begin
  449. str(i,hs);
  450. if i>=0 then
  451. tostr_with_plus:='+'+hs
  452. else
  453. tostr_with_plus:=hs;
  454. end;
  455. procedure valint(S : string;var V : longint;var code : integer);
  456. {
  457. val() with support for octal, which is not supported under tp7
  458. }
  459. {$ifndef FPC}
  460. var
  461. vs : longint;
  462. c : byte;
  463. begin
  464. if s[1]='%' then
  465. begin
  466. vs:=0;
  467. longint(v):=0;
  468. for c:=2 to length(s) do
  469. begin
  470. if s[c]='0' then
  471. vs:=vs shl 1
  472. else
  473. if s[c]='1' then
  474. vs:=vs shl 1+1
  475. else
  476. begin
  477. code:=c;
  478. exit;
  479. end;
  480. end;
  481. code:=0;
  482. longint(v):=vs;
  483. end
  484. else
  485. system.val(S,V,code);
  486. end;
  487. {$else not FPC}
  488. begin
  489. system.val(S,V,code);
  490. end;
  491. {$endif not FPC}
  492. function is_number(const s : string) : boolean;
  493. {
  494. is string a correct number ?
  495. }
  496. var
  497. w : integer;
  498. l : longint;
  499. begin
  500. valint(s,l,w);
  501. is_number:=(w=0);
  502. end;
  503. function ispowerof2(value : int64;var power : longint) : boolean;
  504. {
  505. return if value is a power of 2. And if correct return the power
  506. }
  507. var
  508. hl : int64;
  509. i : longint;
  510. begin
  511. if value and (value - 1) <> 0 then
  512. begin
  513. ispowerof2 := false;
  514. exit
  515. end;
  516. hl:=1;
  517. ispowerof2:=true;
  518. for i:=0 to 63 do
  519. begin
  520. if hl=value then
  521. begin
  522. power:=i;
  523. exit;
  524. end;
  525. hl:=hl shl 1;
  526. end;
  527. ispowerof2:=false;
  528. end;
  529. function maybequoted(const s:string):string;
  530. var
  531. s1 : string;
  532. i : integer;
  533. begin
  534. if (pos('"',s)>0) then
  535. begin
  536. s1:='"';
  537. for i:=1 to length(s) do
  538. begin
  539. if s[i]='"' then
  540. s1:=s1+'\"'
  541. else
  542. s1:=s1+s[i];
  543. end;
  544. maybequoted:=s1+'"';
  545. end
  546. else if (pos(' ',s)>0) then
  547. maybequoted:='"'+s+'"'
  548. else
  549. maybequoted:=s;
  550. end;
  551. function pchar2pstring(p : pchar) : pstring;
  552. var
  553. w,i : longint;
  554. begin
  555. w:=strlen(p);
  556. for i:=w-1 downto 0 do
  557. p[i+1]:=p[i];
  558. p[0]:=chr(w);
  559. pchar2pstring:=pstring(p);
  560. end;
  561. function pstring2pchar(p : pstring) : pchar;
  562. var
  563. w,i : longint;
  564. begin
  565. w:=length(p^);
  566. for i:=1 to w do
  567. p^[i-1]:=p^[i];
  568. p^[w]:=#0;
  569. pstring2pchar:=pchar(p);
  570. end;
  571. function lowercase(c : char) : char;
  572. begin
  573. case c of
  574. #65..#90 : c := chr(ord (c) + 32);
  575. #154 : c:=#129; { german }
  576. #142 : c:=#132; { german }
  577. #153 : c:=#148; { german }
  578. #144 : c:=#130; { french }
  579. #128 : c:=#135; { french }
  580. #143 : c:=#134; { swedish/norge (?) }
  581. #165 : c:=#164; { spanish }
  582. #228 : c:=#229; { greek }
  583. #226 : c:=#231; { greek }
  584. #232 : c:=#227; { greek }
  585. end;
  586. lowercase := c;
  587. end;
  588. function strpnew(const s : string) : pchar;
  589. var
  590. p : pchar;
  591. begin
  592. getmem(p,length(s)+1);
  593. strpcopy(p,s);
  594. strpnew:=p;
  595. end;
  596. procedure strdispose(var p : pchar);
  597. begin
  598. if assigned(p) then
  599. begin
  600. freemem(p,strlen(p)+1);
  601. p:=nil;
  602. end;
  603. end;
  604. procedure stringdispose(var p : pstring);
  605. begin
  606. if assigned(p) then
  607. freemem(p,length(p^)+1);
  608. p:=nil;
  609. end;
  610. function stringdup(const s : string) : pstring;
  611. var
  612. p : pstring;
  613. begin
  614. getmem(p,length(s)+1);
  615. p^:=s;
  616. stringdup:=p;
  617. end;
  618. function CompareText(S1, S2: string): longint;
  619. begin
  620. UpperVar(S1);
  621. UpperVar(S2);
  622. if S1<S2 then
  623. CompareText:=-1
  624. else
  625. if S1>S2 then
  626. CompareText:= 1
  627. else
  628. CompareText:=0;
  629. end;
  630. {*****************************************************************************
  631. GetSpeedValue
  632. *****************************************************************************}
  633. {$ifdef ver1_0}
  634. {$R-}
  635. {$endif}
  636. var
  637. Crc32Tbl : array[0..255] of cardinal;
  638. procedure MakeCRC32Tbl;
  639. var
  640. crc : cardinal;
  641. i,n : integer;
  642. begin
  643. for i:=0 to 255 do
  644. begin
  645. crc:=i;
  646. for n:=1 to 8 do
  647. if odd(longint(crc)) then
  648. crc:=cardinal(crc shr 1) xor cardinal($edb88320)
  649. else
  650. crc:=cardinal(crc shr 1);
  651. Crc32Tbl[i]:=crc;
  652. end;
  653. end;
  654. Function GetSpeedValue(Const s:String):cardinal;
  655. var
  656. i : integer;
  657. InitCrc : cardinal;
  658. begin
  659. if Crc32Tbl[1]=0 then
  660. MakeCrc32Tbl;
  661. InitCrc:=cardinal($ffffffff);
  662. for i:=1 to Length(s) do
  663. InitCrc:=Crc32Tbl[byte(InitCrc) xor ord(s[i])] xor (InitCrc shr 8);
  664. GetSpeedValue:=InitCrc;
  665. end;
  666. {*****************************************************************************
  667. Ansistring (PChar+Length)
  668. *****************************************************************************}
  669. procedure ansistringdispose(var p : pchar;length : longint);
  670. begin
  671. if assigned(p) then
  672. freemem(p,length+1);
  673. p:=nil;
  674. end;
  675. { enable ansistring comparison }
  676. { 0 means equal }
  677. { 1 means p1 > p2 }
  678. { -1 means p1 < p2 }
  679. function compareansistrings(p1,p2 : pchar;length1,length2 : longint) : longint;
  680. var
  681. i,j : longint;
  682. begin
  683. compareansistrings:=0;
  684. j:=min(length1,length2);
  685. i:=0;
  686. while (i<j) do
  687. begin
  688. if p1[i]>p2[i] then
  689. begin
  690. compareansistrings:=1;
  691. exit;
  692. end
  693. else
  694. if p1[i]<p2[i] then
  695. begin
  696. compareansistrings:=-1;
  697. exit;
  698. end;
  699. inc(i);
  700. end;
  701. if length1>length2 then
  702. compareansistrings:=1
  703. else
  704. if length1<length2 then
  705. compareansistrings:=-1;
  706. end;
  707. function concatansistrings(p1,p2 : pchar;length1,length2 : longint) : pchar;
  708. var
  709. p : pchar;
  710. begin
  711. getmem(p,length1+length2+1);
  712. move(p1[0],p[0],length1);
  713. move(p2[0],p[length1],length2+1);
  714. concatansistrings:=p;
  715. end;
  716. {*****************************************************************************
  717. File Functions
  718. *****************************************************************************}
  719. function DeleteFile(const fn:string):boolean;
  720. var
  721. f : file;
  722. begin
  723. {$I-}
  724. assign(f,fn);
  725. erase(f);
  726. {$I-}
  727. DeleteFile:=(IOResult=0);
  728. end;
  729. initialization
  730. initupperlower;
  731. end.
  732. {
  733. $Log$
  734. Revision 1.24 2002-12-27 18:05:27 peter
  735. * support quotes in gettoken
  736. Revision 1.23 2002/10/05 12:43:24 carl
  737. * fixes for Delphi 6 compilation
  738. (warning : Some features do not work under Delphi)
  739. Revision 1.22 2002/09/05 19:29:42 peter
  740. * memdebug enhancements
  741. Revision 1.21 2002/07/26 11:16:35 jonas
  742. * fixed (actual and potential) range errors
  743. Revision 1.20 2002/07/07 11:13:34 carl
  744. * range check error fix (patch from Sergey)
  745. Revision 1.19 2002/07/07 09:52:32 florian
  746. * powerpc target fixed, very simple units can be compiled
  747. * some basic stuff for better callparanode handling, far from being finished
  748. Revision 1.18 2002/07/01 18:46:22 peter
  749. * internal linker
  750. * reorganized aasm layer
  751. Revision 1.17 2002/05/18 13:34:07 peter
  752. * readded missing revisions
  753. Revision 1.16 2002/05/16 19:46:36 carl
  754. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  755. + try to fix temp allocation (still in ifdef)
  756. + generic constructor calls
  757. + start of tassembler / tmodulebase class cleanup
  758. Revision 1.14 2002/04/12 17:16:35 carl
  759. + more documentation of basic unit
  760. }