cutils.pas 18 KB

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