cutils.pas 14 KB

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