cutils.pas 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801
  1. {
  2. $Id$
  3. Copyright (C) 1998-2000 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 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. unit cutils;
  19. {$i defines.inc}
  20. interface
  21. uses
  22. cpuinfo;
  23. {$ifdef delphi}
  24. type
  25. dword = cardinal;
  26. qword = int64;
  27. {$endif}
  28. type
  29. pstring = ^string;
  30. function min(a,b : longint) : longint;
  31. function max(a,b : longint) : longint;
  32. function SwapLong(x : longint): longint;
  33. function SwapWord(x : word): word;
  34. function align(i,a:longint):longint;
  35. function used_align(varalign,minalign,maxalign:longint):longint;
  36. function size_2_align(len : longint) : longint;
  37. procedure Replace(var s:string;s1:string;const s2:string);
  38. procedure ReplaceCase(var s:string;const s1,s2:string);
  39. function upper(const s : string) : string;
  40. function lower(const s : string) : string;
  41. function trimbspace(const s:string):string;
  42. function trimspace(const s:string):string;
  43. function GetToken(var s:string;endchar:char):string;
  44. procedure uppervar(var s : string);
  45. function hexstr(val : cardinal;cnt : byte) : string;
  46. function tostru(i:cardinal) : string;
  47. function tostr(i : longint) : string;
  48. function int64tostr(i : int64) : string;
  49. function tostr_with_plus(i : longint) : string;
  50. procedure valint(S : string;var V : longint;var code : integer);
  51. function is_number(const s : string) : boolean;
  52. function ispowerof2(value : TConstExprInt;var power : longint) : boolean;
  53. function maybequoted(const s:string):string;
  54. function CompareText(S1, S2: string): longint;
  55. { releases the string p and assignes nil to p }
  56. { if p=nil then freemem isn't called }
  57. procedure stringdispose(var p : pstring);
  58. { allocates mem for a copy of s, copies s to this mem and returns }
  59. { a pointer to this mem }
  60. function stringdup(const s : string) : pstring;
  61. { allocates memory for s and copies s as zero terminated string
  62. to that mem and returns a pointer to that mem }
  63. function strpnew(const s : string) : pchar;
  64. procedure strdispose(var p : pchar);
  65. { makes a char lowercase, with spanish, french and german char set }
  66. function lowercase(c : char) : char;
  67. { makes zero terminated string to a pascal string }
  68. { the data in p is modified and p is returned }
  69. function pchar2pstring(p : pchar) : pstring;
  70. { ambivalent to pchar2pstring }
  71. function pstring2pchar(p : pstring) : pchar;
  72. { Speed/Hash value }
  73. Function GetSpeedValue(Const s:String):cardinal;
  74. { Ansistring (pchar+length) support }
  75. procedure ansistringdispose(var p : pchar;length : longint);
  76. function compareansistrings(p1,p2 : pchar;length1,length2 : longint) : longint;
  77. function concatansistrings(p1,p2 : pchar;length1,length2 : longint) : pchar;
  78. {*****************************************************************************
  79. File Functions
  80. *****************************************************************************}
  81. function DeleteFile(const fn:string):boolean;
  82. implementation
  83. uses
  84. {$ifdef delphi}
  85. sysutils
  86. {$else}
  87. strings
  88. {$endif}
  89. ;
  90. var
  91. uppertbl,
  92. lowertbl : array[char] of char;
  93. function min(a,b : longint) : longint;
  94. {
  95. return the minimal of a and b
  96. }
  97. begin
  98. if a>b then
  99. min:=b
  100. else
  101. min:=a;
  102. end;
  103. function max(a,b : longint) : longint;
  104. {
  105. return the maximum of a and b
  106. }
  107. begin
  108. if a<b then
  109. max:=b
  110. else
  111. max:=a;
  112. end;
  113. Function SwapLong(x : longint): longint;
  114. var
  115. y : word;
  116. z : word;
  117. Begin
  118. y := (x shr 16) and $FFFF;
  119. y := ((y shl 8) and $FFFF) or ((y shr 8) and $ff);
  120. z := x and $FFFF;
  121. z := ((z shl 8) and $FFFF) or ((z shr 8) and $ff);
  122. SwapLong := (longint(z) shl 16) or longint(y);
  123. End;
  124. Function SwapWord(x : word): word;
  125. var
  126. z : byte;
  127. Begin
  128. z := (x shr 8) and $ff;
  129. x := x and $ff;
  130. x := (x shl 8);
  131. SwapWord := x or z;
  132. End;
  133. function align(i,a:longint):longint;
  134. {
  135. return value <i> aligned <a> boundary
  136. }
  137. begin
  138. { for 0 and 1 no aligning is needed }
  139. if a<=1 then
  140. align:=i
  141. else
  142. align:=((i+a-1) div a) * a;
  143. end;
  144. function size_2_align(len : longint) : longint;
  145. begin
  146. if len>16 then
  147. size_2_align:=32
  148. else if len>8 then
  149. size_2_align:=16
  150. else if len>4 then
  151. size_2_align:=8
  152. else if len>2 then
  153. size_2_align:=4
  154. else if len>1 then
  155. size_2_align:=2
  156. else
  157. size_2_align:=1;
  158. end;
  159. function used_align(varalign,minalign,maxalign:longint):longint;
  160. begin
  161. { varalign : minimum alignment required for the variable
  162. minalign : Minimum alignment of this structure, 0 = undefined
  163. maxalign : Maximum alignment of this structure, 0 = undefined }
  164. if (minalign>0) and
  165. (varalign<minalign) then
  166. used_align:=minalign
  167. else
  168. begin
  169. if (maxalign>0) and
  170. (varalign>maxalign) then
  171. used_align:=maxalign
  172. else
  173. used_align:=varalign;
  174. end;
  175. end;
  176. procedure Replace(var s:string;s1:string;const s2:string);
  177. var
  178. last,
  179. i : longint;
  180. begin
  181. s1:=upper(s1);
  182. last:=0;
  183. repeat
  184. i:=pos(s1,upper(s));
  185. if i=last then
  186. i:=0;
  187. if (i>0) then
  188. begin
  189. Delete(s,i,length(s1));
  190. Insert(s2,s,i);
  191. last:=i;
  192. end;
  193. until (i=0);
  194. end;
  195. procedure ReplaceCase(var s:string;const s1,s2:string);
  196. var
  197. last,
  198. i : longint;
  199. begin
  200. last:=0;
  201. repeat
  202. i:=pos(s1,s);
  203. if i=last then
  204. i:=0;
  205. if (i>0) then
  206. begin
  207. Delete(s,i,length(s1));
  208. Insert(s2,s,i);
  209. last:=i;
  210. end;
  211. until (i=0);
  212. end;
  213. function upper(const s : string) : string;
  214. {
  215. return uppercased string of s
  216. }
  217. var
  218. i : longint;
  219. begin
  220. for i:=1 to length(s) do
  221. upper[i]:=uppertbl[s[i]];
  222. upper[0]:=s[0];
  223. end;
  224. function lower(const s : string) : string;
  225. {
  226. return lowercased string of s
  227. }
  228. var
  229. i : longint;
  230. begin
  231. for i:=1 to length(s) do
  232. lower[i]:=lowertbl[s[i]];
  233. lower[0]:=s[0];
  234. end;
  235. procedure uppervar(var s : string);
  236. {
  237. uppercase string s
  238. }
  239. var
  240. i : longint;
  241. begin
  242. for i:=1 to length(s) do
  243. s[i]:=uppertbl[s[i]];
  244. end;
  245. procedure initupperlower;
  246. var
  247. c : char;
  248. begin
  249. for c:=#0 to #255 do
  250. begin
  251. lowertbl[c]:=c;
  252. uppertbl[c]:=c;
  253. case c of
  254. 'A'..'Z' :
  255. lowertbl[c]:=char(byte(c)+32);
  256. 'a'..'z' :
  257. uppertbl[c]:=char(byte(c)-32);
  258. end;
  259. end;
  260. end;
  261. function hexstr(val : cardinal;cnt : byte) : string;
  262. const
  263. HexTbl : array[0..15] of char='0123456789ABCDEF';
  264. var
  265. i : longint;
  266. begin
  267. hexstr[0]:=char(cnt);
  268. for i:=cnt downto 1 do
  269. begin
  270. hexstr[i]:=hextbl[val and $f];
  271. val:=val shr 4;
  272. end;
  273. end;
  274. function tostru(i:cardinal):string;
  275. {
  276. return string of value i, but for cardinals
  277. }
  278. var
  279. hs : string;
  280. begin
  281. str(i,hs);
  282. tostru:=hs;
  283. end;
  284. function trimbspace(const s:string):string;
  285. {
  286. return s with all leading spaces and tabs removed
  287. }
  288. var
  289. i,j : longint;
  290. begin
  291. j:=1;
  292. i:=length(s);
  293. while (j<i) and (s[j] in [#9,' ']) do
  294. inc(j);
  295. trimbspace:=Copy(s,j,i-j+1);
  296. end;
  297. function trimspace(const s:string):string;
  298. {
  299. return s with all leading and ending spaces and tabs removed
  300. }
  301. var
  302. i,j : longint;
  303. begin
  304. i:=length(s);
  305. while (i>0) and (s[i] in [#9,' ']) do
  306. dec(i);
  307. j:=1;
  308. while (j<i) and (s[j] in [#9,' ']) do
  309. inc(j);
  310. trimspace:=Copy(s,j,i-j+1);
  311. end;
  312. function GetToken(var s:string;endchar:char):string;
  313. var
  314. i : longint;
  315. begin
  316. s:=TrimSpace(s);
  317. i:=pos(EndChar,s);
  318. if i=0 then
  319. begin
  320. GetToken:=s;
  321. s:='';
  322. end
  323. else
  324. begin
  325. GetToken:=Copy(s,1,i-1);
  326. Delete(s,1,i);
  327. end;
  328. end;
  329. function tostr(i : longint) : string;
  330. {
  331. return string of value i
  332. }
  333. var
  334. hs : string;
  335. begin
  336. str(i,hs);
  337. tostr:=hs;
  338. end;
  339. function int64tostr(i : int64) : string;
  340. {
  341. return string of value i
  342. }
  343. var
  344. hs : string;
  345. begin
  346. str(i,hs);
  347. int64tostr:=hs;
  348. end;
  349. function tostr_with_plus(i : longint) : string;
  350. {
  351. return string of value i, but always include a + when i>=0
  352. }
  353. var
  354. hs : string;
  355. begin
  356. str(i,hs);
  357. if i>=0 then
  358. tostr_with_plus:='+'+hs
  359. else
  360. tostr_with_plus:=hs;
  361. end;
  362. procedure valint(S : string;var V : longint;var code : integer);
  363. {
  364. val() with support for octal, which is not supported under tp7
  365. }
  366. {$ifndef FPC}
  367. var
  368. vs : longint;
  369. c : byte;
  370. begin
  371. if s[1]='%' then
  372. begin
  373. vs:=0;
  374. longint(v):=0;
  375. for c:=2 to length(s) do
  376. begin
  377. if s[c]='0' then
  378. vs:=vs shl 1
  379. else
  380. if s[c]='1' then
  381. vs:=vs shl 1+1
  382. else
  383. begin
  384. code:=c;
  385. exit;
  386. end;
  387. end;
  388. code:=0;
  389. longint(v):=vs;
  390. end
  391. else
  392. system.val(S,V,code);
  393. end;
  394. {$else not FPC}
  395. begin
  396. system.val(S,V,code);
  397. end;
  398. {$endif not FPC}
  399. function is_number(const s : string) : boolean;
  400. {
  401. is string a correct number ?
  402. }
  403. var
  404. w : integer;
  405. l : longint;
  406. begin
  407. valint(s,l,w);
  408. is_number:=(w=0);
  409. end;
  410. function ispowerof2(value : TConstExprInt;var power : longint) : boolean;
  411. {
  412. return if value is a power of 2. And if correct return the power
  413. }
  414. var
  415. hl : TConstExprInt;
  416. i : longint;
  417. begin
  418. if value and (value - 1) <> 0 then
  419. begin
  420. ispowerof2 := false;
  421. exit
  422. end;
  423. hl:=1;
  424. ispowerof2:=true;
  425. for i:=0 to 63 do
  426. begin
  427. if hl=value then
  428. begin
  429. power:=i;
  430. exit;
  431. end;
  432. hl:=hl shl 1;
  433. end;
  434. ispowerof2:=false;
  435. end;
  436. function maybequoted(const s:string):string;
  437. var
  438. s1 : string;
  439. i : integer;
  440. begin
  441. if (pos('"',s)>0) then
  442. begin
  443. s1:='"';
  444. for i:=1 to length(s) do
  445. begin
  446. if s[i]='"' then
  447. s1:=s1+'\"'
  448. else
  449. s1:=s1+s[i];
  450. end;
  451. maybequoted:=s1+'"';
  452. end
  453. else if (pos(' ',s)>0) then
  454. maybequoted:='"'+s+'"'
  455. else
  456. maybequoted:=s;
  457. end;
  458. function pchar2pstring(p : pchar) : pstring;
  459. var
  460. w,i : longint;
  461. begin
  462. w:=strlen(p);
  463. for i:=w-1 downto 0 do
  464. p[i+1]:=p[i];
  465. p[0]:=chr(w);
  466. pchar2pstring:=pstring(p);
  467. end;
  468. function pstring2pchar(p : pstring) : pchar;
  469. var
  470. w,i : longint;
  471. begin
  472. w:=length(p^);
  473. for i:=1 to w do
  474. p^[i-1]:=p^[i];
  475. p^[w]:=#0;
  476. pstring2pchar:=pchar(p);
  477. end;
  478. function lowercase(c : char) : char;
  479. begin
  480. case c of
  481. #65..#90 : c := chr(ord (c) + 32);
  482. #154 : c:=#129; { german }
  483. #142 : c:=#132; { german }
  484. #153 : c:=#148; { german }
  485. #144 : c:=#130; { french }
  486. #128 : c:=#135; { french }
  487. #143 : c:=#134; { swedish/norge (?) }
  488. #165 : c:=#164; { spanish }
  489. #228 : c:=#229; { greek }
  490. #226 : c:=#231; { greek }
  491. #232 : c:=#227; { greek }
  492. end;
  493. lowercase := c;
  494. end;
  495. function strpnew(const s : string) : pchar;
  496. var
  497. p : pchar;
  498. begin
  499. getmem(p,length(s)+1);
  500. strpcopy(p,s);
  501. strpnew:=p;
  502. end;
  503. procedure strdispose(var p : pchar);
  504. begin
  505. if assigned(p) then
  506. begin
  507. freemem(p,strlen(p)+1);
  508. p:=nil;
  509. end;
  510. end;
  511. procedure stringdispose(var p : pstring);
  512. begin
  513. if assigned(p) then
  514. freemem(p,length(p^)+1);
  515. p:=nil;
  516. end;
  517. function stringdup(const s : string) : pstring;
  518. var
  519. p : pstring;
  520. begin
  521. getmem(p,length(s)+1);
  522. p^:=s;
  523. stringdup:=p;
  524. end;
  525. function CompareText(S1, S2: string): longint;
  526. begin
  527. UpperVar(S1);
  528. UpperVar(S2);
  529. if S1<S2 then
  530. CompareText:=-1
  531. else
  532. if S1>S2 then
  533. CompareText:= 1
  534. else
  535. CompareText:=0;
  536. end;
  537. {*****************************************************************************
  538. GetSpeedValue
  539. *****************************************************************************}
  540. {$ifdef ver1_0}
  541. {$R-}
  542. {$endif}
  543. var
  544. Crc32Tbl : array[0..255] of cardinal;
  545. procedure MakeCRC32Tbl;
  546. var
  547. crc : cardinal;
  548. i,n : integer;
  549. begin
  550. for i:=0 to 255 do
  551. begin
  552. crc:=i;
  553. for n:=1 to 8 do
  554. if odd(longint(crc)) then
  555. crc:=cardinal(crc shr 1) xor cardinal($edb88320)
  556. else
  557. crc:=cardinal(crc shr 1);
  558. Crc32Tbl[i]:=crc;
  559. end;
  560. end;
  561. Function GetSpeedValue(Const s:String):cardinal;
  562. var
  563. i : integer;
  564. InitCrc : cardinal;
  565. begin
  566. if Crc32Tbl[1]=0 then
  567. MakeCrc32Tbl;
  568. InitCrc:=cardinal($ffffffff);
  569. for i:=1 to Length(s) do
  570. InitCrc:=Crc32Tbl[byte(InitCrc) xor ord(s[i])] xor (InitCrc shr 8);
  571. GetSpeedValue:=InitCrc;
  572. end;
  573. {*****************************************************************************
  574. Ansistring (PChar+Length)
  575. *****************************************************************************}
  576. procedure ansistringdispose(var p : pchar;length : longint);
  577. begin
  578. if assigned(p) then
  579. freemem(p,length+1);
  580. p:=nil;
  581. end;
  582. { enable ansistring comparison }
  583. { 0 means equal }
  584. { 1 means p1 > p2 }
  585. { -1 means p1 < p2 }
  586. function compareansistrings(p1,p2 : pchar;length1,length2 : longint) : longint;
  587. var
  588. i,j : longint;
  589. begin
  590. compareansistrings:=0;
  591. j:=min(length1,length2);
  592. i:=0;
  593. while (i<j) do
  594. begin
  595. if p1[i]>p2[i] then
  596. begin
  597. compareansistrings:=1;
  598. exit;
  599. end
  600. else
  601. if p1[i]<p2[i] then
  602. begin
  603. compareansistrings:=-1;
  604. exit;
  605. end;
  606. inc(i);
  607. end;
  608. if length1>length2 then
  609. compareansistrings:=1
  610. else
  611. if length1<length2 then
  612. compareansistrings:=-1;
  613. end;
  614. function concatansistrings(p1,p2 : pchar;length1,length2 : longint) : pchar;
  615. var
  616. p : pchar;
  617. begin
  618. getmem(p,length1+length2+1);
  619. move(p1[0],p[0],length1);
  620. move(p2[0],p[length1],length2+1);
  621. concatansistrings:=p;
  622. end;
  623. {*****************************************************************************
  624. File Functions
  625. *****************************************************************************}
  626. function DeleteFile(const fn:string):boolean;
  627. var
  628. f : file;
  629. begin
  630. {$I-}
  631. assign(f,fn);
  632. erase(f);
  633. {$I-}
  634. DeleteFile:=(IOResult=0);
  635. end;
  636. initialization
  637. initupperlower;
  638. end.
  639. {
  640. $Log$
  641. Revision 1.12 2001-11-18 18:43:13 peter
  642. * overloading supported in child classes
  643. * fixed parsing of classes with private and virtual and overloaded
  644. so it is compatible with delphi
  645. Revision 1.11 2001/09/05 15:20:26 jonas
  646. * ispowerf2 now works with 64bit ints and should be faster
  647. Revision 1.10 2001/08/04 11:06:30 peter
  648. * browcol has no depends on ide/fv
  649. Revision 1.9 2001/07/30 20:59:27 peter
  650. * m68k updates from v10 merged
  651. Revision 1.8 2001/07/01 20:16:15 peter
  652. * alignmentinfo record added
  653. * -Oa argument supports more alignment settings that can be specified
  654. per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
  655. RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
  656. required alignment and the maximum usefull alignment. The final
  657. alignment will be choosen per variable size dependent on these
  658. settings
  659. Revision 1.7 2001/06/18 20:36:23 peter
  660. * -Ur switch (merged)
  661. * masm fixes (merged)
  662. * quoted filenames for go32v2 and win32
  663. Revision 1.6 2001/05/09 14:11:10 jonas
  664. * range check error fixes from Peter
  665. Revision 1.5 2000/12/24 12:25:31 peter
  666. + cstreams unit
  667. * dynamicarray object to class
  668. Revision 1.4 2000/11/28 00:17:43 pierre
  669. + int64tostr function added
  670. Revision 1.3 2000/11/07 20:47:35 peter
  671. * use tables for upper/lower
  672. Revision 1.2 2000/09/24 15:06:14 peter
  673. * use defines.inc
  674. Revision 1.1 2000/08/27 16:11:50 peter
  675. * moved some util functions from globals,cobjects to cutils
  676. * splitted files into finput,fmodule
  677. }