cutils.pas 14 KB

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