sstrings.inc 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903
  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. inc(code);
  475. end;
  476. '%' : begin
  477. base:=2;
  478. inc(code);
  479. end;
  480. '&' : begin
  481. Base:=8;
  482. inc(code);
  483. end;
  484. '0' : begin
  485. if (code < length(s)) and (s[code+1] in ['x', 'X']) then
  486. begin
  487. inc(code, 2);
  488. base := 16;
  489. end;
  490. end;
  491. end;
  492. end;
  493. { strip leading zeros }
  494. while ((code < length(s)) and (s[code] = '0')) do begin
  495. inc(code);
  496. end;
  497. InitVal:=code;
  498. end;
  499. Function fpc_Val_SInt_ShortStr(DestSize: SizeInt; Const S: ShortString; var Code: ValSInt): ValSInt; [public, alias:'FPC_VAL_SINT_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  500. var
  501. u, temp, prev, maxPrevValue, maxNewValue: ValUInt;
  502. base : byte;
  503. negative : boolean;
  504. begin
  505. fpc_Val_SInt_ShortStr := 0;
  506. Temp:=0;
  507. Code:=InitVal(s,negative,base);
  508. if Code>length(s) then
  509. exit;
  510. maxPrevValue := ValUInt(MaxUIntValue) div ValUInt(Base);
  511. if (base = 10) then
  512. maxNewValue := MaxSIntValue + ord(negative)
  513. else
  514. maxNewValue := MaxUIntValue;
  515. while Code<=Length(s) do
  516. begin
  517. case s[Code] of
  518. '0'..'9' : u:=Ord(S[Code])-Ord('0');
  519. 'A'..'F' : u:=Ord(S[Code])-(Ord('A')-10);
  520. 'a'..'f' : u:=Ord(S[Code])-(Ord('a')-10);
  521. else
  522. u:=16;
  523. end;
  524. Prev := Temp;
  525. Temp := Temp*ValUInt(base);
  526. If (u >= base) or
  527. (ValUInt(maxNewValue-u) < Temp) or
  528. (prev > maxPrevValue) Then
  529. Begin
  530. fpc_Val_SInt_ShortStr := 0;
  531. Exit
  532. End;
  533. Temp:=Temp+u;
  534. inc(code);
  535. end;
  536. code := 0;
  537. fpc_Val_SInt_ShortStr := ValSInt(Temp);
  538. If Negative Then
  539. fpc_Val_SInt_ShortStr := -fpc_Val_SInt_ShortStr;
  540. If Not(Negative) and (base <> 10) Then
  541. {sign extend the result to allow proper range checking}
  542. Case DestSize of
  543. 1: fpc_Val_SInt_ShortStr := shortint(fpc_Val_SInt_ShortStr);
  544. 2: fpc_Val_SInt_ShortStr := smallint(fpc_Val_SInt_ShortStr);
  545. { Uncomment the folling once full 64bit support is in place
  546. 4: fpc_Val_SInt_ShortStr := SizeInt(fpc_Val_SInt_ShortStr);}
  547. End;
  548. end;
  549. { we need this for fpc_Val_SInt_Ansistr and fpc_Val_SInt_WideStr because }
  550. { we have to pass the DestSize parameter on (JM) }
  551. Function int_Val_SInt_ShortStr(DestSize: SizeInt; Const S: ShortString; var Code: ValSInt): ValSInt; [external name 'FPC_VAL_SINT_SHORTSTR'];
  552. Function fpc_Val_UInt_Shortstr(Const S: ShortString; var Code: ValSInt): ValUInt; [public, alias:'FPC_VAL_UINT_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  553. var
  554. u, prev : ValUInt;
  555. base : byte;
  556. negative : boolean;
  557. begin
  558. fpc_Val_UInt_Shortstr:=0;
  559. Code:=InitVal(s,negative,base);
  560. If Negative or (Code>length(s)) Then
  561. Exit;
  562. while Code<=Length(s) do
  563. begin
  564. case s[Code] of
  565. '0'..'9' : u:=Ord(S[Code])-Ord('0');
  566. 'A'..'F' : u:=Ord(S[Code])-(Ord('A')-10);
  567. 'a'..'f' : u:=Ord(S[Code])-(Ord('a')-10);
  568. else
  569. u:=16;
  570. end;
  571. prev := fpc_Val_UInt_Shortstr;
  572. If (u>=base) or
  573. (ValUInt(MaxUIntValue-u) div ValUInt(Base)<prev) then
  574. begin
  575. fpc_Val_UInt_Shortstr:=0;
  576. exit;
  577. end;
  578. fpc_Val_UInt_Shortstr:=fpc_Val_UInt_Shortstr*ValUInt(base) + u;
  579. inc(code);
  580. end;
  581. code := 0;
  582. end;
  583. {$ifndef CPU64}
  584. Function fpc_val_int64_shortstr(Const S: ShortString; var Code: ValSInt): Int64; [public, alias:'FPC_VAL_INT64_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  585. type
  586. QWordRec = packed record
  587. l1,l2: longint;
  588. end;
  589. var
  590. u, temp, prev, maxint64, maxqword : qword;
  591. base : byte;
  592. negative : boolean;
  593. begin
  594. fpc_val_int64_shortstr := 0;
  595. Temp:=0;
  596. Code:=InitVal(s,negative,base);
  597. if Code>length(s) then
  598. exit;
  599. { high(int64) produces 0 in version 1.0 (JM) }
  600. with qwordrec(maxint64) do
  601. begin
  602. {$ifdef ENDIAN_LITTLE}
  603. l1 := longint($ffffffff);
  604. l2 := $7fffffff;
  605. {$else ENDIAN_LITTLE}
  606. l1 := $7fffffff;
  607. l2 := longint($ffffffff);
  608. {$endif ENDIAN_LITTLE}
  609. end;
  610. with qwordrec(maxqword) do
  611. begin
  612. l1 := longint($ffffffff);
  613. l2 := longint($ffffffff);
  614. end;
  615. while Code<=Length(s) do
  616. begin
  617. case s[Code] of
  618. '0'..'9' : u:=Ord(S[Code])-Ord('0');
  619. 'A'..'F' : u:=Ord(S[Code])-(Ord('A')-10);
  620. 'a'..'f' : u:=Ord(S[Code])-(Ord('a')-10);
  621. else
  622. u:=16;
  623. end;
  624. Prev:=Temp;
  625. Temp:=Temp*Int64(base);
  626. If (u >= base) or
  627. ((base = 10) and
  628. (maxint64-temp+ord(negative) < u)) or
  629. ((base <> 10) and
  630. (qword(maxqword-temp) < u)) or
  631. (prev > maxqword div qword(base)) Then
  632. Begin
  633. fpc_val_int64_shortstr := 0;
  634. Exit
  635. End;
  636. Temp:=Temp+u;
  637. inc(code);
  638. end;
  639. code:=0;
  640. fpc_val_int64_shortstr:=int64(Temp);
  641. If Negative Then
  642. fpc_val_int64_shortstr:=-fpc_val_int64_shortstr;
  643. end;
  644. Function fpc_val_qword_shortstr(Const S: ShortString; var Code: ValSInt): QWord; [public, alias:'FPC_VAL_QWORD_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  645. type qwordrec = packed record
  646. l1,l2: longint;
  647. end;
  648. var
  649. u, prev, maxqword: QWord;
  650. base : byte;
  651. negative : boolean;
  652. begin
  653. fpc_val_qword_shortstr:=0;
  654. Code:=InitVal(s,negative,base);
  655. If Negative or (Code>length(s)) Then
  656. Exit;
  657. with qwordrec(maxqword) do
  658. begin
  659. l1 := longint($ffffffff);
  660. l2 := longint($ffffffff);
  661. end;
  662. while Code<=Length(s) do
  663. begin
  664. case s[Code] of
  665. '0'..'9' : u:=Ord(S[Code])-Ord('0');
  666. 'A'..'F' : u:=Ord(S[Code])-(Ord('A')-10);
  667. 'a'..'f' : u:=Ord(S[Code])-(Ord('a')-10);
  668. else
  669. u:=16;
  670. end;
  671. prev := fpc_val_qword_shortstr;
  672. If (u>=base) or
  673. ((QWord(maxqword-u) div QWord(base))<prev) then
  674. Begin
  675. fpc_val_qword_shortstr := 0;
  676. Exit
  677. End;
  678. fpc_val_qword_shortstr:=fpc_val_qword_shortstr*QWord(base) + u;
  679. inc(code);
  680. end;
  681. code := 0;
  682. end;
  683. {$endif CPU64}
  684. Function fpc_Val_Real_ShortStr(const s : shortstring; var code : ValSInt): ValReal; [public, alias:'FPC_VAL_REAL_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  685. var
  686. hd,
  687. esign,sign : valreal;
  688. exponent,i : SizeInt;
  689. flags : byte;
  690. begin
  691. fpc_Val_Real_ShortStr:=0.0;
  692. code:=1;
  693. exponent:=0;
  694. esign:=1;
  695. flags:=0;
  696. sign:=1;
  697. while (code<=length(s)) and (s[code] in [' ',#9]) do
  698. inc(code);
  699. case s[code] of
  700. '+' : inc(code);
  701. '-' : begin
  702. sign:=-1;
  703. inc(code);
  704. end;
  705. end;
  706. while (Code<=Length(s)) and (s[code] in ['0'..'9']) do
  707. begin
  708. { Read integer part }
  709. flags:=flags or 1;
  710. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr*10+(ord(s[code])-ord('0'));
  711. inc(code);
  712. end;
  713. { Decimal ? }
  714. if (length(s)>=code) and (s[code]='.') then
  715. begin
  716. hd:=1.0;
  717. inc(code);
  718. while (length(s)>=code) and (s[code] in ['0'..'9']) do
  719. begin
  720. { Read fractional part. }
  721. flags:=flags or 2;
  722. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr*10+(ord(s[code])-ord('0'));
  723. hd:=hd*10.0;
  724. inc(code);
  725. end;
  726. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr/hd;
  727. end;
  728. { Again, read integer and fractional part}
  729. if flags=0 then
  730. begin
  731. fpc_Val_Real_ShortStr:=0.0;
  732. exit;
  733. end;
  734. { Exponent ? }
  735. if (length(s)>=code) and (upcase(s[code])='E') then
  736. begin
  737. inc(code);
  738. if Length(s) >= code then
  739. if s[code]='+' then
  740. inc(code)
  741. else
  742. if s[code]='-' then
  743. begin
  744. esign:=-1;
  745. inc(code);
  746. end;
  747. if (length(s)<code) or not(s[code] in ['0'..'9']) then
  748. begin
  749. fpc_Val_Real_ShortStr:=0.0;
  750. exit;
  751. end;
  752. while (length(s)>=code) and (s[code] in ['0'..'9']) do
  753. begin
  754. exponent:=exponent*10;
  755. exponent:=exponent+ord(s[code])-ord('0');
  756. inc(code);
  757. end;
  758. end;
  759. { Calculate Exponent }
  760. {
  761. if esign>0 then
  762. for i:=1 to exponent do
  763. fpc_Val_Real_ShortStr:=Val_Real_ShortStr*10
  764. else
  765. for i:=1 to exponent do
  766. fpc_Val_Real_ShortStr:=Val_Real_ShortStr/10; }
  767. hd:=1.0;
  768. for i:=1 to exponent do
  769. hd:=hd*10.0;
  770. if esign>0 then
  771. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr*hd
  772. else
  773. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr/hd;
  774. { Not all characters are read ? }
  775. if length(s)>=code then
  776. begin
  777. fpc_Val_Real_ShortStr:=0.0;
  778. exit;
  779. end;
  780. { evaluate sign }
  781. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr*sign;
  782. { success ! }
  783. code:=0;
  784. end;
  785. Procedure SetString (Var S : Shortstring; Buf : PChar; Len : SizeInt);
  786. begin
  787. If Len > High(S) then
  788. Len := High(S);
  789. SetLength(S,Len);
  790. If Buf<>Nil then
  791. begin
  792. Move (Buf[0],S[1],Len);
  793. end;
  794. end;
  795. {
  796. $Log$
  797. Revision 1.36 2005-04-02 07:57:38 florian
  798. + 0x is now recognized as hex prefix
  799. Revision 1.35 2005/03/20 12:45:19 michael
  800. + Patch from Colin Western to fix uninitialized memory reads
  801. Revision 1.34 2005/02/25 12:34:46 peter
  802. * added HexStr(Pointer)
  803. Revision 1.33 2005/02/14 17:13:27 peter
  804. * truncate log
  805. }