sstrings.inc 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799
  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. function lowercase(c : char) : char;
  119. {$IFDEF IBM_CHAR_SET}
  120. var
  121. i : longint;
  122. {$ENDIF}
  123. begin
  124. if (c in ['A'..'Z']) then
  125. lowercase:=char(byte(c)+32)
  126. else
  127. {$IFDEF IBM_CHAR_SET}
  128. begin
  129. i:=Pos(c,UpCaseTbl);
  130. if i>0 then
  131. lowercase:=LoCaseTbl[i]
  132. else
  133. lowercase:=c;
  134. end;
  135. {$ELSE}
  136. lowercase:=c;
  137. {$ENDIF}
  138. end;
  139. function lowercase(const s : string) : string;
  140. var i : longint;
  141. begin
  142. lowercase [0] := s[0];
  143. for i := 1 to length (s) do
  144. lowercase[i] := lowercase (s[i]);
  145. end;
  146. function space (b : byte): string;
  147. begin
  148. space[0] := chr(b);
  149. FillChar (Space[1],b,' ');
  150. end;
  151. function hexstr(val : longint;cnt : byte) : string;
  152. const
  153. HexTbl : array[0..15] of char='0123456789ABCDEF';
  154. var
  155. i : longint;
  156. begin
  157. hexstr[0]:=char(cnt);
  158. for i:=cnt downto 1 do
  159. begin
  160. hexstr[i]:=hextbl[val and $f];
  161. val:=val shr 4;
  162. end;
  163. end;
  164. function binstr(val : longint;cnt : byte) : string;
  165. var
  166. i : longint;
  167. begin
  168. binstr[0]:=char(cnt);
  169. for i:=cnt downto 1 do
  170. begin
  171. binstr[i]:=char(48+val and 1);
  172. val:=val shr 1;
  173. end;
  174. end;
  175. {$ifndef str_intern }
  176. procedure str(i : integer;var s : string);
  177. begin
  178. str(longint(i),s);
  179. end;
  180. procedure str(si : shortint;var s : string);
  181. begin
  182. str(longint(si),s);
  183. end;
  184. procedure str(b : byte;var s : string);
  185. begin
  186. str(longint(b),s);
  187. end;
  188. procedure str(w : word;var s : string);
  189. begin
  190. str(longint(w),s);
  191. end;
  192. {$ifdef ieee_support}
  193. procedure str(d : double;var s : string);
  194. begin
  195. str_real(-1,-1,d,rt_s64real,s);
  196. end;
  197. {$endif ieee_support}
  198. {$ifndef ieee_support}
  199. { REAL TYPE = single type in this case }
  200. procedure str(d : real;var s : string);
  201. begin
  202. str_real(-1,-1,d,rt_s32real,s);
  203. end;
  204. {$endif ieee_support}
  205. {$else not str_intern }
  206. procedure int_str_real(d : real;len,fr : longint;var s : string);[public, alias : 'STR_REAL'];
  207. begin
  208. {$ifdef i386}
  209. str_real(len,fr,d,rt_s64real,s);
  210. {$else}
  211. str_real(len,fr,d,rt_s32real,s);
  212. {$endif}
  213. end;
  214. {$ifdef support_ieee}
  215. procedure int_str_single(d : single;len,fr : longint;var s : string);[public, alias : 'STR_SINGLE'];
  216. begin
  217. str_real(len,fr,d,rt_s32real,s);
  218. end;
  219. procedure int_str_extended(d : extended;len,fr : longint;var s : string);[public, alias : 'STR_EXTENDED'];
  220. begin
  221. str_real(len,fr,d,rt_s80real,s);
  222. end;
  223. {$endif support_ieee}
  224. {$ifdef support_comp}
  225. procedure int_str_comp(d : comp;len,fr : longint;var s : string);[public, alias : 'STR_COMP'];
  226. begin
  227. str_real(len,fr,d,rt_s64bit,s);
  228. end;
  229. {$endif support_comp}
  230. procedure int_str_fixed(d : fixed;len,fr : longint;var s : string);[public, alias : 'STR_FIXED'];
  231. begin
  232. str_real(len,fr,d,rt_f32bit,s);
  233. end;
  234. procedure int_str_longint(v : longint;len : longint;var s : string);[public, alias : 'STR_LONGINT'];
  235. begin
  236. int_str(v,s);
  237. if length(s)<len then
  238. s:=space(len-length(s))+s;
  239. end;
  240. {$ifdef ver_above0_9_8}
  241. procedure int_str_cardinal(v : cardinal;len : longint;var s : string);[public, alias : 'STR_CARDINAL'];
  242. var
  243. d : real;
  244. begin
  245. int_str(v,s);
  246. if length(s)<len then
  247. s:=space(len-length(s))+s;
  248. end;
  249. {$endif ver_above0_9_8}
  250. {$endif str_intern }
  251. procedure val(const s : string;var d : real;var code : word);
  252. var
  253. { faster on a pentium }
  254. esign,sign : real;
  255. i : longint;
  256. exponent : longint;
  257. flags : byte;
  258. hd : real;
  259. begin
  260. d:=0;
  261. code:=1;
  262. exponent:=0;
  263. esign:=1;
  264. flags:=0;
  265. sign:=1;
  266. while (code<=length(s)) and (s[code] in [' ',#9]) do
  267. inc(code);
  268. case s[code] of
  269. '+' : inc(code);
  270. '-' : begin
  271. sign:=-1.0;
  272. inc(code);
  273. end;
  274. end;
  275. while (Code<=Length(s)) and (s[code] in ['0'..'9']) do
  276. begin
  277. { Read integer part }
  278. flags:=flags or 1;
  279. d:=d*10;
  280. d:=d+(ord(s[code])-ord('0'));
  281. inc(code);
  282. end;
  283. { Decimal ? }
  284. if (s[code]='.') and (length(s)>=code) then
  285. begin
  286. hd:=0.1;
  287. inc(code);
  288. { After dot, a number is required. }
  289. if not(s[code] in ['0'..'9']) or (length(s)<code) then
  290. begin
  291. d:=0.0;
  292. exit;
  293. end;
  294. while (s[code] in ['0'..'9']) and (length(s)>=code) do
  295. begin
  296. { Read fractional part. }
  297. flags:=flags or 2;
  298. d:=d+hd*(ord(s[code])-ord('0'));
  299. hd:=hd/10.0;
  300. inc(code);
  301. end;
  302. end;
  303. { Again, read integer and fractional part}
  304. if flags=0 then
  305. begin
  306. d:=0.0;
  307. exit;
  308. end;
  309. { Exponent ? }
  310. if (upcase(s[code])='E') and (length(s)>=code) then
  311. begin
  312. inc(code);
  313. if s[code]='+' then
  314. inc(code)
  315. else if s[code]='-' then
  316. begin
  317. esign:=-1;
  318. inc(code);
  319. end;
  320. if not(s[code] in ['0'..'9']) or (length(s)<code) then
  321. begin
  322. d:=0.0;
  323. exit;
  324. end;
  325. while (s[code] in ['0'..'9']) and (length(s)>=code) do
  326. begin
  327. exponent:=exponent*10;
  328. exponent:=exponent+ord(s[code])-ord('0');
  329. inc(code);
  330. end;
  331. end;
  332. { Calculate Exponent }
  333. if esign>0 then
  334. for i:=1 to exponent do
  335. d:=d*10
  336. else
  337. for i:=1 to exponent do
  338. d:=d/10;
  339. { Not all characters are read ? }
  340. if length(s)>=code then
  341. begin
  342. d:=0.0;
  343. exit;
  344. end;
  345. { evalute sign }
  346. d:=d*sign;
  347. { success ! }
  348. code:=0;
  349. end;
  350. procedure val(const s : string;var d : real;var code : integer);
  351. begin
  352. val(s,d,word(code));
  353. end;
  354. procedure val(const s : string;var d : real);
  355. var code : word;
  356. begin
  357. val(s,d,code);
  358. end;
  359. {$ifdef ver_above0_9_2}
  360. {$IFDEF ieee_support}
  361. procedure val(const s : string;var d : single;var code : word);
  362. var e : double;
  363. begin
  364. val(s,e,code);
  365. d:=e;
  366. end;
  367. procedure val(const s : string;var d : single;var code : integer);
  368. var e : double;
  369. begin
  370. val(s,e,word(code));
  371. d:=e;
  372. end;
  373. procedure val(const s : string;var d : single);
  374. var code : word;
  375. e : double;
  376. begin
  377. val(s,e,code);
  378. d:=e;
  379. end;
  380. {$ENDIF ieee_support}
  381. {$endif ver_above0_9_2}
  382. {$ifdef ver_above0_9_7}
  383. {$ifdef ieee_support}
  384. procedure val(const s : string;var d : extended;var code : word);
  385. var e : double;
  386. begin
  387. val(s,e,code);
  388. d:=e;
  389. end;
  390. procedure val(const s : string;var d : extended;var code : integer);
  391. var e : double;
  392. begin
  393. val(s,e,word(code));
  394. d:=e;
  395. end;
  396. procedure val(const s : string;var d : extended);
  397. var code : word;
  398. e : double;
  399. begin
  400. val(s,e,code);
  401. d:=e;
  402. end;
  403. {$endif ieee_support}
  404. {$ifdef comp_support}
  405. procedure val(const s : string;var d : comp;var code : word);
  406. var e : double;
  407. begin
  408. val(s,e,code);
  409. d:=e;
  410. end;
  411. procedure val(const s : string;var d : comp;var code : integer);
  412. var e : double;
  413. begin
  414. val(s,e,word(code));
  415. d:=e;
  416. end;
  417. procedure val(const s : string;var d : comp);
  418. var code : word;
  419. e : double;
  420. begin
  421. val(s,e,code);
  422. d:=e;
  423. end;
  424. {$endif comp_support}
  425. {$endif ver_above0_9_7}
  426. Function InitVal(const s:string;var negativ:boolean;var base:byte):Word;
  427. var
  428. Code : Longint;
  429. begin
  430. {Skip Spaces and Tab}
  431. code:=1;
  432. while (code<=length(s)) and (s[code] in [' ',#9]) do
  433. inc(code);
  434. {Sign}
  435. negativ:=false;
  436. case s[code] of
  437. '-' : begin
  438. negativ:=true;
  439. inc(code);
  440. end;
  441. '+' : inc(code);
  442. end;
  443. {Base}
  444. base:=10;
  445. if code<=length(s) then
  446. begin
  447. case s[code] of
  448. '$' : begin
  449. base:=16;
  450. repeat
  451. inc(code);
  452. until (code>=length(s)) or (s[code]<>'0');
  453. if length(s)-code>7 then
  454. inc(code,8);
  455. end;
  456. '%' : begin
  457. base:=2;
  458. inc(code);
  459. end;
  460. end;
  461. end;
  462. InitVal:=code;
  463. end;
  464. procedure val(const s : string;var v : longint;var code : word);
  465. var
  466. base,u : byte;
  467. negativ : boolean;
  468. begin
  469. v:=0;
  470. Code:=InitVal(s,negativ,base);
  471. if Code>length(s) then
  472. exit;
  473. if negativ and (s='-2147483648') then
  474. begin
  475. Code:=0;
  476. v:=$80000000;
  477. exit;
  478. end;
  479. while Code<=Length(s) do
  480. begin
  481. u:=ord(s[code]);
  482. case u of
  483. 48..57 : dec(u,48);
  484. 65..70 : dec(u,55);
  485. 97..104 : dec(u,87);
  486. else
  487. u:=16;
  488. end;
  489. v:=v*longint(base);
  490. if (u>=base) or ((base=10) and (2147483647-v<longint(u))) then
  491. begin
  492. v:=0;
  493. exit;
  494. end;
  495. inc(v,u);
  496. inc(code);
  497. end;
  498. code := 0;
  499. if negativ then
  500. v:=0-v;
  501. end;
  502. procedure val(const s : string;var l : longint;var code : integer);
  503. begin
  504. val(s,l,word(code));
  505. end;
  506. procedure val(const s : string;var l : longint);
  507. var
  508. code : word;
  509. begin
  510. val (s,l,code);
  511. end;
  512. procedure val(const s : string;var b : byte);
  513. var
  514. l : longint;
  515. begin
  516. val(s,l);
  517. b:=l;
  518. end;
  519. procedure val(const s : string;var b : byte;var code : word);
  520. var
  521. l : longint;
  522. begin
  523. val(s,l,code);
  524. b:=l;
  525. end;
  526. procedure val(const s : string;var b : byte;var code : Integer);
  527. begin
  528. val(s,b,word(code));
  529. end;
  530. procedure val(const s : string;var b : shortint);
  531. var
  532. l : longint;
  533. begin
  534. val(s,l);
  535. b:=l;
  536. end;
  537. procedure val(const s : string;var b : shortint;var code : word);
  538. var
  539. l : longint;
  540. begin
  541. val(s,l,code);
  542. b:=l;
  543. end;
  544. procedure val(const s : string;var b : shortint;var code : Integer);
  545. begin
  546. val(s,b,word(code));
  547. end;
  548. procedure val(const s : string;var b : word);
  549. var
  550. l : longint;
  551. begin
  552. val(s,l);
  553. b:=l;
  554. end;
  555. procedure val(const s : string;var b : word;var code : word);
  556. var
  557. l : longint;
  558. begin
  559. val(s,l,code);
  560. b:=l;
  561. end;
  562. procedure val(const s : string;var b : word;var code : Integer);
  563. begin
  564. val(s,b,word(code));
  565. end;
  566. procedure val(const s : string;var b : integer);
  567. var
  568. l : longint;
  569. begin
  570. val(s,l);
  571. b:=l;
  572. end;
  573. procedure val(const s : string;var b : integer;var code : word);
  574. var
  575. l : longint;
  576. begin
  577. val(s,l,code);
  578. b:=l;
  579. end;
  580. procedure val(const s : string;var b : integer;var code : Integer);
  581. begin
  582. val(s,b,word(code));
  583. end;
  584. {$ifdef ver_above0_9_8}
  585. procedure val(const s : string;var v : cardinal;var code : word);
  586. var
  587. negativ : boolean;
  588. base,u : byte;
  589. begin
  590. v:=0;
  591. code:=InitVal(s,negativ,base);
  592. if (Code>length(s)) or negativ then
  593. exit;
  594. while Code<=Length(s) do
  595. begin
  596. u:=ord(s[code]);
  597. case u of
  598. 48..57 : dec(u,48);
  599. 65..70 : dec(u,55);
  600. 97..104 : dec(u,87);
  601. else
  602. u:=16;
  603. end;
  604. cardinal(v):=cardinal(v)*cardinal(longint(base));
  605. if (u>base) or (cardinal($ffffffff)-cardinal(v)>cardinal(longint(u))) then
  606. begin
  607. v:=0;
  608. exit;
  609. end;
  610. inc(v,u);
  611. inc(code);
  612. end;
  613. code:=0;
  614. end;
  615. procedure val(const s : string;var v : cardinal);
  616. var
  617. code : word;
  618. begin
  619. val(s,v,code);
  620. end;
  621. procedure val(const s : string;var v : cardinal;var code : integer);
  622. begin
  623. val(s,v,word(code));
  624. end;
  625. {$endif ver_above0_9_8}
  626. {
  627. $Log$
  628. Revision 1.2 1998-03-26 14:41:22 michael
  629. + Added comp support for val and read(ln)
  630. Revision 1.1.1.1 1998/03/25 11:18:43 root
  631. * Restored version
  632. Revision 1.8 1998/03/18 15:04:36 pierre
  633. * bug in val : a was accepted as 10 in base 10 !!
  634. Revision 1.7 1998/02/11 16:55:18 michael
  635. fixed cardinal printing. Large cardinals (>0fffffff) not yet working
  636. Revision 1.6 1998/02/08 23:57:51 peter
  637. * fixed val(longint) so it works again with $80000000+
  638. Revision 1.5 1998/02/08 21:51:40 peter
  639. * some optimizes and Val(cardinal) fixed
  640. Revision 1.4 1998/01/26 12:00:13 michael
  641. + Added log at the end
  642. revision 1.3
  643. date: 1998/01/23 12:06:05; author: daniel; state: Exp; lines: +18 -22
  644. * Did some small code tweaks.
  645. ----------------------------
  646. revision 1.2
  647. date: 1998/01/12 02:31:44; author: carl; state: Exp; lines: +30 -9
  648. + added generic Floating point support/fixes for m68k port and other ports
  649. ----------------------------
  650. revision 1.1
  651. date: 1997/12/22 18:54:25; author: michael; state: Exp;
  652. + Initial implementation: moved all strings routines from system.inc to
  653. sstrings.inc.
  654. =============================================================================
  655. }