sstrings.inc 21 KB

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