cutils.pas 16 KB

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