sstrings.inc 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 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. {$ifndef INTERNSETLENGTH}
  15. procedure SetLength(var s:shortstring;len:StrLenInt);
  16. {$else INTERNSETLENGTH}
  17. procedure fpc_Shortstr_SetLength(var s:shortstring;len:StrLenInt);[Public,Alias : 'FPC_SHORTSTR_SETLENGTH']; {$ifdef hascompilerproc} compilerproc; {$endif}
  18. {$endif INTERNSETLENGTH}
  19. begin
  20. if Len>255 then
  21. Len:=255;
  22. s[0]:=chr(len);
  23. end;
  24. {$ifdef interncopy}
  25. function fpc_shortstr_copy(const s : shortstring;index : StrLenInt;count : StrLenInt): shortstring;compilerproc;
  26. {$else}
  27. function copy(const s : shortstring;index : StrLenInt;count : StrLenInt): shortstring;
  28. {$endif}
  29. begin
  30. if count<0 then
  31. count:=0;
  32. if index>1 then
  33. dec(index)
  34. else
  35. index:=0;
  36. if index>length(s) then
  37. count:=0
  38. else
  39. if count>length(s)-index then
  40. count:=length(s)-index;
  41. {$ifdef interncopy}
  42. fpc_shortstr_Copy[0]:=chr(Count);
  43. Move(s[Index+1],fpc_shortstr_Copy[1],Count);
  44. {$else}
  45. Copy[0]:=chr(Count);
  46. Move(s[Index+1],Copy[1],Count);
  47. {$endif}
  48. end;
  49. procedure delete(var s : shortstring;index : StrLenInt;count : StrLenInt);
  50. begin
  51. if index<=0 then
  52. exit;
  53. if (Index<=Length(s)) and (Count>0) then
  54. begin
  55. if Count>length(s)-Index then
  56. Count:=length(s)-Index+1;
  57. s[0]:=Chr(length(s)-Count);
  58. if Index<=Length(s) then
  59. Move(s[Index+Count],s[Index],Length(s)-Index+1);
  60. end;
  61. end;
  62. procedure insert(const source : shortstring;var s : shortstring;index : StrLenInt);
  63. var
  64. cut,srclen,indexlen : longint;
  65. begin
  66. if index<1 then
  67. index:=1;
  68. if index>length(s) then
  69. index:=length(s)+1;
  70. indexlen:=Length(s)-Index+1;
  71. srclen:=length(Source);
  72. if length(source)+length(s)>=sizeof(s) then
  73. begin
  74. cut:=length(source)+length(s)-sizeof(s)+1;
  75. if cut>indexlen then
  76. begin
  77. dec(srclen,cut-indexlen);
  78. indexlen:=0;
  79. end
  80. else
  81. dec(indexlen,cut);
  82. end;
  83. move(s[Index],s[Index+srclen],indexlen);
  84. move(Source[1],s[Index],srclen);
  85. s[0]:=chr(index+srclen+indexlen-1);
  86. end;
  87. procedure insert(source : Char;var s : shortstring;index : StrLenInt);
  88. var
  89. indexlen : longint;
  90. begin
  91. if index<1 then
  92. index:=1;
  93. if index>length(s) then
  94. index:=length(s)+1;
  95. indexlen:=Length(s)-Index+1;
  96. if (length(s)+1=sizeof(s)) and (indexlen>0) then
  97. dec(indexlen);
  98. move(s[Index],s[Index+1],indexlen);
  99. s[Index]:=Source;
  100. s[0]:=chr(index+indexlen);
  101. end;
  102. function pos(const substr : shortstring;const s : shortstring):StrLenInt;
  103. var
  104. i,MaxLen : StrLenInt;
  105. pc : pchar;
  106. begin
  107. Pos:=0;
  108. if Length(SubStr)>0 then
  109. begin
  110. MaxLen:=Length(s)-Length(SubStr);
  111. i:=0;
  112. pc:=@s[1];
  113. while (i<=MaxLen) do
  114. begin
  115. inc(i);
  116. if (SubStr[1]=pc^) and
  117. (CompareChar(Substr[1],pc^,Length(SubStr))=0) then
  118. begin
  119. Pos:=i;
  120. exit;
  121. end;
  122. inc(pc);
  123. end;
  124. end;
  125. end;
  126. {Faster when looking for a single char...}
  127. function pos(c:char;const s:shortstring):StrLenInt;
  128. var
  129. i : StrLenInt;
  130. pc : pchar;
  131. begin
  132. pc:=@s[1];
  133. for i:=1 to length(s) do
  134. begin
  135. if pc^=c then
  136. begin
  137. pos:=i;
  138. exit;
  139. end;
  140. inc(pc);
  141. end;
  142. pos:=0;
  143. end;
  144. {$ifdef interncopy}
  145. function fpc_char_copy(c:char;index : StrLenInt;count : StrLenInt): shortstring;compilerproc;
  146. begin
  147. if (index=1) and (Count>0) then
  148. fpc_char_Copy:=c
  149. else
  150. fpc_char_Copy:='';
  151. end;
  152. {$else}
  153. function copy(c:char;index : StrLenInt;count : StrLenInt): shortstring;
  154. begin
  155. if (index=1) and (Count>0) then
  156. Copy:=c
  157. else
  158. Copy:='';
  159. end;
  160. {$endif}
  161. function pos(const substr : shortstring;c:char): StrLenInt;
  162. begin
  163. if (length(substr)=1) and (substr[1]=c) then
  164. Pos:=1
  165. else
  166. Pos:=0;
  167. end;
  168. {$ifdef IBM_CHAR_SET}
  169. const
  170. UpCaseTbl : shortstring[7]=#154#142#153#144#128#143#165;
  171. LoCaseTbl : shortstring[7]=#129#132#148#130#135#134#164;
  172. {$endif}
  173. function upcase(c : char) : char;
  174. {$IFDEF IBM_CHAR_SET}
  175. var
  176. i : longint;
  177. {$ENDIF}
  178. begin
  179. if (c in ['a'..'z']) then
  180. upcase:=char(byte(c)-32)
  181. else
  182. {$IFDEF IBM_CHAR_SET}
  183. begin
  184. i:=Pos(c,LoCaseTbl);
  185. if i>0 then
  186. upcase:=UpCaseTbl[i]
  187. else
  188. upcase:=c;
  189. end;
  190. {$ELSE}
  191. upcase:=c;
  192. {$ENDIF}
  193. end;
  194. function upcase(const s : shortstring) : shortstring;
  195. var
  196. i : longint;
  197. begin
  198. upcase[0]:=s[0];
  199. for i := 1 to length (s) do
  200. upcase[i] := upcase (s[i]);
  201. end;
  202. function lowercase(c : char) : char;overload;
  203. {$IFDEF IBM_CHAR_SET}
  204. var
  205. i : longint;
  206. {$ENDIF}
  207. begin
  208. if (c in ['A'..'Z']) then
  209. lowercase:=char(byte(c)+32)
  210. else
  211. {$IFDEF IBM_CHAR_SET}
  212. begin
  213. i:=Pos(c,UpCaseTbl);
  214. if i>0 then
  215. lowercase:=LoCaseTbl[i]
  216. else
  217. lowercase:=c;
  218. end;
  219. {$ELSE}
  220. lowercase:=c;
  221. {$ENDIF}
  222. end;
  223. function lowercase(const s : shortstring) : shortstring; overload;
  224. var
  225. i : longint;
  226. begin
  227. lowercase [0]:=s[0];
  228. for i:=1 to length(s) do
  229. lowercase[i]:=lowercase (s[i]);
  230. end;
  231. const
  232. HexTbl : array[0..15] of char='0123456789ABCDEF';
  233. function hexstr(val : longint;cnt : byte) : shortstring;
  234. var
  235. i : longint;
  236. begin
  237. hexstr[0]:=char(cnt);
  238. for i:=cnt downto 1 do
  239. begin
  240. hexstr[i]:=hextbl[val and $f];
  241. val:=val shr 4;
  242. end;
  243. end;
  244. function octstr(val : longint;cnt : byte) : shortstring;
  245. var
  246. i : longint;
  247. begin
  248. octstr[0]:=char(cnt);
  249. for i:=cnt downto 1 do
  250. begin
  251. octstr[i]:=hextbl[val and 7];
  252. val:=val shr 3;
  253. end;
  254. end;
  255. function binstr(val : longint;cnt : byte) : shortstring;
  256. var
  257. i : longint;
  258. begin
  259. binstr[0]:=char(cnt);
  260. for i:=cnt downto 1 do
  261. begin
  262. binstr[i]:=char(48+val and 1);
  263. val:=val shr 1;
  264. end;
  265. end;
  266. function hexstr(val : int64;cnt : byte) : shortstring;
  267. var
  268. i : longint;
  269. begin
  270. hexstr[0]:=char(cnt);
  271. for i:=cnt downto 1 do
  272. begin
  273. hexstr[i]:=hextbl[val and $f];
  274. val:=val shr 4;
  275. end;
  276. end;
  277. function octstr(val : int64;cnt : byte) : shortstring;
  278. var
  279. i : longint;
  280. begin
  281. octstr[0]:=char(cnt);
  282. for i:=cnt downto 1 do
  283. begin
  284. octstr[i]:=hextbl[val and 7];
  285. val:=val shr 3;
  286. end;
  287. end;
  288. function binstr(val : int64;cnt : byte) : shortstring;
  289. var
  290. i : longint;
  291. begin
  292. binstr[0]:=char(cnt);
  293. for i:=cnt downto 1 do
  294. begin
  295. binstr[i]:=char(48+val and 1);
  296. val:=val shr 1;
  297. end;
  298. end;
  299. function space (b : byte): shortstring;
  300. begin
  301. space[0] := chr(b);
  302. FillChar (Space[1],b,' ');
  303. end;
  304. {*****************************************************************************
  305. Str() Helpers
  306. *****************************************************************************}
  307. {$ifdef STR_USES_VALINT}
  308. procedure fpc_shortstr_SInt(v : valSInt;len : StrLenInt;var s : shortstring);[public,alias:'FPC_SHORTSTR_SINT']; {$ifdef hascompilerproc} compilerproc; {$endif}
  309. {$else}
  310. procedure fpc_shortstr_longint(v : longint;len : StrLenInt;var s : shortstring);[public,alias:'FPC_SHORTSTR_LONGINT']; {$ifdef hascompilerproc} compilerproc; {$endif}
  311. {$endif}
  312. begin
  313. int_str(v,s);
  314. if length(s)<len then
  315. s:=space(len-length(s))+s;
  316. end;
  317. {$ifdef STR_USES_VALINT}
  318. procedure fpc_shortstr_UInt(v : valUInt;len : StrLenInt;var s : shortstring);[public,alias:'FPC_SHORTSTR_UINT']; {$ifdef hascompilerproc} compilerproc; {$endif}
  319. {$else}
  320. {$ifdef ver1_0}
  321. procedure fpc_shortstr_cardinal(v : longword;len : StrLenInt;var s : shortstring);[public,alias:'FPC_SHORTSTR_CARDINAL']; {$ifdef hascompilerproc} compilerproc; {$endif}
  322. {$else}
  323. procedure fpc_shortstr_longword(v : longword;len : StrLenInt;var s : shortstring);[public,alias:'FPC_SHORTSTR_LONGWORD']; {$ifdef hascompilerproc} compilerproc; {$endif}
  324. {$endif}
  325. {$endif}
  326. begin
  327. int_str(v,s);
  328. if length(s)<len then
  329. s:=space(len-length(s))+s;
  330. end;
  331. {$ifndef CPU64}
  332. procedure int_qword_str(value : qword;var s : string);
  333. var
  334. hs : string;
  335. begin
  336. hs:='';
  337. repeat
  338. hs:=chr(longint(value mod qword(10))+48)+hs;
  339. value:=value div qword(10);
  340. until value=0;
  341. s:=hs;
  342. end;
  343. procedure fpc_shortstr_qword(v : qword;len : longint;var s : shortstring);[public,alias:'FPC_SHORTSTR_QWORD']; {$ifdef hascompilerproc} compilerproc; {$endif}
  344. begin
  345. int_qword_str(v,s);
  346. if length(s)<len then
  347. s:=space(len-length(s))+s;
  348. end;
  349. procedure fpc_shortstr_int64(v : int64;len : longint;var s : shortstring);[public,alias:'FPC_SHORTSTR_INT64']; {$ifdef hascompilerproc} compilerproc; {$endif}
  350. var
  351. hs : shortstring;
  352. q : qword;
  353. begin
  354. if v<0 then
  355. begin
  356. q:=qword(-v);
  357. int_qword_str(q,hs);
  358. s:='-'+hs;
  359. end
  360. else
  361. int_qword_str(qword(v),s);
  362. if length(s)<len then
  363. s:=space(len-length(s))+s;
  364. end;
  365. {$endif CPU64}
  366. { fpc_shortstr_sInt must appear before this file is included, because }
  367. { it's used inside real2str.inc and otherwise the searching via the }
  368. { compilerproc name will fail (JM) }
  369. {$I real2str.inc}
  370. procedure fpc_ShortStr_Float(d : ValReal;len,fr,rt : StrLenInt;var s : shortstring);[public,alias:'FPC_SHORTSTR_FLOAT']; {$ifdef hascompilerproc}compilerproc;{$endif hascompilerproc}
  371. begin
  372. str_real(len,fr,d,treal_type(rt),s);
  373. end;
  374. {
  375. Array Of Char Str() helpers
  376. }
  377. {$ifdef STR_USES_VALINT}
  378. procedure fpc_chararray_sint(v : valsint;len : StrLenInt;var a:array of char);{$ifdef hascompilerproc} compilerproc; {$endif}
  379. {$else}
  380. procedure fpc_chararray_longint(v : longint;len : StrLenInt;var a:array of char);{$ifdef hascompilerproc} compilerproc; {$endif}
  381. {$endif}
  382. var
  383. ss : shortstring;
  384. maxlen : StrLenInt;
  385. begin
  386. int_str(v,ss);
  387. if length(ss)<len then
  388. ss:=space(len-length(ss))+ss;
  389. if length(ss)<high(a)+1 then
  390. maxlen:=length(ss)
  391. else
  392. maxlen:=high(a)+1;
  393. move(ss[1],pchar(@a)^,maxlen);
  394. end;
  395. {$ifdef STR_USES_VALINT}
  396. procedure fpc_chararray_uint(v : valuint;len : StrLenInt;var a : array of char);{$ifdef hascompilerproc} compilerproc; {$endif}
  397. {$else}
  398. procedure fpc_chararray_longword(v : longword;len : StrLenInt;var a : array of char);{$ifdef hascompilerproc} compilerproc; {$endif}
  399. {$endif}
  400. var
  401. ss : shortstring;
  402. maxlen : StrLenInt;
  403. begin
  404. int_str(v,ss);
  405. if length(ss)<len then
  406. ss:=space(len-length(ss))+ss;
  407. if length(ss)<high(a)+1 then
  408. maxlen:=length(ss)
  409. else
  410. maxlen:=high(a)+1;
  411. move(ss[1],pchar(@a)^,maxlen);
  412. end;
  413. {$ifndef CPU64}
  414. procedure fpc_chararray_qword(v : qword;len : StrLenInt;var a : array of char);{$ifdef hascompilerproc} compilerproc; {$endif}
  415. var
  416. ss : shortstring;
  417. maxlen : StrLenInt;
  418. begin
  419. int_qword_str(v,ss);
  420. if length(ss)<len then
  421. ss:=space(len-length(ss))+ss;
  422. if length(ss)<high(a)+1 then
  423. maxlen:=length(ss)
  424. else
  425. maxlen:=high(a)+1;
  426. move(ss[1],pchar(@a)^,maxlen);
  427. end;
  428. procedure fpc_chararray_int64(v : int64;len : StrLenInt;var a : array of char);{$ifdef hascompilerproc} compilerproc; {$endif}
  429. var
  430. ss : shortstring;
  431. maxlen : StrLenInt;
  432. q : qword;
  433. begin
  434. if v<0 then
  435. begin
  436. q:=qword(-v);
  437. int_qword_str(q,ss);
  438. ss:='-'+ss;
  439. end
  440. else
  441. int_qword_str(qword(v),ss);
  442. if length(ss)<len then
  443. ss:=space(len-length(ss))+ss;
  444. if length(ss)<high(a)+1 then
  445. maxlen:=length(ss)
  446. else
  447. maxlen:=high(a)+1;
  448. move(ss[1],pchar(@a)^,maxlen);
  449. end;
  450. {$endif CPU64}
  451. procedure fpc_chararray_Float(d : ValReal;len,fr,rt : StrLenInt;var a : array of char);{$ifdef hascompilerproc}compilerproc;{$endif hascompilerproc}
  452. var
  453. ss : shortstring;
  454. maxlen : StrLenInt;
  455. begin
  456. str_real(len,fr,d,treal_type(rt),ss);
  457. if length(ss)<high(a)+1 then
  458. maxlen:=length(ss)
  459. else
  460. maxlen:=high(a)+1;
  461. move(ss[1],pchar(@a)^,maxlen);
  462. end;
  463. {*****************************************************************************
  464. Val() Functions
  465. *****************************************************************************}
  466. Function InitVal(const s:shortstring;var negativ:boolean;var base:byte):ValSInt;
  467. var
  468. Code : StrLenInt;
  469. begin
  470. {Skip Spaces and Tab}
  471. code:=1;
  472. while (code<=length(s)) and (s[code] in [' ',#9]) do
  473. inc(code);
  474. {Sign}
  475. negativ:=false;
  476. case s[code] of
  477. '-' : begin
  478. negativ:=true;
  479. inc(code);
  480. end;
  481. '+' : inc(code);
  482. end;
  483. {Base}
  484. base:=10;
  485. if code<=length(s) then
  486. begin
  487. case s[code] of
  488. '$' : begin
  489. base:=16;
  490. repeat
  491. inc(code);
  492. until (code>=length(s)) or (s[code]<>'0');
  493. end;
  494. '%' : begin
  495. base:=2;
  496. inc(code);
  497. end;
  498. '&' : begin
  499. Base:=8;
  500. repeat
  501. inc(code);
  502. until (code>=length(s)) or (s[code]<>'0');
  503. end;
  504. end;
  505. end;
  506. InitVal:=code;
  507. end;
  508. Function fpc_Val_SInt_ShortStr(DestSize: StrLenInt; Const S: ShortString; var Code: ValSInt): ValSInt; [public, alias:'FPC_VAL_SINT_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  509. var
  510. u, temp, prev, maxPrevValue, maxNewValue: ValUInt;
  511. base : byte;
  512. negative : boolean;
  513. begin
  514. fpc_Val_SInt_ShortStr := 0;
  515. Temp:=0;
  516. Code:=InitVal(s,negative,base);
  517. if Code>length(s) then
  518. exit;
  519. maxPrevValue := ValUInt(MaxUIntValue) div ValUInt(Base);
  520. if (base = 10) then
  521. maxNewValue := MaxSIntValue + ord(negative)
  522. else
  523. maxNewValue := MaxUIntValue;
  524. while Code<=Length(s) do
  525. begin
  526. case s[Code] of
  527. '0'..'9' : u:=Ord(S[Code])-Ord('0');
  528. 'A'..'F' : u:=Ord(S[Code])-(Ord('A')-10);
  529. 'a'..'f' : u:=Ord(S[Code])-(Ord('a')-10);
  530. else
  531. u:=16;
  532. end;
  533. Prev := Temp;
  534. Temp := Temp*ValUInt(base);
  535. If (u >= base) or
  536. (ValUInt(maxNewValue-u) < Temp) or
  537. (prev > maxPrevValue) Then
  538. Begin
  539. fpc_Val_SInt_ShortStr := 0;
  540. Exit
  541. End;
  542. Temp:=Temp+u;
  543. inc(code);
  544. end;
  545. code := 0;
  546. fpc_Val_SInt_ShortStr := ValSInt(Temp);
  547. If Negative Then
  548. fpc_Val_SInt_ShortStr := -fpc_Val_SInt_ShortStr;
  549. If Not(Negative) and (base <> 10) Then
  550. {sign extend the result to allow proper range checking}
  551. Case DestSize of
  552. 1: fpc_Val_SInt_ShortStr := shortint(fpc_Val_SInt_ShortStr);
  553. 2: fpc_Val_SInt_ShortStr := smallint(fpc_Val_SInt_ShortStr);
  554. { Uncomment the folling once full 64bit support is in place
  555. 4: fpc_Val_SInt_ShortStr := StrLenInt(fpc_Val_SInt_ShortStr);}
  556. End;
  557. end;
  558. {$ifdef hascompilerproc}
  559. { we need this for fpc_Val_SInt_Ansistr and fpc_Val_SInt_WideStr because }
  560. { we have to pass the DestSize parameter on (JM) }
  561. Function fpc_Val_SInt_ShortStr(DestSize: StrLenInt; Const S: ShortString; var Code: ValSInt): ValSInt; [external name 'FPC_VAL_SINT_SHORTSTR'];
  562. {$endif hascompilerproc}
  563. Function fpc_Val_UInt_Shortstr(Const S: ShortString; var Code: ValSInt): ValUInt; [public, alias:'FPC_VAL_UINT_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  564. var
  565. u, prev : ValUInt;
  566. base : byte;
  567. negative : boolean;
  568. begin
  569. fpc_Val_UInt_Shortstr:=0;
  570. Code:=InitVal(s,negative,base);
  571. If Negative or (Code>length(s)) Then
  572. Exit;
  573. while Code<=Length(s) do
  574. begin
  575. case s[Code] of
  576. '0'..'9' : u:=Ord(S[Code])-Ord('0');
  577. 'A'..'F' : u:=Ord(S[Code])-(Ord('A')-10);
  578. 'a'..'f' : u:=Ord(S[Code])-(Ord('a')-10);
  579. else
  580. u:=16;
  581. end;
  582. prev := fpc_Val_UInt_Shortstr;
  583. If (u>=base) or
  584. (ValUInt(MaxUIntValue-u) div ValUInt(Base)<prev) then
  585. begin
  586. fpc_Val_UInt_Shortstr:=0;
  587. exit;
  588. end;
  589. fpc_Val_UInt_Shortstr:=fpc_Val_UInt_Shortstr*ValUInt(base) + u;
  590. inc(code);
  591. end;
  592. code := 0;
  593. end;
  594. {$ifndef CPU64}
  595. Function fpc_val_int64_shortstr(Const S: ShortString; var Code: ValSInt): Int64; [public, alias:'FPC_VAL_INT64_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  596. type
  597. QWordRec = packed record
  598. l1,l2: longint;
  599. end;
  600. var
  601. u, temp, prev, maxint64, maxqword : qword;
  602. base : byte;
  603. negative : boolean;
  604. begin
  605. fpc_val_int64_shortstr := 0;
  606. Temp:=0;
  607. Code:=InitVal(s,negative,base);
  608. if Code>length(s) then
  609. exit;
  610. { high(int64) produces 0 in version 1.0 (JM) }
  611. with qwordrec(maxint64) do
  612. begin
  613. l1 := longint($ffffffff);
  614. l2 := $7fffffff;
  615. end;
  616. with qwordrec(maxqword) do
  617. begin
  618. l1 := longint($ffffffff);
  619. l2 := longint($ffffffff);
  620. end;
  621. while Code<=Length(s) do
  622. begin
  623. case s[Code] of
  624. '0'..'9' : u:=Ord(S[Code])-Ord('0');
  625. 'A'..'F' : u:=Ord(S[Code])-(Ord('A')-10);
  626. 'a'..'f' : u:=Ord(S[Code])-(Ord('a')-10);
  627. else
  628. u:=16;
  629. end;
  630. Prev:=Temp;
  631. Temp:=Temp*Int64(base);
  632. If (u >= base) or
  633. ((base = 10) and
  634. (maxint64-temp+ord(negative) < u)) or
  635. ((base <> 10) and
  636. (qword(maxqword-temp) < u)) or
  637. (prev > maxqword div qword(base)) Then
  638. Begin
  639. fpc_val_int64_shortstr := 0;
  640. Exit
  641. End;
  642. Temp:=Temp+u;
  643. inc(code);
  644. end;
  645. code:=0;
  646. fpc_val_int64_shortstr:=int64(Temp);
  647. If Negative Then
  648. fpc_val_int64_shortstr:=-fpc_val_int64_shortstr;
  649. end;
  650. Function fpc_val_qword_shortstr(Const S: ShortString; var Code: ValSInt): QWord; [public, alias:'FPC_VAL_QWORD_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  651. type qwordrec = packed record
  652. l1,l2: longint;
  653. end;
  654. var
  655. u, prev, maxqword: QWord;
  656. base : byte;
  657. negative : boolean;
  658. begin
  659. fpc_val_qword_shortstr:=0;
  660. Code:=InitVal(s,negative,base);
  661. If Negative or (Code>length(s)) Then
  662. Exit;
  663. with qwordrec(maxqword) do
  664. begin
  665. l1 := longint($ffffffff);
  666. l2 := longint($ffffffff);
  667. end;
  668. while Code<=Length(s) do
  669. begin
  670. case s[Code] of
  671. '0'..'9' : u:=Ord(S[Code])-Ord('0');
  672. 'A'..'F' : u:=Ord(S[Code])-(Ord('A')-10);
  673. 'a'..'f' : u:=Ord(S[Code])-(Ord('a')-10);
  674. else
  675. u:=16;
  676. end;
  677. prev := fpc_val_qword_shortstr;
  678. If (u>=base) or
  679. ((QWord(maxqword-u) div QWord(base))<prev) then
  680. Begin
  681. fpc_val_qword_shortstr := 0;
  682. Exit
  683. End;
  684. fpc_val_qword_shortstr:=fpc_val_qword_shortstr*QWord(base) + u;
  685. inc(code);
  686. end;
  687. code := 0;
  688. end;
  689. {$endif CPU64}
  690. Function fpc_Val_Real_ShortStr(const s : shortstring; var code : ValSInt): ValReal; [public, alias:'FPC_VAL_REAL_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  691. var
  692. hd,
  693. esign,sign : valreal;
  694. exponent,i : StrLenInt;
  695. flags : byte;
  696. begin
  697. fpc_Val_Real_ShortStr:=0.0;
  698. code:=1;
  699. exponent:=0;
  700. esign:=1;
  701. flags:=0;
  702. sign:=1;
  703. while (code<=length(s)) and (s[code] in [' ',#9]) do
  704. inc(code);
  705. case s[code] of
  706. '+' : inc(code);
  707. '-' : begin
  708. sign:=-1;
  709. inc(code);
  710. end;
  711. end;
  712. while (Code<=Length(s)) and (s[code] in ['0'..'9']) do
  713. begin
  714. { Read integer part }
  715. flags:=flags or 1;
  716. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr*10+(ord(s[code])-ord('0'));
  717. inc(code);
  718. end;
  719. { Decimal ? }
  720. if (s[code]='.') and (length(s)>=code) then
  721. begin
  722. hd:=1.0;
  723. inc(code);
  724. while (s[code] in ['0'..'9']) and (length(s)>=code) do
  725. begin
  726. { Read fractional part. }
  727. flags:=flags or 2;
  728. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr*10+(ord(s[code])-ord('0'));
  729. hd:=hd*10.0;
  730. inc(code);
  731. end;
  732. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr/hd;
  733. end;
  734. { Again, read integer and fractional part}
  735. if flags=0 then
  736. begin
  737. fpc_Val_Real_ShortStr:=0.0;
  738. exit;
  739. end;
  740. { Exponent ? }
  741. if (upcase(s[code])='E') and (length(s)>=code) then
  742. begin
  743. inc(code);
  744. if s[code]='+' then
  745. inc(code)
  746. else
  747. if s[code]='-' then
  748. begin
  749. esign:=-1;
  750. inc(code);
  751. end;
  752. if not(s[code] in ['0'..'9']) or (length(s)<code) then
  753. begin
  754. fpc_Val_Real_ShortStr:=0.0;
  755. exit;
  756. end;
  757. while (s[code] in ['0'..'9']) and (length(s)>=code) do
  758. begin
  759. exponent:=exponent*10;
  760. exponent:=exponent+ord(s[code])-ord('0');
  761. inc(code);
  762. end;
  763. end;
  764. { Calculate Exponent }
  765. {
  766. if esign>0 then
  767. for i:=1 to exponent do
  768. fpc_Val_Real_ShortStr:=Val_Real_ShortStr*10
  769. else
  770. for i:=1 to exponent do
  771. fpc_Val_Real_ShortStr:=Val_Real_ShortStr/10; }
  772. hd:=1.0;
  773. for i:=1 to exponent do
  774. hd:=hd*10.0;
  775. if esign>0 then
  776. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr*hd
  777. else
  778. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr/hd;
  779. { Not all characters are read ? }
  780. if length(s)>=code then
  781. begin
  782. fpc_Val_Real_ShortStr:=0.0;
  783. exit;
  784. end;
  785. { evaluate sign }
  786. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr*sign;
  787. { success ! }
  788. code:=0;
  789. end;
  790. Procedure SetString (Var S : Shortstring; Buf : PChar; Len : StrLenInt);
  791. begin
  792. If Len > High(S) then
  793. Len := High(S);
  794. SetLength(S,Len);
  795. If Buf<>Nil then
  796. begin
  797. Move (Buf[0],S[1],Len);
  798. end;
  799. end;
  800. {
  801. $Log$
  802. Revision 1.28 2004-04-29 18:59:43 peter
  803. * str() helpers now also use valint/valuint
  804. * int64/qword helpers disabled for cpu64
  805. Revision 1.27 2003/02/26 20:04:47 jonas
  806. * fixed shortstring version of setstring
  807. Revision 1.26 2002/10/21 19:52:47 jonas
  808. * fixed some buffer overflow errors in SetString (both short and
  809. ansistring versions) (merged)
  810. Revision 1.25 2002/10/19 17:06:50 michael
  811. + Added check for nil buffer to setstring
  812. Revision 1.24 2002/10/02 18:21:51 peter
  813. * Copy() changed to internal function calling compilerprocs
  814. * FPC_SHORTSTR_COPY renamed to FPC_SHORTSTR_ASSIGN because of the
  815. new copy functions
  816. Revision 1.23 2002/09/14 11:20:50 carl
  817. * Delphi compatibility fix (with string routines)
  818. Revision 1.22 2002/09/07 21:19:00 carl
  819. * cardinal -> longword
  820. Revision 1.21 2002/09/07 15:07:46 peter
  821. * old logs removed and tabs fixed
  822. Revision 1.20 2002/09/02 19:24:41 peter
  823. * array of char support for Str()
  824. Revision 1.19 2002/08/06 20:53:38 michael
  825. + Added support for octal strings (using &)
  826. Revision 1.18 2002/01/24 18:27:06 peter
  827. * lowercase() overloaded
  828. }