sstrings.inc 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908
  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 space (b : byte): shortstring;
  300. begin
  301. space[0] := chr(b);
  302. FillChar (Space[1],b,' ');
  303. end;
  304. {*****************************************************************************
  305. Str() Helpers
  306. *****************************************************************************}
  307. {$ifdef STR_USES_VALINT}
  308. procedure fpc_shortstr_SInt(v : valSInt;len : SizeInt;var s : shortstring);[public,alias:'FPC_SHORTSTR_SINT']; {$ifdef hascompilerproc} compilerproc; {$endif}
  309. {$else}
  310. procedure fpc_shortstr_longint(v : longint;len : SizeInt;var s : shortstring);[public,alias:'FPC_SHORTSTR_LONGINT']; {$ifdef hascompilerproc} compilerproc; {$endif}
  311. {$endif}
  312. begin
  313. int_str(v,s);
  314. if length(s)<len then
  315. s:=space(len-length(s))+s;
  316. end;
  317. {$ifdef STR_USES_VALINT}
  318. procedure fpc_shortstr_UInt(v : valUInt;len : SizeInt;var s : shortstring);[public,alias:'FPC_SHORTSTR_UINT']; {$ifdef hascompilerproc} compilerproc; {$endif}
  319. {$else}
  320. {$ifdef ver1_0}
  321. procedure fpc_shortstr_cardinal(v : longword;len : SizeInt;var s : shortstring);[public,alias:'FPC_SHORTSTR_CARDINAL']; {$ifdef hascompilerproc} compilerproc; {$endif}
  322. {$else}
  323. procedure fpc_shortstr_longword(v : longword;len : SizeInt;var s : shortstring);[public,alias:'FPC_SHORTSTR_LONGWORD']; {$ifdef hascompilerproc} compilerproc; {$endif}
  324. {$endif}
  325. {$endif}
  326. begin
  327. int_str(v,s);
  328. if length(s)<len then
  329. s:=space(len-length(s))+s;
  330. end;
  331. {$ifndef CPU64}
  332. procedure fpc_shortstr_qword(v : qword;len : longint;var s : shortstring);[public,alias:'FPC_SHORTSTR_QWORD']; {$ifdef hascompilerproc} compilerproc; {$endif}
  333. begin
  334. int_str(v,s);
  335. if length(s)<len then
  336. s:=space(len-length(s))+s;
  337. end;
  338. procedure fpc_shortstr_int64(v : int64;len : longint;var s : shortstring);[public,alias:'FPC_SHORTSTR_INT64']; {$ifdef hascompilerproc} compilerproc; {$endif}
  339. begin
  340. int_str(v,s);
  341. if length(s)<len then
  342. s:=space(len-length(s))+s;
  343. end;
  344. {$endif CPU64}
  345. { fpc_shortstr_sInt must appear before this file is included, because }
  346. { it's used inside real2str.inc and otherwise the searching via the }
  347. { compilerproc name will fail (JM) }
  348. {$I real2str.inc}
  349. procedure fpc_ShortStr_Float(d : ValReal;len,fr,rt : SizeInt;var s : shortstring);[public,alias:'FPC_SHORTSTR_FLOAT']; {$ifdef hascompilerproc}compilerproc;{$endif hascompilerproc}
  350. begin
  351. str_real(len,fr,d,treal_type(rt),s);
  352. end;
  353. {
  354. Array Of Char Str() helpers
  355. }
  356. {$ifdef STR_USES_VALINT}
  357. procedure fpc_chararray_sint(v : valsint;len : SizeInt;var a:array of char);{$ifdef hascompilerproc} compilerproc; {$endif}
  358. {$else}
  359. procedure fpc_chararray_longint(v : longint;len : SizeInt;var a:array of char);{$ifdef hascompilerproc} compilerproc; {$endif}
  360. {$endif}
  361. var
  362. ss : shortstring;
  363. maxlen : SizeInt;
  364. begin
  365. int_str(v,ss);
  366. if length(ss)<len then
  367. ss:=space(len-length(ss))+ss;
  368. if length(ss)<high(a)+1 then
  369. maxlen:=length(ss)
  370. else
  371. maxlen:=high(a)+1;
  372. move(ss[1],pchar(@a)^,maxlen);
  373. end;
  374. {$ifdef STR_USES_VALINT}
  375. procedure fpc_chararray_uint(v : valuint;len : SizeInt;var a : array of char);{$ifdef hascompilerproc} compilerproc; {$endif}
  376. {$else}
  377. procedure fpc_chararray_longword(v : longword;len : SizeInt;var a : array of char);{$ifdef hascompilerproc} compilerproc; {$endif}
  378. {$endif}
  379. var
  380. ss : shortstring;
  381. maxlen : SizeInt;
  382. begin
  383. int_str(v,ss);
  384. if length(ss)<len then
  385. ss:=space(len-length(ss))+ss;
  386. if length(ss)<high(a)+1 then
  387. maxlen:=length(ss)
  388. else
  389. maxlen:=high(a)+1;
  390. move(ss[1],pchar(@a)^,maxlen);
  391. end;
  392. {$ifndef CPU64}
  393. procedure fpc_chararray_qword(v : qword;len : SizeInt;var a : array of char);{$ifdef hascompilerproc} compilerproc; {$endif}
  394. var
  395. ss : shortstring;
  396. maxlen : SizeInt;
  397. begin
  398. int_str(v,ss);
  399. if length(ss)<len then
  400. ss:=space(len-length(ss))+ss;
  401. if length(ss)<high(a)+1 then
  402. maxlen:=length(ss)
  403. else
  404. maxlen:=high(a)+1;
  405. move(ss[1],pchar(@a)^,maxlen);
  406. end;
  407. procedure fpc_chararray_int64(v : int64;len : SizeInt;var a : array of char);{$ifdef hascompilerproc} compilerproc; {$endif}
  408. var
  409. ss : shortstring;
  410. maxlen : SizeInt;
  411. begin
  412. int_str(v,ss);
  413. if length(ss)<len then
  414. ss:=space(len-length(ss))+ss;
  415. if length(ss)<high(a)+1 then
  416. maxlen:=length(ss)
  417. else
  418. maxlen:=high(a)+1;
  419. move(ss[1],pchar(@a)^,maxlen);
  420. end;
  421. {$endif CPU64}
  422. procedure fpc_chararray_Float(d : ValReal;len,fr,rt : SizeInt;var a : array of char);{$ifdef hascompilerproc}compilerproc;{$endif hascompilerproc}
  423. var
  424. ss : shortstring;
  425. maxlen : SizeInt;
  426. begin
  427. str_real(len,fr,d,treal_type(rt),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. {*****************************************************************************
  435. Val() Functions
  436. *****************************************************************************}
  437. Function InitVal(const s:shortstring;var negativ:boolean;var base:byte):ValSInt;
  438. var
  439. Code : SizeInt;
  440. begin
  441. {Skip Spaces and Tab}
  442. code:=1;
  443. while (code<=length(s)) and (s[code] in [' ',#9]) do
  444. inc(code);
  445. {Sign}
  446. negativ:=false;
  447. case s[code] of
  448. '-' : begin
  449. negativ:=true;
  450. inc(code);
  451. end;
  452. '+' : inc(code);
  453. end;
  454. {Base}
  455. base:=10;
  456. if code<=length(s) then
  457. begin
  458. case s[code] of
  459. '$' : begin
  460. base:=16;
  461. repeat
  462. inc(code);
  463. until (code>=length(s)) or (s[code]<>'0');
  464. end;
  465. '%' : begin
  466. base:=2;
  467. inc(code);
  468. end;
  469. '&' : begin
  470. Base:=8;
  471. repeat
  472. inc(code);
  473. until (code>=length(s)) or (s[code]<>'0');
  474. end;
  475. end;
  476. end;
  477. InitVal:=code;
  478. end;
  479. Function fpc_Val_SInt_ShortStr(DestSize: SizeInt; Const S: ShortString; var Code: ValSInt): ValSInt; [public, alias:'FPC_VAL_SINT_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  480. var
  481. u, temp, prev, maxPrevValue, maxNewValue: ValUInt;
  482. base : byte;
  483. negative : boolean;
  484. begin
  485. fpc_Val_SInt_ShortStr := 0;
  486. Temp:=0;
  487. Code:=InitVal(s,negative,base);
  488. if Code>length(s) then
  489. exit;
  490. maxPrevValue := ValUInt(MaxUIntValue) div ValUInt(Base);
  491. if (base = 10) then
  492. maxNewValue := MaxSIntValue + ord(negative)
  493. else
  494. maxNewValue := MaxUIntValue;
  495. while Code<=Length(s) do
  496. begin
  497. case s[Code] of
  498. '0'..'9' : u:=Ord(S[Code])-Ord('0');
  499. 'A'..'F' : u:=Ord(S[Code])-(Ord('A')-10);
  500. 'a'..'f' : u:=Ord(S[Code])-(Ord('a')-10);
  501. else
  502. u:=16;
  503. end;
  504. Prev := Temp;
  505. Temp := Temp*ValUInt(base);
  506. If (u >= base) or
  507. (ValUInt(maxNewValue-u) < Temp) or
  508. (prev > maxPrevValue) Then
  509. Begin
  510. fpc_Val_SInt_ShortStr := 0;
  511. Exit
  512. End;
  513. Temp:=Temp+u;
  514. inc(code);
  515. end;
  516. code := 0;
  517. fpc_Val_SInt_ShortStr := ValSInt(Temp);
  518. If Negative Then
  519. fpc_Val_SInt_ShortStr := -fpc_Val_SInt_ShortStr;
  520. If Not(Negative) and (base <> 10) Then
  521. {sign extend the result to allow proper range checking}
  522. Case DestSize of
  523. 1: fpc_Val_SInt_ShortStr := shortint(fpc_Val_SInt_ShortStr);
  524. 2: fpc_Val_SInt_ShortStr := smallint(fpc_Val_SInt_ShortStr);
  525. { Uncomment the folling once full 64bit support is in place
  526. 4: fpc_Val_SInt_ShortStr := SizeInt(fpc_Val_SInt_ShortStr);}
  527. End;
  528. end;
  529. {$ifdef hascompilerproc}
  530. { we need this for fpc_Val_SInt_Ansistr and fpc_Val_SInt_WideStr because }
  531. { we have to pass the DestSize parameter on (JM) }
  532. Function fpc_Val_SInt_ShortStr(DestSize: SizeInt; Const S: ShortString; var Code: ValSInt): ValSInt; [external name 'FPC_VAL_SINT_SHORTSTR'];
  533. {$endif hascompilerproc}
  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. l1 := longint($ffffffff);
  585. l2 := $7fffffff;
  586. end;
  587. with qwordrec(maxqword) do
  588. begin
  589. l1 := longint($ffffffff);
  590. l2 := longint($ffffffff);
  591. end;
  592. while Code<=Length(s) do
  593. begin
  594. case s[Code] of
  595. '0'..'9' : u:=Ord(S[Code])-Ord('0');
  596. 'A'..'F' : u:=Ord(S[Code])-(Ord('A')-10);
  597. 'a'..'f' : u:=Ord(S[Code])-(Ord('a')-10);
  598. else
  599. u:=16;
  600. end;
  601. Prev:=Temp;
  602. Temp:=Temp*Int64(base);
  603. If (u >= base) or
  604. ((base = 10) and
  605. (maxint64-temp+ord(negative) < u)) or
  606. ((base <> 10) and
  607. (qword(maxqword-temp) < u)) or
  608. (prev > maxqword div qword(base)) Then
  609. Begin
  610. fpc_val_int64_shortstr := 0;
  611. Exit
  612. End;
  613. Temp:=Temp+u;
  614. inc(code);
  615. end;
  616. code:=0;
  617. fpc_val_int64_shortstr:=int64(Temp);
  618. If Negative Then
  619. fpc_val_int64_shortstr:=-fpc_val_int64_shortstr;
  620. end;
  621. Function fpc_val_qword_shortstr(Const S: ShortString; var Code: ValSInt): QWord; [public, alias:'FPC_VAL_QWORD_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  622. type qwordrec = packed record
  623. l1,l2: longint;
  624. end;
  625. var
  626. u, prev, maxqword: QWord;
  627. base : byte;
  628. negative : boolean;
  629. begin
  630. fpc_val_qword_shortstr:=0;
  631. Code:=InitVal(s,negative,base);
  632. If Negative or (Code>length(s)) Then
  633. Exit;
  634. with qwordrec(maxqword) do
  635. begin
  636. l1 := longint($ffffffff);
  637. l2 := longint($ffffffff);
  638. end;
  639. while Code<=Length(s) do
  640. begin
  641. case s[Code] of
  642. '0'..'9' : u:=Ord(S[Code])-Ord('0');
  643. 'A'..'F' : u:=Ord(S[Code])-(Ord('A')-10);
  644. 'a'..'f' : u:=Ord(S[Code])-(Ord('a')-10);
  645. else
  646. u:=16;
  647. end;
  648. prev := fpc_val_qword_shortstr;
  649. If (u>=base) or
  650. ((QWord(maxqword-u) div QWord(base))<prev) then
  651. Begin
  652. fpc_val_qword_shortstr := 0;
  653. Exit
  654. End;
  655. fpc_val_qword_shortstr:=fpc_val_qword_shortstr*QWord(base) + u;
  656. inc(code);
  657. end;
  658. code := 0;
  659. end;
  660. {$endif CPU64}
  661. Function fpc_Val_Real_ShortStr(const s : shortstring; var code : ValSInt): ValReal; [public, alias:'FPC_VAL_REAL_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  662. var
  663. hd,
  664. esign,sign : valreal;
  665. exponent,i : SizeInt;
  666. flags : byte;
  667. begin
  668. fpc_Val_Real_ShortStr:=0.0;
  669. code:=1;
  670. exponent:=0;
  671. esign:=1;
  672. flags:=0;
  673. sign:=1;
  674. while (code<=length(s)) and (s[code] in [' ',#9]) do
  675. inc(code);
  676. case s[code] of
  677. '+' : inc(code);
  678. '-' : begin
  679. sign:=-1;
  680. inc(code);
  681. end;
  682. end;
  683. while (Code<=Length(s)) and (s[code] in ['0'..'9']) do
  684. begin
  685. { Read integer part }
  686. flags:=flags or 1;
  687. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr*10+(ord(s[code])-ord('0'));
  688. inc(code);
  689. end;
  690. { Decimal ? }
  691. if (s[code]='.') and (length(s)>=code) then
  692. begin
  693. hd:=1.0;
  694. inc(code);
  695. while (s[code] in ['0'..'9']) and (length(s)>=code) do
  696. begin
  697. { Read fractional part. }
  698. flags:=flags or 2;
  699. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr*10+(ord(s[code])-ord('0'));
  700. hd:=hd*10.0;
  701. inc(code);
  702. end;
  703. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr/hd;
  704. end;
  705. { Again, read integer and fractional part}
  706. if flags=0 then
  707. begin
  708. fpc_Val_Real_ShortStr:=0.0;
  709. exit;
  710. end;
  711. { Exponent ? }
  712. if (upcase(s[code])='E') and (length(s)>=code) then
  713. begin
  714. inc(code);
  715. if s[code]='+' then
  716. inc(code)
  717. else
  718. if s[code]='-' then
  719. begin
  720. esign:=-1;
  721. inc(code);
  722. end;
  723. if not(s[code] in ['0'..'9']) or (length(s)<code) then
  724. begin
  725. fpc_Val_Real_ShortStr:=0.0;
  726. exit;
  727. end;
  728. while (s[code] in ['0'..'9']) and (length(s)>=code) do
  729. begin
  730. exponent:=exponent*10;
  731. exponent:=exponent+ord(s[code])-ord('0');
  732. inc(code);
  733. end;
  734. end;
  735. { Calculate Exponent }
  736. {
  737. if esign>0 then
  738. for i:=1 to exponent do
  739. fpc_Val_Real_ShortStr:=Val_Real_ShortStr*10
  740. else
  741. for i:=1 to exponent do
  742. fpc_Val_Real_ShortStr:=Val_Real_ShortStr/10; }
  743. hd:=1.0;
  744. for i:=1 to exponent do
  745. hd:=hd*10.0;
  746. if esign>0 then
  747. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr*hd
  748. else
  749. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr/hd;
  750. { Not all characters are read ? }
  751. if length(s)>=code then
  752. begin
  753. fpc_Val_Real_ShortStr:=0.0;
  754. exit;
  755. end;
  756. { evaluate sign }
  757. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr*sign;
  758. { success ! }
  759. code:=0;
  760. end;
  761. Procedure SetString (Var S : Shortstring; Buf : PChar; Len : SizeInt);
  762. begin
  763. If Len > High(S) then
  764. Len := High(S);
  765. SetLength(S,Len);
  766. If Buf<>Nil then
  767. begin
  768. Move (Buf[0],S[1],Len);
  769. end;
  770. end;
  771. {
  772. $Log$
  773. Revision 1.30 2004-05-01 23:55:18 peter
  774. * replace strlenint with sizeint
  775. Revision 1.29 2004/05/01 20:52:50 peter
  776. * ValSInt fixed for 64 bit
  777. Revision 1.28 2004/04/29 18:59:43 peter
  778. * str() helpers now also use valint/valuint
  779. * int64/qword helpers disabled for cpu64
  780. Revision 1.27 2003/02/26 20:04:47 jonas
  781. * fixed shortstring version of setstring
  782. Revision 1.26 2002/10/21 19:52:47 jonas
  783. * fixed some buffer overflow errors in SetString (both short and
  784. ansistring versions) (merged)
  785. Revision 1.25 2002/10/19 17:06:50 michael
  786. + Added check for nil buffer to setstring
  787. Revision 1.24 2002/10/02 18:21:51 peter
  788. * Copy() changed to internal function calling compilerprocs
  789. * FPC_SHORTSTR_COPY renamed to FPC_SHORTSTR_ASSIGN because of the
  790. new copy functions
  791. Revision 1.23 2002/09/14 11:20:50 carl
  792. * Delphi compatibility fix (with string routines)
  793. Revision 1.22 2002/09/07 21:19:00 carl
  794. * cardinal -> longword
  795. Revision 1.21 2002/09/07 15:07:46 peter
  796. * old logs removed and tabs fixed
  797. Revision 1.20 2002/09/02 19:24:41 peter
  798. * array of char support for Str()
  799. Revision 1.19 2002/08/06 20:53:38 michael
  800. + Added support for octal strings (using &)
  801. Revision 1.18 2002/01/24 18:27:06 peter
  802. * lowercase() overloaded
  803. }