cutils.pas 17 KB

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