sstrings.inc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  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. {$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 : real;var code : word);
  386. var
  387. hd,
  388. esign,sign : real;
  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 : real;var code : integer);
  484. begin
  485. val(s,d,word(code));
  486. end;
  487. procedure val(const s : string;var d : real);
  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 : double;
  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 : double;
  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 SUPPORT_EXTENDED}
  518. procedure val(const s : string;var d : extended;var code : word);
  519. var
  520. e : double;
  521. begin
  522. val(s,e,code);
  523. d:=e;
  524. end;
  525. procedure val(const s : string;var d : extended;var code : integer);
  526. var
  527. e : double;
  528. begin
  529. val(s,e,word(code));
  530. d:=e;
  531. end;
  532. procedure val(const s : string;var d : extended);
  533. var
  534. code : word;
  535. e : double;
  536. begin
  537. val(s,e,code);
  538. d:=e;
  539. end;
  540. {$endif SUPPORT_EXTENDED}
  541. {$ifdef SUPPORT_COMP}
  542. procedure val(const s : string;var d : comp;var code : word);
  543. var
  544. e : double;
  545. begin
  546. val(s,e,code);
  547. d:=comp(e);
  548. end;
  549. procedure val(const s : string;var d : comp;var code : integer);
  550. var
  551. e : double;
  552. begin
  553. val(s,e,word(code));
  554. d:=comp(e);
  555. end;
  556. procedure val(const s : string;var d : comp);
  557. var
  558. code : word;
  559. e : double;
  560. begin
  561. val(s,e,code);
  562. d:=comp(e);
  563. end;
  564. {$endif SUPPORT_COMP}
  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 : u:=u-48;
  579. 65..70 : u:=u-55;
  580. 97..104 : u:=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. v:=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. {
  606. $Log$
  607. Revision 1.8 1998-07-10 11:02:38 peter
  608. * support_fixed, becuase fixed is not 100% yet for the m68k
  609. Revision 1.7 1998/07/02 12:14:19 carl
  610. * No SINGLE type for non-intel processors!!
  611. Revision 1.6 1998/06/25 09:44:19 daniel
  612. + RTLLITE directive to compile minimal RTL.
  613. Revision 1.5 1998/06/04 23:45:59 peter
  614. * comp,extended are only i386 added support_comp,support_extended
  615. Revision 1.4 1998/05/31 14:14:52 peter
  616. * removed warnings using comp()
  617. Revision 1.3 1998/05/12 10:42:45 peter
  618. * moved getopts to inc/, all supported OS's need argc,argv exported
  619. + strpas, strlen are now exported in the systemunit
  620. * removed logs
  621. * removed $ifdef ver_above
  622. }