sstrings.inc 19 KB

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