sstrings.inc 21 KB

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