cutils.pas 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802
  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) : longint;
  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. var
  541. Crc32Tbl : array[0..255] of longint;
  542. procedure MakeCRC32Tbl;
  543. var
  544. crc : longint;
  545. i,n : byte;
  546. begin
  547. for i:=0 to 255 do
  548. begin
  549. crc:=i;
  550. for n:=1 to 8 do
  551. if odd(crc) then
  552. crc:=(crc shr 1) xor longint($edb88320)
  553. else
  554. crc:=crc shr 1;
  555. Crc32Tbl[i]:=crc;
  556. end;
  557. end;
  558. {$ifopt R+}
  559. {$define Range_check_on}
  560. {$endif opt R+}
  561. {$R- needed here }
  562. {CRC 32}
  563. Function GetSpeedValue(Const s:String):longint;
  564. var
  565. i,InitCrc : longint;
  566. begin
  567. if Crc32Tbl[1]=0 then
  568. MakeCrc32Tbl;
  569. InitCrc:=-1;
  570. for i:=1 to Length(s) do
  571. InitCrc:=Crc32Tbl[byte(InitCrc) xor ord(s[i])] xor (InitCrc shr 8);
  572. GetSpeedValue:=InitCrc;
  573. end;
  574. {$ifdef Range_check_on}
  575. {$R+}
  576. {$undef Range_check_on}
  577. {$endif Range_check_on}
  578. {*****************************************************************************
  579. Ansistring (PChar+Length)
  580. *****************************************************************************}
  581. procedure ansistringdispose(var p : pchar;length : longint);
  582. begin
  583. if assigned(p) then
  584. freemem(p,length+1);
  585. p:=nil;
  586. end;
  587. { enable ansistring comparison }
  588. { 0 means equal }
  589. { 1 means p1 > p2 }
  590. { -1 means p1 < p2 }
  591. function compareansistrings(p1,p2 : pchar;length1,length2 : longint) : longint;
  592. var
  593. i,j : longint;
  594. begin
  595. compareansistrings:=0;
  596. j:=min(length1,length2);
  597. i:=0;
  598. while (i<j) do
  599. begin
  600. if p1[i]>p2[i] then
  601. begin
  602. compareansistrings:=1;
  603. exit;
  604. end
  605. else
  606. if p1[i]<p2[i] then
  607. begin
  608. compareansistrings:=-1;
  609. exit;
  610. end;
  611. inc(i);
  612. end;
  613. if length1>length2 then
  614. compareansistrings:=1
  615. else
  616. if length1<length2 then
  617. compareansistrings:=-1;
  618. end;
  619. function concatansistrings(p1,p2 : pchar;length1,length2 : longint) : pchar;
  620. var
  621. p : pchar;
  622. begin
  623. getmem(p,length1+length2+1);
  624. move(p1[0],p[0],length1);
  625. move(p2[0],p[length1],length2+1);
  626. concatansistrings:=p;
  627. end;
  628. {*****************************************************************************
  629. File Functions
  630. *****************************************************************************}
  631. function DeleteFile(const fn:string):boolean;
  632. var
  633. f : file;
  634. begin
  635. {$I-}
  636. assign(f,fn);
  637. erase(f);
  638. {$I-}
  639. DeleteFile:=(IOResult=0);
  640. end;
  641. initialization
  642. initupperlower;
  643. end.
  644. {
  645. $Log$
  646. Revision 1.11 2001-09-05 15:20:26 jonas
  647. * ispowerf2 now works with 64bit ints and should be faster
  648. Revision 1.10 2001/08/04 11:06:30 peter
  649. * browcol has no depends on ide/fv
  650. Revision 1.9 2001/07/30 20:59:27 peter
  651. * m68k updates from v10 merged
  652. Revision 1.8 2001/07/01 20:16:15 peter
  653. * alignmentinfo record added
  654. * -Oa argument supports more alignment settings that can be specified
  655. per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
  656. RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
  657. required alignment and the maximum usefull alignment. The final
  658. alignment will be choosen per variable size dependent on these
  659. settings
  660. Revision 1.7 2001/06/18 20:36:23 peter
  661. * -Ur switch (merged)
  662. * masm fixes (merged)
  663. * quoted filenames for go32v2 and win32
  664. Revision 1.6 2001/05/09 14:11:10 jonas
  665. * range check error fixes from Peter
  666. Revision 1.5 2000/12/24 12:25:31 peter
  667. + cstreams unit
  668. * dynamicarray object to class
  669. Revision 1.4 2000/11/28 00:17:43 pierre
  670. + int64tostr function added
  671. Revision 1.3 2000/11/07 20:47:35 peter
  672. * use tables for upper/lower
  673. Revision 1.2 2000/09/24 15:06:14 peter
  674. * use defines.inc
  675. Revision 1.1 2000/08/27 16:11:50 peter
  676. * moved some util functions from globals,cobjects to cutils
  677. * splitted files into finput,fmodule
  678. }