sstrings.inc 19 KB

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