sstrings.inc 21 KB

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