sstrings.inc 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870
  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']; {$ifdef hascompilerproc} compilerproc; {$endif}
  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. {$ifdef STR_USES_VALINT}
  307. procedure fpc_shortstr_SInt(v : valSInt;len : SizeInt;var s : shortstring);[public,alias:'FPC_SHORTSTR_SINT']; {$ifdef hascompilerproc} compilerproc; {$endif}
  308. {$else}
  309. procedure fpc_shortstr_longint(v : longint;len : SizeInt;var s : shortstring);[public,alias:'FPC_SHORTSTR_LONGINT']; {$ifdef hascompilerproc} compilerproc; {$endif}
  310. {$endif}
  311. begin
  312. int_str(v,s);
  313. if length(s)<len then
  314. s:=space(len-length(s))+s;
  315. end;
  316. {$ifdef STR_USES_VALINT}
  317. procedure fpc_shortstr_UInt(v : valUInt;len : SizeInt;var s : shortstring);[public,alias:'FPC_SHORTSTR_UINT']; {$ifdef hascompilerproc} compilerproc; {$endif}
  318. {$else}
  319. procedure fpc_shortstr_longword(v : longword;len : SizeInt;var s : shortstring);[public,alias:'FPC_SHORTSTR_LONGWORD']; {$ifdef hascompilerproc} compilerproc; {$endif}
  320. {$endif}
  321. begin
  322. int_str(v,s);
  323. if length(s)<len then
  324. s:=space(len-length(s))+s;
  325. end;
  326. {$ifndef CPU64}
  327. procedure fpc_shortstr_qword(v : qword;len : longint;var s : shortstring);[public,alias:'FPC_SHORTSTR_QWORD']; {$ifdef hascompilerproc} compilerproc; {$endif}
  328. begin
  329. int_str(v,s);
  330. if length(s)<len then
  331. s:=space(len-length(s))+s;
  332. end;
  333. procedure fpc_shortstr_int64(v : int64;len : longint;var s : shortstring);[public,alias:'FPC_SHORTSTR_INT64']; {$ifdef hascompilerproc} compilerproc; {$endif}
  334. begin
  335. int_str(v,s);
  336. if length(s)<len then
  337. s:=space(len-length(s))+s;
  338. end;
  339. {$endif CPU64}
  340. { fpc_shortstr_sInt must appear before this file is included, because }
  341. { it's used inside real2str.inc and otherwise the searching via the }
  342. { compilerproc name will fail (JM) }
  343. {$I real2str.inc}
  344. procedure fpc_ShortStr_Float(d : ValReal;len,fr,rt : SizeInt;var s : shortstring);[public,alias:'FPC_SHORTSTR_FLOAT']; {$ifdef hascompilerproc}compilerproc;{$endif hascompilerproc}
  345. begin
  346. str_real(len,fr,d,treal_type(rt),s);
  347. end;
  348. {
  349. Array Of Char Str() helpers
  350. }
  351. {$ifdef STR_USES_VALINT}
  352. procedure fpc_chararray_sint(v : valsint;len : SizeInt;var a:array of char);{$ifdef hascompilerproc} compilerproc; {$endif}
  353. {$else}
  354. procedure fpc_chararray_longint(v : longint;len : SizeInt;var a:array of char);{$ifdef hascompilerproc} compilerproc; {$endif}
  355. {$endif}
  356. var
  357. ss : shortstring;
  358. maxlen : SizeInt;
  359. begin
  360. int_str(v,ss);
  361. if length(ss)<len then
  362. ss:=space(len-length(ss))+ss;
  363. if length(ss)<high(a)+1 then
  364. maxlen:=length(ss)
  365. else
  366. maxlen:=high(a)+1;
  367. move(ss[1],pchar(@a)^,maxlen);
  368. end;
  369. {$ifdef STR_USES_VALINT}
  370. procedure fpc_chararray_uint(v : valuint;len : SizeInt;var a : array of char);{$ifdef hascompilerproc} compilerproc; {$endif}
  371. {$else}
  372. procedure fpc_chararray_longword(v : longword;len : SizeInt;var a : array of char);{$ifdef hascompilerproc} compilerproc; {$endif}
  373. {$endif}
  374. var
  375. ss : shortstring;
  376. maxlen : SizeInt;
  377. begin
  378. int_str(v,ss);
  379. if length(ss)<len then
  380. ss:=space(len-length(ss))+ss;
  381. if length(ss)<high(a)+1 then
  382. maxlen:=length(ss)
  383. else
  384. maxlen:=high(a)+1;
  385. move(ss[1],pchar(@a)^,maxlen);
  386. end;
  387. {$ifndef CPU64}
  388. procedure fpc_chararray_qword(v : qword;len : SizeInt;var a : array of char);{$ifdef hascompilerproc} compilerproc; {$endif}
  389. var
  390. ss : shortstring;
  391. maxlen : SizeInt;
  392. begin
  393. int_str(v,ss);
  394. if length(ss)<len then
  395. ss:=space(len-length(ss))+ss;
  396. if length(ss)<high(a)+1 then
  397. maxlen:=length(ss)
  398. else
  399. maxlen:=high(a)+1;
  400. move(ss[1],pchar(@a)^,maxlen);
  401. end;
  402. procedure fpc_chararray_int64(v : int64;len : SizeInt;var a : array of char);{$ifdef hascompilerproc} compilerproc; {$endif}
  403. var
  404. ss : shortstring;
  405. maxlen : SizeInt;
  406. begin
  407. int_str(v,ss);
  408. if length(ss)<len then
  409. ss:=space(len-length(ss))+ss;
  410. if length(ss)<high(a)+1 then
  411. maxlen:=length(ss)
  412. else
  413. maxlen:=high(a)+1;
  414. move(ss[1],pchar(@a)^,maxlen);
  415. end;
  416. {$endif CPU64}
  417. procedure fpc_chararray_Float(d : ValReal;len,fr,rt : SizeInt;var a : array of char);{$ifdef hascompilerproc}compilerproc;{$endif hascompilerproc}
  418. var
  419. ss : shortstring;
  420. maxlen : SizeInt;
  421. begin
  422. str_real(len,fr,d,treal_type(rt),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. {*****************************************************************************
  430. Val() Functions
  431. *****************************************************************************}
  432. Function InitVal(const s:shortstring;var negativ:boolean;var base:byte):ValSInt;
  433. var
  434. Code : SizeInt;
  435. begin
  436. {Skip Spaces and Tab}
  437. code:=1;
  438. while (code<=length(s)) and (s[code] in [' ',#9]) do
  439. inc(code);
  440. {Sign}
  441. negativ:=false;
  442. case s[code] of
  443. '-' : begin
  444. negativ:=true;
  445. inc(code);
  446. end;
  447. '+' : inc(code);
  448. end;
  449. {Base}
  450. base:=10;
  451. if code<=length(s) then
  452. begin
  453. case s[code] of
  454. '$' : begin
  455. base:=16;
  456. inc(code);
  457. end;
  458. '%' : begin
  459. base:=2;
  460. inc(code);
  461. end;
  462. '&' : begin
  463. Base:=8;
  464. inc(code);
  465. end;
  466. '0' : begin
  467. if (code < length(s)) and (s[code+1] in ['x', 'X']) then
  468. begin
  469. inc(code, 2);
  470. base := 16;
  471. end;
  472. end;
  473. end;
  474. end;
  475. { strip leading zeros }
  476. while ((code < length(s)) and (s[code] = '0')) do begin
  477. inc(code);
  478. end;
  479. InitVal:=code;
  480. end;
  481. Function fpc_Val_SInt_ShortStr(DestSize: SizeInt; Const S: ShortString; var Code: ValSInt): ValSInt; [public, alias:'FPC_VAL_SINT_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  482. var
  483. u, temp, prev, maxPrevValue, maxNewValue: ValUInt;
  484. base : byte;
  485. negative : boolean;
  486. begin
  487. fpc_Val_SInt_ShortStr := 0;
  488. Temp:=0;
  489. Code:=InitVal(s,negative,base);
  490. if Code>length(s) then
  491. exit;
  492. maxPrevValue := ValUInt(MaxUIntValue) div ValUInt(Base);
  493. if (base = 10) then
  494. maxNewValue := MaxSIntValue + ord(negative)
  495. else
  496. maxNewValue := MaxUIntValue;
  497. while Code<=Length(s) do
  498. begin
  499. case s[Code] of
  500. '0'..'9' : u:=Ord(S[Code])-Ord('0');
  501. 'A'..'F' : u:=Ord(S[Code])-(Ord('A')-10);
  502. 'a'..'f' : u:=Ord(S[Code])-(Ord('a')-10);
  503. else
  504. u:=16;
  505. end;
  506. Prev := Temp;
  507. Temp := Temp*ValUInt(base);
  508. If (u >= base) or
  509. (ValUInt(maxNewValue-u) < Temp) or
  510. (prev > maxPrevValue) Then
  511. Begin
  512. fpc_Val_SInt_ShortStr := 0;
  513. Exit
  514. End;
  515. Temp:=Temp+u;
  516. inc(code);
  517. end;
  518. code := 0;
  519. fpc_Val_SInt_ShortStr := ValSInt(Temp);
  520. If Negative Then
  521. fpc_Val_SInt_ShortStr := -fpc_Val_SInt_ShortStr;
  522. If Not(Negative) and (base <> 10) Then
  523. {sign extend the result to allow proper range checking}
  524. Case DestSize of
  525. 1: fpc_Val_SInt_ShortStr := shortint(fpc_Val_SInt_ShortStr);
  526. 2: fpc_Val_SInt_ShortStr := smallint(fpc_Val_SInt_ShortStr);
  527. { Uncomment the folling once full 64bit support is in place
  528. 4: fpc_Val_SInt_ShortStr := SizeInt(fpc_Val_SInt_ShortStr);}
  529. End;
  530. end;
  531. { we need this for fpc_Val_SInt_Ansistr and fpc_Val_SInt_WideStr because }
  532. { we have to pass the DestSize parameter on (JM) }
  533. Function int_Val_SInt_ShortStr(DestSize: SizeInt; Const S: ShortString; var Code: ValSInt): ValSInt; [external name 'FPC_VAL_SINT_SHORTSTR'];
  534. Function fpc_Val_UInt_Shortstr(Const S: ShortString; var Code: ValSInt): ValUInt; [public, alias:'FPC_VAL_UINT_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  535. var
  536. u, prev : ValUInt;
  537. base : byte;
  538. negative : boolean;
  539. begin
  540. fpc_Val_UInt_Shortstr:=0;
  541. Code:=InitVal(s,negative,base);
  542. If Negative or (Code>length(s)) Then
  543. Exit;
  544. while Code<=Length(s) do
  545. begin
  546. case s[Code] of
  547. '0'..'9' : u:=Ord(S[Code])-Ord('0');
  548. 'A'..'F' : u:=Ord(S[Code])-(Ord('A')-10);
  549. 'a'..'f' : u:=Ord(S[Code])-(Ord('a')-10);
  550. else
  551. u:=16;
  552. end;
  553. prev := fpc_Val_UInt_Shortstr;
  554. If (u>=base) or
  555. (ValUInt(MaxUIntValue-u) div ValUInt(Base)<prev) then
  556. begin
  557. fpc_Val_UInt_Shortstr:=0;
  558. exit;
  559. end;
  560. fpc_Val_UInt_Shortstr:=fpc_Val_UInt_Shortstr*ValUInt(base) + u;
  561. inc(code);
  562. end;
  563. code := 0;
  564. end;
  565. {$ifndef CPU64}
  566. Function fpc_val_int64_shortstr(Const S: ShortString; var Code: ValSInt): Int64; [public, alias:'FPC_VAL_INT64_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  567. type
  568. QWordRec = packed record
  569. l1,l2: longint;
  570. end;
  571. var
  572. u, temp, prev, maxint64, maxqword : qword;
  573. base : byte;
  574. negative : boolean;
  575. begin
  576. fpc_val_int64_shortstr := 0;
  577. Temp:=0;
  578. Code:=InitVal(s,negative,base);
  579. if Code>length(s) then
  580. exit;
  581. { high(int64) produces 0 in version 1.0 (JM) }
  582. with qwordrec(maxint64) do
  583. begin
  584. {$ifdef ENDIAN_LITTLE}
  585. l1 := longint($ffffffff);
  586. l2 := $7fffffff;
  587. {$else ENDIAN_LITTLE}
  588. l1 := $7fffffff;
  589. l2 := longint($ffffffff);
  590. {$endif ENDIAN_LITTLE}
  591. end;
  592. with qwordrec(maxqword) do
  593. begin
  594. l1 := longint($ffffffff);
  595. l2 := longint($ffffffff);
  596. end;
  597. while Code<=Length(s) do
  598. begin
  599. case s[Code] of
  600. '0'..'9' : u:=Ord(S[Code])-Ord('0');
  601. 'A'..'F' : u:=Ord(S[Code])-(Ord('A')-10);
  602. 'a'..'f' : u:=Ord(S[Code])-(Ord('a')-10);
  603. else
  604. u:=16;
  605. end;
  606. Prev:=Temp;
  607. Temp:=Temp*Int64(base);
  608. If (u >= base) or
  609. ((base = 10) and
  610. (maxint64-temp+ord(negative) < u)) or
  611. ((base <> 10) and
  612. (qword(maxqword-temp) < u)) or
  613. (prev > maxqword div qword(base)) Then
  614. Begin
  615. fpc_val_int64_shortstr := 0;
  616. Exit
  617. End;
  618. Temp:=Temp+u;
  619. inc(code);
  620. end;
  621. code:=0;
  622. fpc_val_int64_shortstr:=int64(Temp);
  623. If Negative Then
  624. fpc_val_int64_shortstr:=-fpc_val_int64_shortstr;
  625. end;
  626. Function fpc_val_qword_shortstr(Const S: ShortString; var Code: ValSInt): QWord; [public, alias:'FPC_VAL_QWORD_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  627. type qwordrec = packed record
  628. l1,l2: longint;
  629. end;
  630. var
  631. u, prev, maxqword: QWord;
  632. base : byte;
  633. negative : boolean;
  634. begin
  635. fpc_val_qword_shortstr:=0;
  636. Code:=InitVal(s,negative,base);
  637. If Negative or (Code>length(s)) Then
  638. Exit;
  639. with qwordrec(maxqword) do
  640. begin
  641. l1 := longint($ffffffff);
  642. l2 := longint($ffffffff);
  643. end;
  644. while Code<=Length(s) do
  645. begin
  646. case s[Code] of
  647. '0'..'9' : u:=Ord(S[Code])-Ord('0');
  648. 'A'..'F' : u:=Ord(S[Code])-(Ord('A')-10);
  649. 'a'..'f' : u:=Ord(S[Code])-(Ord('a')-10);
  650. else
  651. u:=16;
  652. end;
  653. prev := fpc_val_qword_shortstr;
  654. If (u>=base) or
  655. ((QWord(maxqword-u) div QWord(base))<prev) then
  656. Begin
  657. fpc_val_qword_shortstr := 0;
  658. Exit
  659. End;
  660. fpc_val_qword_shortstr:=fpc_val_qword_shortstr*QWord(base) + u;
  661. inc(code);
  662. end;
  663. code := 0;
  664. end;
  665. {$endif CPU64}
  666. Function fpc_Val_Real_ShortStr(const s : shortstring; var code : ValSInt): ValReal; [public, alias:'FPC_VAL_REAL_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  667. var
  668. hd,
  669. esign,sign : valreal;
  670. exponent,i : SizeInt;
  671. flags : byte;
  672. begin
  673. fpc_Val_Real_ShortStr:=0.0;
  674. code:=1;
  675. exponent:=0;
  676. esign:=1;
  677. flags:=0;
  678. sign:=1;
  679. while (code<=length(s)) and (s[code] in [' ',#9]) do
  680. inc(code);
  681. case s[code] of
  682. '+' : inc(code);
  683. '-' : begin
  684. sign:=-1;
  685. inc(code);
  686. end;
  687. end;
  688. while (Code<=Length(s)) and (s[code] in ['0'..'9']) do
  689. begin
  690. { Read integer part }
  691. flags:=flags or 1;
  692. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr*10+(ord(s[code])-ord('0'));
  693. inc(code);
  694. end;
  695. { Decimal ? }
  696. if (length(s)>=code) and (s[code]='.') then
  697. begin
  698. hd:=1.0;
  699. inc(code);
  700. while (length(s)>=code) and (s[code] in ['0'..'9']) do
  701. begin
  702. { Read fractional part. }
  703. flags:=flags or 2;
  704. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr*10+(ord(s[code])-ord('0'));
  705. hd:=hd*10.0;
  706. inc(code);
  707. end;
  708. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr/hd;
  709. end;
  710. { Again, read integer and fractional part}
  711. if flags=0 then
  712. begin
  713. fpc_Val_Real_ShortStr:=0.0;
  714. exit;
  715. end;
  716. { Exponent ? }
  717. if (length(s)>=code) and (upcase(s[code])='E') then
  718. begin
  719. inc(code);
  720. if Length(s) >= code then
  721. if s[code]='+' then
  722. inc(code)
  723. else
  724. if s[code]='-' then
  725. begin
  726. esign:=-1;
  727. inc(code);
  728. end;
  729. if (length(s)<code) or not(s[code] in ['0'..'9']) then
  730. begin
  731. fpc_Val_Real_ShortStr:=0.0;
  732. exit;
  733. end;
  734. while (length(s)>=code) and (s[code] in ['0'..'9']) do
  735. begin
  736. exponent:=exponent*10;
  737. exponent:=exponent+ord(s[code])-ord('0');
  738. inc(code);
  739. end;
  740. end;
  741. { Calculate Exponent }
  742. {
  743. if esign>0 then
  744. for i:=1 to exponent do
  745. fpc_Val_Real_ShortStr:=Val_Real_ShortStr*10
  746. else
  747. for i:=1 to exponent do
  748. fpc_Val_Real_ShortStr:=Val_Real_ShortStr/10; }
  749. hd:=1.0;
  750. for i:=1 to exponent do
  751. hd:=hd*10.0;
  752. if esign>0 then
  753. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr*hd
  754. else
  755. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr/hd;
  756. { Not all characters are read ? }
  757. if length(s)>=code then
  758. begin
  759. fpc_Val_Real_ShortStr:=0.0;
  760. exit;
  761. end;
  762. { evaluate sign }
  763. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr*sign;
  764. { success ! }
  765. code:=0;
  766. end;
  767. Procedure SetString (Var S : Shortstring; Buf : PChar; Len : SizeInt);
  768. begin
  769. If Len > High(S) then
  770. Len := High(S);
  771. SetLength(S,Len);
  772. If Buf<>Nil then
  773. begin
  774. Move (Buf[0],S[1],Len);
  775. end;
  776. end;