sstrings.inc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1993,97 by the Free Pascal development team
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {****************************************************************************
  12. subroutines for string handling
  13. ****************************************************************************}
  14. {$I real2str.inc}
  15. function copy(const s : string;index : integer;count : integer): string;
  16. begin
  17. if count<0 then
  18. count:=0;
  19. if index>1 then
  20. dec(index)
  21. else
  22. index:=0;
  23. if index>length(s) then
  24. count:=0
  25. else
  26. if index+count>length(s) then
  27. count:=length(s)-index;
  28. Copy[0]:=chr(Count);
  29. Move(s[Index+1],Copy[1],Count);
  30. end;
  31. procedure delete(var s : string;index : integer;count : integer);
  32. begin
  33. if index<=0 then
  34. begin
  35. count:=count+index-1;
  36. index:=1;
  37. end;
  38. if (Index<=Length(s)) and (Count>0) then
  39. begin
  40. if Count+Index>length(s) then
  41. Count:=length(s)-Index+1;
  42. s[0]:=Chr(length(s)-Count);
  43. if Index<=Length(s) then
  44. Move(s[Index+Count],s[Index],Length(s)-Index+1);
  45. end;
  46. end;
  47. procedure insert(const source : string;var s : string;index : integer);
  48. begin
  49. if index>1 then
  50. dec(index)
  51. else
  52. index:=0;
  53. s:=Copy(s,1,Index)+source+Copy(s,Index+1,length(s));
  54. end;
  55. function pos(const substr : string;const s : string): byte;
  56. var i,j : longint;
  57. e : boolean;
  58. begin
  59. i := 0;
  60. j := 0;
  61. e:=(length(SubStr)>0);
  62. while e and (i<=Length(s)-Length(SubStr)) do
  63. begin
  64. inc(i);
  65. if (SubStr[1]=s[i]) and (Substr=Copy(s,i,Length(SubStr))) then
  66. begin
  67. j:=i;
  68. e:=false;
  69. end;
  70. end;
  71. Pos:=j;
  72. end;
  73. {Faster when looking for a single char...}
  74. function pos(c:char;const s:string):byte;
  75. var i:longint;
  76. begin
  77. for i:=1 to length(s) do
  78. if s[i]=c then
  79. begin
  80. pos:=i;
  81. exit;
  82. end;
  83. pos:=0;
  84. end;
  85. {$ifdef IBM_CHAR_SET}
  86. const
  87. UpCaseTbl : string[7]=#154#142#153#144#128#143#165;
  88. LoCaseTbl : string[7]=#129#132#148#130#135#134#164;
  89. {$endif}
  90. function upcase(c : char) : char;
  91. {$IFDEF IBM_CHAR_SET}
  92. var
  93. i : longint;
  94. {$ENDIF}
  95. begin
  96. if (c in ['a'..'z']) then
  97. upcase:=char(byte(c)-32)
  98. else
  99. {$IFDEF IBM_CHAR_SET}
  100. begin
  101. i:=Pos(c,LoCaseTbl);
  102. if i>0 then
  103. upcase:=UpCaseTbl[i]
  104. else
  105. upcase:=c;
  106. end;
  107. {$ELSE}
  108. upcase:=c;
  109. {$ENDIF}
  110. end;
  111. function upcase(const s : string) : string;
  112. var i : longint;
  113. begin
  114. upcase[0]:=s[0];
  115. for i := 1 to length (s) do
  116. upcase[i] := upcase (s[i]);
  117. end;
  118. {$ifndef RTLLITE}
  119. function lowercase(c : char) : char;
  120. {$IFDEF IBM_CHAR_SET}
  121. var
  122. i : longint;
  123. {$ENDIF}
  124. begin
  125. if (c in ['A'..'Z']) then
  126. lowercase:=char(byte(c)+32)
  127. else
  128. {$IFDEF IBM_CHAR_SET}
  129. begin
  130. i:=Pos(c,UpCaseTbl);
  131. if i>0 then
  132. lowercase:=LoCaseTbl[i]
  133. else
  134. lowercase:=c;
  135. end;
  136. {$ELSE}
  137. lowercase:=c;
  138. {$ENDIF}
  139. end;
  140. function lowercase(const s : string) : string;
  141. var i : longint;
  142. begin
  143. lowercase [0] := s[0];
  144. for i := 1 to length (s) do
  145. lowercase[i] := lowercase (s[i]);
  146. end;
  147. function hexstr(val : longint;cnt : byte) : string;
  148. const
  149. HexTbl : array[0..15] of char='0123456789ABCDEF';
  150. var
  151. i : longint;
  152. begin
  153. hexstr[0]:=char(cnt);
  154. for i:=cnt downto 1 do
  155. begin
  156. hexstr[i]:=hextbl[val and $f];
  157. val:=val shr 4;
  158. end;
  159. end;
  160. function binstr(val : longint;cnt : byte) : string;
  161. var
  162. i : longint;
  163. begin
  164. binstr[0]:=char(cnt);
  165. for i:=cnt downto 1 do
  166. begin
  167. binstr[i]:=char(48+val and 1);
  168. val:=val shr 1;
  169. end;
  170. end;
  171. {$endif RTLLITE}
  172. function space (b : byte): string;
  173. begin
  174. space[0] := chr(b);
  175. FillChar (Space[1],b,' ');
  176. end;
  177. {*****************************************************************************
  178. Str() Helpers
  179. *****************************************************************************}
  180. procedure int_str_real(d : real;len,fr : longint;var s : string);[public, alias : 'STR_REAL'];
  181. begin
  182. {$ifdef i386}
  183. str_real(len,fr,d,rt_s64real,s);
  184. {$else}
  185. str_real(len,fr,d,rt_s32real,s);
  186. {$endif}
  187. end;
  188. {$ifdef SUPPORT_SINGLE}
  189. procedure int_str_single(d : single;len,fr : longint;var s : string);[public, alias : 'STR_SINGLE'];
  190. begin
  191. str_real(len,fr,d,rt_s32real,s);
  192. end;
  193. {$endif SUPPORT_SINGLE}
  194. {$ifdef SUPPORT_EXTENDED}
  195. procedure int_str_extended(d : extended;len,fr : longint;var s : string);[public, alias : 'STR_EXTENDED'];
  196. begin
  197. str_real(len,fr,d,rt_s80real,s);
  198. end;
  199. {$endif SUPPORT_EXTENDED}
  200. {$ifdef SUPPORT_COMP}
  201. procedure int_str_comp(d : comp;len,fr : longint;var s : string);[public, alias : 'STR_COMP'];
  202. begin
  203. str_real(len,fr,d,rt_s64bit,s);
  204. end;
  205. {$endif SUPPORT_COMP}
  206. procedure int_str_fixed(d : fixed;len,fr : longint;var s : string);[public, alias : 'STR_FIXED'];
  207. begin
  208. str_real(len,fr,d,rt_f32bit,s);
  209. end;
  210. procedure int_str_longint(v : longint;len : longint;var s : string);[public, alias : 'STR_LONGINT'];
  211. begin
  212. int_str(v,s);
  213. if length(s)<len then
  214. s:=space(len-length(s))+s;
  215. end;
  216. procedure int_str_cardinal(v : cardinal;len : longint;var s : string);[public, alias : 'STR_CARDINAL'];
  217. begin
  218. int_str(v,s);
  219. if length(s)<len then
  220. s:=space(len-length(s))+s;
  221. end;
  222. {*****************************************************************************
  223. Val() Functions
  224. *****************************************************************************}
  225. Function InitVal(const s:string;var negativ:boolean;var base:byte):Word;
  226. var
  227. Code : Longint;
  228. begin
  229. {Skip Spaces and Tab}
  230. code:=1;
  231. while (code<=length(s)) and (s[code] in [' ',#9]) do
  232. inc(code);
  233. {Sign}
  234. negativ:=false;
  235. case s[code] of
  236. '-' : begin
  237. negativ:=true;
  238. inc(code);
  239. end;
  240. '+' : inc(code);
  241. end;
  242. {Base}
  243. base:=10;
  244. if code<=length(s) then
  245. begin
  246. case s[code] of
  247. '$' : begin
  248. base:=16;
  249. repeat
  250. inc(code);
  251. until (code>=length(s)) or (s[code]<>'0');
  252. if length(s)-code>7 then
  253. code:=code+8;
  254. end;
  255. '%' : begin
  256. base:=2;
  257. inc(code);
  258. end;
  259. end;
  260. end;
  261. InitVal:=code;
  262. end;
  263. procedure val(const s : string;var l : longint;var code : word);
  264. var
  265. base,u : byte;
  266. negativ : boolean;
  267. begin
  268. l:=0;
  269. Code:=InitVal(s,negativ,base);
  270. if Code>length(s) then
  271. exit;
  272. if negativ and (s='-2147483648') then
  273. begin
  274. Code:=0;
  275. l:=$80000000;
  276. exit;
  277. end;
  278. while Code<=Length(s) do
  279. begin
  280. u:=ord(s[code]);
  281. case u of
  282. 48..57 : u:=u-48;
  283. 65..70 : u:=u-55;
  284. 97..104 : u:=u-87;
  285. else
  286. u:=16;
  287. end;
  288. l:=l*longint(base);
  289. if (u>=base) or ((base=10) and (2147483647-l<longint(u))) then
  290. begin
  291. l:=0;
  292. exit;
  293. end;
  294. l:=l+u;
  295. inc(code);
  296. end;
  297. code := 0;
  298. if negativ then
  299. l:=0-l;
  300. end;
  301. procedure val(const s : string;var l : longint;var code : integer);
  302. begin
  303. val(s,l,word(code));
  304. end;
  305. procedure val(const s : string;var l : longint);
  306. var
  307. code : word;
  308. begin
  309. val (s,l,code);
  310. end;
  311. procedure val(const s : string;var b : byte);
  312. var
  313. l : longint;
  314. begin
  315. val(s,l);
  316. b:=l;
  317. end;
  318. procedure val(const s : string;var b : byte;var code : word);
  319. var
  320. l : longint;
  321. begin
  322. val(s,l,code);
  323. b:=l;
  324. end;
  325. procedure val(const s : string;var b : byte;var code : Integer);
  326. begin
  327. val(s,b,word(code));
  328. end;
  329. procedure val(const s : string;var b : shortint);
  330. var
  331. l : longint;
  332. begin
  333. val(s,l);
  334. b:=l;
  335. end;
  336. procedure val(const s : string;var b : shortint;var code : word);
  337. var
  338. l : longint;
  339. begin
  340. val(s,l,code);
  341. b:=l;
  342. end;
  343. procedure val(const s : string;var b : shortint;var code : Integer);
  344. begin
  345. val(s,b,word(code));
  346. end;
  347. procedure val(const s : string;var b : word);
  348. var
  349. l : longint;
  350. begin
  351. val(s,l);
  352. b:=l;
  353. end;
  354. procedure val(const s : string;var b : word;var code : word);
  355. var
  356. l : longint;
  357. begin
  358. val(s,l,code);
  359. b:=l;
  360. end;
  361. procedure val(const s : string;var b : word;var code : Integer);
  362. begin
  363. val(s,b,word(code));
  364. end;
  365. procedure val(const s : string;var b : integer);
  366. var
  367. l : longint;
  368. begin
  369. val(s,l);
  370. b:=l;
  371. end;
  372. procedure val(const s : string;var b : integer;var code : word);
  373. var
  374. l : longint;
  375. begin
  376. val(s,l,code);
  377. b:=l;
  378. end;
  379. procedure val(const s : string;var b : integer;var code : Integer);
  380. begin
  381. val(s,b,word(code));
  382. end;
  383. procedure val(const s : string;var d : real;var code : word);
  384. var
  385. hd,
  386. esign,sign : real;
  387. exponent,i : longint;
  388. flags : byte;
  389. begin
  390. d:=0;
  391. code:=1;
  392. exponent:=0;
  393. esign:=1;
  394. flags:=0;
  395. sign:=1;
  396. while (code<=length(s)) and (s[code] in [' ',#9]) do
  397. inc(code);
  398. case s[code] of
  399. '+' : inc(code);
  400. '-' : begin
  401. sign:=-1.0;
  402. inc(code);
  403. end;
  404. end;
  405. while (Code<=Length(s)) and (s[code] in ['0'..'9']) do
  406. begin
  407. { Read integer part }
  408. flags:=flags or 1;
  409. d:=d*10;
  410. d:=d+(ord(s[code])-ord('0'));
  411. inc(code);
  412. end;
  413. { Decimal ? }
  414. if (s[code]='.') and (length(s)>=code) then
  415. begin
  416. hd:=0.1;
  417. inc(code);
  418. { After dot, a number is required. }
  419. if not(s[code] in ['0'..'9']) or (length(s)<code) then
  420. begin
  421. d:=0.0;
  422. exit;
  423. end;
  424. while (s[code] in ['0'..'9']) and (length(s)>=code) do
  425. begin
  426. { Read fractional part. }
  427. flags:=flags or 2;
  428. d:=d+hd*(ord(s[code])-ord('0'));
  429. hd:=hd/10.0;
  430. inc(code);
  431. end;
  432. end;
  433. { Again, read integer and fractional part}
  434. if flags=0 then
  435. begin
  436. d:=0.0;
  437. exit;
  438. end;
  439. { Exponent ? }
  440. if (upcase(s[code])='E') and (length(s)>=code) then
  441. begin
  442. inc(code);
  443. if s[code]='+' then
  444. inc(code)
  445. else
  446. if s[code]='-' then
  447. begin
  448. esign:=-1;
  449. inc(code);
  450. end;
  451. if not(s[code] in ['0'..'9']) or (length(s)<code) then
  452. begin
  453. d:=0.0;
  454. exit;
  455. end;
  456. while (s[code] in ['0'..'9']) and (length(s)>=code) do
  457. begin
  458. exponent:=exponent*10;
  459. exponent:=exponent+ord(s[code])-ord('0');
  460. inc(code);
  461. end;
  462. end;
  463. { Calculate Exponent }
  464. if esign>0 then
  465. for i:=1 to exponent do
  466. d:=d*10
  467. else
  468. for i:=1 to exponent do
  469. d:=d/10;
  470. { Not all characters are read ? }
  471. if length(s)>=code then
  472. begin
  473. d:=0.0;
  474. exit;
  475. end;
  476. { evalute sign }
  477. d:=d*sign;
  478. { success ! }
  479. code:=0;
  480. end;
  481. procedure val(const s : string;var d : real;var code : integer);
  482. begin
  483. val(s,d,word(code));
  484. end;
  485. procedure val(const s : string;var d : real);
  486. var
  487. code : word;
  488. begin
  489. val(s,d,code);
  490. end;
  491. {$ifdef SUPPORT_SINGLE}
  492. procedure val(const s : string;var d : single;var code : word);
  493. var
  494. e : double;
  495. begin
  496. val(s,e,code);
  497. d:=e;
  498. end;
  499. procedure val(const s : string;var d : single;var code : integer);
  500. var
  501. e : double;
  502. begin
  503. val(s,e,word(code));
  504. d:=e;
  505. end;
  506. procedure val(const s : string;var d : single);
  507. var
  508. code : word;
  509. e : double;
  510. begin
  511. val(s,e,code);
  512. d:=e;
  513. end;
  514. {$endif SUPPORT_SINGLE}
  515. {$ifdef SUPPORT_EXTENDED}
  516. procedure val(const s : string;var d : extended;var code : word);
  517. var
  518. e : double;
  519. begin
  520. val(s,e,code);
  521. d:=e;
  522. end;
  523. procedure val(const s : string;var d : extended;var code : integer);
  524. var
  525. e : double;
  526. begin
  527. val(s,e,word(code));
  528. d:=e;
  529. end;
  530. procedure val(const s : string;var d : extended);
  531. var
  532. code : word;
  533. e : double;
  534. begin
  535. val(s,e,code);
  536. d:=e;
  537. end;
  538. {$endif SUPPORT_EXTENDED}
  539. {$ifdef SUPPORT_COMP}
  540. procedure val(const s : string;var d : comp;var code : word);
  541. var
  542. e : double;
  543. begin
  544. val(s,e,code);
  545. d:=comp(e);
  546. end;
  547. procedure val(const s : string;var d : comp;var code : integer);
  548. var
  549. e : double;
  550. begin
  551. val(s,e,word(code));
  552. d:=comp(e);
  553. end;
  554. procedure val(const s : string;var d : comp);
  555. var
  556. code : word;
  557. e : double;
  558. begin
  559. val(s,e,code);
  560. d:=comp(e);
  561. end;
  562. {$endif SUPPORT_COMP}
  563. procedure val(const s : string;var v : cardinal;var code : word);
  564. var
  565. negativ : boolean;
  566. base,u : byte;
  567. begin
  568. v:=0;
  569. code:=InitVal(s,negativ,base);
  570. if (Code>length(s)) or negativ then
  571. exit;
  572. while Code<=Length(s) do
  573. begin
  574. u:=ord(s[code]);
  575. case u of
  576. 48..57 : u:=u-48;
  577. 65..70 : u:=u-55;
  578. 97..104 : u:=u-87;
  579. else
  580. u:=16;
  581. end;
  582. cardinal(v):=cardinal(v)*cardinal(longint(base));
  583. if (u>base) or (cardinal($ffffffff)-cardinal(v)>cardinal(longint(u))) then
  584. begin
  585. v:=0;
  586. exit;
  587. end;
  588. v:=v+u;
  589. inc(code);
  590. end;
  591. code:=0;
  592. end;
  593. procedure val(const s : string;var v : cardinal);
  594. var
  595. code : word;
  596. begin
  597. val(s,v,code);
  598. end;
  599. procedure val(const s : string;var v : cardinal;var code : integer);
  600. begin
  601. val(s,v,word(code));
  602. end;
  603. {
  604. $Log$
  605. Revision 1.7 1998-07-02 12:14:19 carl
  606. * No SINGLE type for non-intel processors!!
  607. Revision 1.6 1998/06/25 09:44:19 daniel
  608. + RTLLITE directive to compile minimal RTL.
  609. Revision 1.5 1998/06/04 23:45:59 peter
  610. * comp,extended are only i386 added support_comp,support_extended
  611. Revision 1.4 1998/05/31 14:14:52 peter
  612. * removed warnings using comp()
  613. Revision 1.3 1998/05/12 10:42:45 peter
  614. * moved getopts to inc/, all supported OS's need argc,argv exported
  615. + strpas, strlen are now exported in the systemunit
  616. * removed logs
  617. * removed $ifdef ver_above
  618. }