sstrings.inc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768
  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. { Again, not fast, but solid and understandable. }
  382. {$endif ver_above0_9_2}
  383. {$ifdef ver_above0_9_7}
  384. {$ifdef ieee_support}
  385. procedure val(const s : string;var d : extended;var code : word);
  386. var e : double;
  387. begin
  388. val(s,e,code);
  389. d:=e;
  390. end;
  391. procedure val(const s : string;var d : extended;var code : integer);
  392. var e : double;
  393. begin
  394. val(s,e,word(code));
  395. d:=e;
  396. end;
  397. procedure val(const s : string;var d : extended);
  398. var code : word;
  399. e : double;
  400. begin
  401. val(s,e,code);
  402. d:=e;
  403. end;
  404. {$endif ieee_support}
  405. {$endif ver_above0_9_7}
  406. Function InitVal(const s:string;var negativ:boolean;var base:byte):Word;
  407. var
  408. Code : Longint;
  409. begin
  410. {Skip Spaces and Tab}
  411. code:=1;
  412. while (code<=length(s)) and (s[code] in [' ',#9]) do
  413. inc(code);
  414. {Sign}
  415. negativ:=false;
  416. case s[code] of
  417. '-' : begin
  418. negativ:=true;
  419. inc(code);
  420. end;
  421. '+' : inc(code);
  422. end;
  423. {Base}
  424. base:=10;
  425. if code<=length(s) then
  426. begin
  427. case s[code] of
  428. '$' : begin
  429. base:=16;
  430. repeat
  431. inc(code);
  432. until (code>=length(s)) or (s[code]<>'0');
  433. if length(s)-code>7 then
  434. inc(code,8);
  435. end;
  436. '%' : begin
  437. base:=2;
  438. inc(code);
  439. end;
  440. end;
  441. end;
  442. InitVal:=code;
  443. end;
  444. procedure val(const s : string;var v : longint;var code : word);
  445. var
  446. base,u : byte;
  447. negativ : boolean;
  448. begin
  449. v:=0;
  450. Code:=InitVal(s,negativ,base);
  451. if Code>length(s) then
  452. exit;
  453. if negativ and (s='-2147483648') then
  454. begin
  455. Code:=0;
  456. v:=$80000000;
  457. exit;
  458. end;
  459. while Code<=Length(s) do
  460. begin
  461. u:=ord(s[code]);
  462. case u of
  463. 48..57 : dec(u,48);
  464. 65..70 : dec(u,55);
  465. 97..104 : dec(u,87);
  466. else
  467. u:=16;
  468. end;
  469. v:=v*longint(base);
  470. if (u>=base) or ((base=10) and (2147483647-v<longint(u))) then
  471. begin
  472. v:=0;
  473. exit;
  474. end;
  475. inc(v,u);
  476. inc(code);
  477. end;
  478. code := 0;
  479. if negativ then
  480. v:=0-v;
  481. end;
  482. procedure val(const s : string;var l : longint;var code : integer);
  483. begin
  484. val(s,l,word(code));
  485. end;
  486. procedure val(const s : string;var l : longint);
  487. var
  488. code : word;
  489. begin
  490. val (s,l,code);
  491. end;
  492. procedure val(const s : string;var b : byte);
  493. var
  494. l : longint;
  495. begin
  496. val(s,l);
  497. b:=l;
  498. end;
  499. procedure val(const s : string;var b : byte;var code : word);
  500. var
  501. l : longint;
  502. begin
  503. val(s,l,code);
  504. b:=l;
  505. end;
  506. procedure val(const s : string;var b : byte;var code : Integer);
  507. begin
  508. val(s,b,word(code));
  509. end;
  510. procedure val(const s : string;var b : shortint);
  511. var
  512. l : longint;
  513. begin
  514. val(s,l);
  515. b:=l;
  516. end;
  517. procedure val(const s : string;var b : shortint;var code : word);
  518. var
  519. l : longint;
  520. begin
  521. val(s,l,code);
  522. b:=l;
  523. end;
  524. procedure val(const s : string;var b : shortint;var code : Integer);
  525. begin
  526. val(s,b,word(code));
  527. end;
  528. procedure val(const s : string;var b : word);
  529. var
  530. l : longint;
  531. begin
  532. val(s,l);
  533. b:=l;
  534. end;
  535. procedure val(const s : string;var b : word;var code : word);
  536. var
  537. l : longint;
  538. begin
  539. val(s,l,code);
  540. b:=l;
  541. end;
  542. procedure val(const s : string;var b : word;var code : Integer);
  543. begin
  544. val(s,b,word(code));
  545. end;
  546. procedure val(const s : string;var b : integer);
  547. var
  548. l : longint;
  549. begin
  550. val(s,l);
  551. b:=l;
  552. end;
  553. procedure val(const s : string;var b : integer;var code : word);
  554. var
  555. l : longint;
  556. begin
  557. val(s,l,code);
  558. b:=l;
  559. end;
  560. procedure val(const s : string;var b : integer;var code : Integer);
  561. begin
  562. val(s,b,word(code));
  563. end;
  564. {$ifdef ver_above0_9_8}
  565. procedure val(const s : string;var v : cardinal;var code : word);
  566. var
  567. negativ : boolean;
  568. base,u : byte;
  569. begin
  570. v:=0;
  571. code:=InitVal(s,negativ,base);
  572. if (Code>length(s)) or negativ then
  573. exit;
  574. while Code<=Length(s) do
  575. begin
  576. u:=ord(s[code]);
  577. case u of
  578. 48..57 : dec(u,48);
  579. 65..70 : dec(u,55);
  580. 97..104 : dec(u,87);
  581. else
  582. u:=16;
  583. end;
  584. cardinal(v):=cardinal(v)*cardinal(longint(base));
  585. if (u>base) or (cardinal($ffffffff)-cardinal(v)>cardinal(longint(u))) then
  586. begin
  587. v:=0;
  588. exit;
  589. end;
  590. inc(v,u);
  591. inc(code);
  592. end;
  593. code:=0;
  594. end;
  595. procedure val(const s : string;var v : cardinal);
  596. var
  597. code : word;
  598. begin
  599. val(s,v,code);
  600. end;
  601. procedure val(const s : string;var v : cardinal;var code : integer);
  602. begin
  603. val(s,v,word(code));
  604. end;
  605. {$endif ver_above0_9_8}
  606. {
  607. $Log$
  608. Revision 1.1 1998-03-25 11:18:43 root
  609. Initial revision
  610. Revision 1.8 1998/03/18 15:04:36 pierre
  611. * bug in val : a was accepted as 10 in base 10 !!
  612. Revision 1.7 1998/02/11 16:55:18 michael
  613. fixed cardinal printing. Large cardinals (>0fffffff) not yet working
  614. Revision 1.6 1998/02/08 23:57:51 peter
  615. * fixed val(longint) so it works again with $80000000+
  616. Revision 1.5 1998/02/08 21:51:40 peter
  617. * some optimizes and Val(cardinal) fixed
  618. Revision 1.4 1998/01/26 12:00:13 michael
  619. + Added log at the end
  620. revision 1.3
  621. date: 1998/01/23 12:06:05; author: daniel; state: Exp; lines: +18 -22
  622. * Did some small code tweaks.
  623. ----------------------------
  624. revision 1.2
  625. date: 1998/01/12 02:31:44; author: carl; state: Exp; lines: +30 -9
  626. + added generic Floating point support/fixes for m68k port and other ports
  627. ----------------------------
  628. revision 1.1
  629. date: 1997/12/22 18:54:25; author: michael; state: Exp;
  630. + Initial implementation: moved all strings routines from system.inc to
  631. sstrings.inc.
  632. =============================================================================
  633. }