sstrings.inc 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786
  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 : StrLenInt;count : StrLenInt): 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 : StrLenInt;count : StrLenInt);
  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 : StrLenInt);
  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. {$ifdef SUPPORT_FIXED}
  207. procedure int_str_fixed(d : fixed;len,fr : longint;var s : string);[public, alias : 'STR_FIXED'];
  208. begin
  209. str_real(len,fr,d,rt_f32bit,s);
  210. end;
  211. {$endif SUPPORT_FIXED}
  212. procedure int_str_longint(v : longint;len : longint;var s : string);[public, alias : 'STR_LONGINT'];
  213. begin
  214. int_str(v,s);
  215. if length(s)<len then
  216. s:=space(len-length(s))+s;
  217. end;
  218. procedure int_str_cardinal(v : cardinal;len : longint;var s : string);[public, alias : 'STR_CARDINAL'];
  219. begin
  220. int_str(v,s);
  221. if length(s)<len then
  222. s:=space(len-length(s))+s;
  223. end;
  224. {*****************************************************************************
  225. Val() Functions
  226. *****************************************************************************}
  227. Function InitVal(const s:string;var negativ:boolean;var base:byte):Word;
  228. var
  229. Code : Longint;
  230. begin
  231. {Skip Spaces and Tab}
  232. code:=1;
  233. while (code<=length(s)) and (s[code] in [' ',#9]) do
  234. inc(code);
  235. {Sign}
  236. negativ:=false;
  237. case s[code] of
  238. '-' : begin
  239. negativ:=true;
  240. inc(code);
  241. end;
  242. '+' : inc(code);
  243. end;
  244. {Base}
  245. base:=10;
  246. if code<=length(s) then
  247. begin
  248. case s[code] of
  249. '$' : begin
  250. base:=16;
  251. repeat
  252. inc(code);
  253. until (code>=length(s)) or (s[code]<>'0');
  254. if length(s)-code>7 then
  255. code:=code+8;
  256. end;
  257. '%' : begin
  258. base:=2;
  259. inc(code);
  260. end;
  261. end;
  262. end;
  263. InitVal:=code;
  264. end;
  265. procedure val(const s : string;var l : longint;var code : word);
  266. var
  267. base,u : byte;
  268. negativ : boolean;
  269. begin
  270. l:=0;
  271. Code:=InitVal(s,negativ,base);
  272. if Code>length(s) then
  273. exit;
  274. if negativ and (s='-2147483648') then
  275. begin
  276. Code:=0;
  277. l:=$80000000;
  278. exit;
  279. end;
  280. while Code<=Length(s) do
  281. begin
  282. u:=ord(s[code]);
  283. case u of
  284. 48..57 : u:=u-48;
  285. 65..70 : u:=u-55;
  286. 97..104 : u:=u-87;
  287. else
  288. u:=16;
  289. end;
  290. l:=l*longint(base);
  291. if (u>=base) or ((base=10) and (2147483647-l<longint(u))) then
  292. begin
  293. l:=0;
  294. exit;
  295. end;
  296. l:=l+u;
  297. inc(code);
  298. end;
  299. code := 0;
  300. if negativ then
  301. l:=0-l;
  302. end;
  303. procedure val(const s : string;var l : longint;var code : integer);
  304. begin
  305. val(s,l,word(code));
  306. end;
  307. procedure val(const s : string;var l : longint);
  308. var
  309. code : word;
  310. begin
  311. val (s,l,code);
  312. end;
  313. procedure val(const s : string;var b : byte);
  314. var
  315. l : longint;
  316. begin
  317. val(s,l);
  318. b:=l;
  319. end;
  320. procedure val(const s : string;var b : byte;var code : word);
  321. var
  322. l : longint;
  323. begin
  324. val(s,l,code);
  325. b:=l;
  326. end;
  327. procedure val(const s : string;var b : byte;var code : Integer);
  328. begin
  329. val(s,b,word(code));
  330. end;
  331. procedure val(const s : string;var b : shortint);
  332. var
  333. l : longint;
  334. begin
  335. val(s,l);
  336. b:=l;
  337. end;
  338. procedure val(const s : string;var b : shortint;var code : word);
  339. var
  340. l : longint;
  341. begin
  342. val(s,l,code);
  343. b:=l;
  344. end;
  345. procedure val(const s : string;var b : shortint;var code : Integer);
  346. begin
  347. val(s,b,word(code));
  348. end;
  349. procedure val(const s : string;var b : word);
  350. var
  351. l : longint;
  352. begin
  353. val(s,l);
  354. b:=l;
  355. end;
  356. procedure val(const s : string;var b : word;var code : word);
  357. var
  358. l : longint;
  359. begin
  360. val(s,l,code);
  361. b:=l;
  362. end;
  363. procedure val(const s : string;var b : word;var code : Integer);
  364. begin
  365. val(s,b,word(code));
  366. end;
  367. procedure val(const s : string;var b : integer);
  368. var
  369. l : longint;
  370. begin
  371. val(s,l);
  372. b:=l;
  373. end;
  374. procedure val(const s : string;var b : integer;var code : word);
  375. var
  376. l : longint;
  377. begin
  378. val(s,l,code);
  379. b:=l;
  380. end;
  381. procedure val(const s : string;var b : integer;var code : Integer);
  382. begin
  383. val(s,b,word(code));
  384. end;
  385. procedure val(const s : string;var d : valreal;var code : word);
  386. var
  387. hd,
  388. esign,sign : valreal;
  389. exponent,i : longint;
  390. flags : byte;
  391. begin
  392. d:=0;
  393. code:=1;
  394. exponent:=0;
  395. esign:=1;
  396. flags:=0;
  397. sign:=1;
  398. while (code<=length(s)) and (s[code] in [' ',#9]) do
  399. inc(code);
  400. case s[code] of
  401. '+' : inc(code);
  402. '-' : begin
  403. sign:=-1.0;
  404. inc(code);
  405. end;
  406. end;
  407. while (Code<=Length(s)) and (s[code] in ['0'..'9']) do
  408. begin
  409. { Read integer part }
  410. flags:=flags or 1;
  411. d:=d*10;
  412. d:=d+(ord(s[code])-ord('0'));
  413. inc(code);
  414. end;
  415. { Decimal ? }
  416. if (s[code]='.') and (length(s)>=code) then
  417. begin
  418. hd:=0.1;
  419. inc(code);
  420. { After dot, a number is required. }
  421. if not(s[code] in ['0'..'9']) or (length(s)<code) then
  422. begin
  423. d:=0.0;
  424. exit;
  425. end;
  426. while (s[code] in ['0'..'9']) and (length(s)>=code) do
  427. begin
  428. { Read fractional part. }
  429. flags:=flags or 2;
  430. d:=d+hd*(ord(s[code])-ord('0'));
  431. hd:=hd/10.0;
  432. inc(code);
  433. end;
  434. end;
  435. { Again, read integer and fractional part}
  436. if flags=0 then
  437. begin
  438. d:=0.0;
  439. exit;
  440. end;
  441. { Exponent ? }
  442. if (upcase(s[code])='E') and (length(s)>=code) then
  443. begin
  444. inc(code);
  445. if s[code]='+' then
  446. inc(code)
  447. else
  448. if s[code]='-' then
  449. begin
  450. esign:=-1;
  451. inc(code);
  452. end;
  453. if not(s[code] in ['0'..'9']) or (length(s)<code) then
  454. begin
  455. d:=0.0;
  456. exit;
  457. end;
  458. while (s[code] in ['0'..'9']) and (length(s)>=code) do
  459. begin
  460. exponent:=exponent*10;
  461. exponent:=exponent+ord(s[code])-ord('0');
  462. inc(code);
  463. end;
  464. end;
  465. { Calculate Exponent }
  466. if esign>0 then
  467. for i:=1 to exponent do
  468. d:=d*10
  469. else
  470. for i:=1 to exponent do
  471. d:=d/10;
  472. { Not all characters are read ? }
  473. if length(s)>=code then
  474. begin
  475. d:=0.0;
  476. exit;
  477. end;
  478. { evalute sign }
  479. d:=d*sign;
  480. { success ! }
  481. code:=0;
  482. end;
  483. procedure val(const s : string;var d : valreal;var code : integer);
  484. begin
  485. val(s,d,word(code));
  486. end;
  487. procedure val(const s : string;var d : valreal);
  488. var
  489. code : word;
  490. begin
  491. val(s,d,code);
  492. end;
  493. {$ifdef SUPPORT_SINGLE}
  494. procedure val(const s : string;var d : single;var code : word);
  495. var
  496. e : valreal;
  497. begin
  498. val(s,e,code);
  499. d:=e;
  500. end;
  501. procedure val(const s : string;var d : single;var code : integer);
  502. var
  503. e : valreal;
  504. begin
  505. val(s,e,word(code));
  506. d:=e;
  507. end;
  508. procedure val(const s : string;var d : single);
  509. var
  510. code : word;
  511. e : double;
  512. begin
  513. val(s,e,code);
  514. d:=e;
  515. end;
  516. {$endif SUPPORT_SINGLE}
  517. {$ifdef DEFAULT_EXTENDED}
  518. { with extended as default the valreal is extended so for real there need
  519. to be a new val }
  520. procedure val(const s : string;var d : real;var code : word);
  521. var
  522. e : valreal;
  523. begin
  524. val(s,e,code);
  525. d:=e;
  526. end;
  527. procedure val(const s : string;var d : real;var code : integer);
  528. var
  529. e : valreal;
  530. begin
  531. val(s,e,word(code));
  532. d:=e;
  533. end;
  534. procedure val(const s : string;var d : real);
  535. var
  536. code : word;
  537. e : valreal;
  538. begin
  539. val(s,e,code);
  540. d:=e;
  541. end;
  542. {$else DEFAULT_EXTENDED}
  543. { when extended is not the default it could still be supported }
  544. {$ifdef SUPPORT_EXTENDED}
  545. procedure val(const s : string;var d : extended;var code : word);
  546. var
  547. e : valreal;
  548. begin
  549. val(s,e,code);
  550. d:=e;
  551. end;
  552. procedure val(const s : string;var d : extended;var code : integer);
  553. var
  554. e : valreal;
  555. begin
  556. val(s,e,word(code));
  557. d:=e;
  558. end;
  559. procedure val(const s : string;var d : extended);
  560. var
  561. code : word;
  562. e : valreal;
  563. begin
  564. val(s,e,code);
  565. d:=e;
  566. end;
  567. {$endif SUPPORT_EXTENDED}
  568. {$endif DEFAULT_EXTENDED}
  569. {$ifdef SUPPORT_COMP}
  570. procedure val(const s : string;var d : comp;var code : word);
  571. var
  572. e : valreal;
  573. begin
  574. val(s,e,code);
  575. d:=comp(e);
  576. end;
  577. procedure val(const s : string;var d : comp;var code : integer);
  578. var
  579. e : valreal;
  580. begin
  581. val(s,e,word(code));
  582. d:=comp(e);
  583. end;
  584. procedure val(const s : string;var d : comp);
  585. var
  586. code : word;
  587. e : valreal;
  588. begin
  589. val(s,e,code);
  590. d:=comp(e);
  591. end;
  592. {$endif SUPPORT_COMP}
  593. procedure val(const s : string;var v : cardinal;var code : word);
  594. var
  595. negativ : boolean;
  596. base,u : byte;
  597. begin
  598. v:=0;
  599. code:=InitVal(s,negativ,base);
  600. if (Code>length(s)) or negativ then
  601. exit;
  602. while Code<=Length(s) do
  603. begin
  604. u:=ord(s[code]);
  605. case u of
  606. 48..57 : u:=u-48;
  607. 65..70 : u:=u-55;
  608. 97..104 : u:=u-87;
  609. else
  610. u:=16;
  611. end;
  612. cardinal(v):=cardinal(v)*cardinal(longint(base));
  613. if (u>base) or (cardinal($ffffffff)-cardinal(v)>cardinal(longint(u))) then
  614. begin
  615. v:=0;
  616. exit;
  617. end;
  618. v:=v+u;
  619. inc(code);
  620. end;
  621. code:=0;
  622. end;
  623. procedure val(const s : string;var v : cardinal);
  624. var
  625. code : word;
  626. begin
  627. val(s,v,code);
  628. end;
  629. procedure val(const s : string;var v : cardinal;var code : integer);
  630. begin
  631. val(s,v,word(code));
  632. end;
  633. {
  634. $Log$
  635. Revision 1.11 1998-08-11 21:39:07 peter
  636. * splitted default_extended from support_extended
  637. Revision 1.10 1998/08/08 12:28:13 florian
  638. * a lot small fixes to the extended data type work
  639. Revision 1.9 1998/07/18 17:14:23 florian
  640. * strlenint type implemented
  641. Revision 1.8 1998/07/10 11:02:38 peter
  642. * support_fixed, becuase fixed is not 100% yet for the m68k
  643. Revision 1.7 1998/07/02 12:14:19 carl
  644. * No SINGLE type for non-intel processors!!
  645. Revision 1.6 1998/06/25 09:44:19 daniel
  646. + RTLLITE directive to compile minimal RTL.
  647. Revision 1.5 1998/06/04 23:45:59 peter
  648. * comp,extended are only i386 added support_comp,support_extended
  649. Revision 1.4 1998/05/31 14:14:52 peter
  650. * removed warnings using comp()
  651. Revision 1.3 1998/05/12 10:42:45 peter
  652. * moved getopts to inc/, all supported OS's need argc,argv exported
  653. + strpas, strlen are now exported in the systemunit
  654. * removed logs
  655. * removed $ifdef ver_above
  656. }