sstrings.inc 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917
  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. { we need this for fpc_Val_SInt_Ansistr and fpc_Val_SInt_WideStr because }
  530. { we have to pass the DestSize parameter on (JM) }
  531. Function int_Val_SInt_ShortStr(DestSize: SizeInt; Const S: ShortString; var Code: ValSInt): ValSInt; [external name 'FPC_VAL_SINT_SHORTSTR'];
  532. Function fpc_Val_UInt_Shortstr(Const S: ShortString; var Code: ValSInt): ValUInt; [public, alias:'FPC_VAL_UINT_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  533. var
  534. u, prev : ValUInt;
  535. base : byte;
  536. negative : boolean;
  537. begin
  538. fpc_Val_UInt_Shortstr:=0;
  539. Code:=InitVal(s,negative,base);
  540. If Negative or (Code>length(s)) Then
  541. Exit;
  542. while Code<=Length(s) do
  543. begin
  544. case s[Code] of
  545. '0'..'9' : u:=Ord(S[Code])-Ord('0');
  546. 'A'..'F' : u:=Ord(S[Code])-(Ord('A')-10);
  547. 'a'..'f' : u:=Ord(S[Code])-(Ord('a')-10);
  548. else
  549. u:=16;
  550. end;
  551. prev := fpc_Val_UInt_Shortstr;
  552. If (u>=base) or
  553. (ValUInt(MaxUIntValue-u) div ValUInt(Base)<prev) then
  554. begin
  555. fpc_Val_UInt_Shortstr:=0;
  556. exit;
  557. end;
  558. fpc_Val_UInt_Shortstr:=fpc_Val_UInt_Shortstr*ValUInt(base) + u;
  559. inc(code);
  560. end;
  561. code := 0;
  562. end;
  563. {$ifndef CPU64}
  564. Function fpc_val_int64_shortstr(Const S: ShortString; var Code: ValSInt): Int64; [public, alias:'FPC_VAL_INT64_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  565. type
  566. QWordRec = packed record
  567. l1,l2: longint;
  568. end;
  569. var
  570. u, temp, prev, maxint64, maxqword : qword;
  571. base : byte;
  572. negative : boolean;
  573. begin
  574. fpc_val_int64_shortstr := 0;
  575. Temp:=0;
  576. Code:=InitVal(s,negative,base);
  577. if Code>length(s) then
  578. exit;
  579. { high(int64) produces 0 in version 1.0 (JM) }
  580. with qwordrec(maxint64) do
  581. begin
  582. {$ifdef ENDIAN_LITTLE}
  583. l1 := longint($ffffffff);
  584. l2 := $7fffffff;
  585. {$else ENDIAN_LITTLE}
  586. l1 := $7fffffff;
  587. l2 := longint($ffffffff);
  588. {$endif ENDIAN_LITTLE}
  589. end;
  590. with qwordrec(maxqword) do
  591. begin
  592. l1 := longint($ffffffff);
  593. l2 := longint($ffffffff);
  594. end;
  595. while Code<=Length(s) do
  596. begin
  597. case s[Code] of
  598. '0'..'9' : u:=Ord(S[Code])-Ord('0');
  599. 'A'..'F' : u:=Ord(S[Code])-(Ord('A')-10);
  600. 'a'..'f' : u:=Ord(S[Code])-(Ord('a')-10);
  601. else
  602. u:=16;
  603. end;
  604. Prev:=Temp;
  605. Temp:=Temp*Int64(base);
  606. If (u >= base) or
  607. ((base = 10) and
  608. (maxint64-temp+ord(negative) < u)) or
  609. ((base <> 10) and
  610. (qword(maxqword-temp) < u)) or
  611. (prev > maxqword div qword(base)) Then
  612. Begin
  613. fpc_val_int64_shortstr := 0;
  614. Exit
  615. End;
  616. Temp:=Temp+u;
  617. inc(code);
  618. end;
  619. code:=0;
  620. fpc_val_int64_shortstr:=int64(Temp);
  621. If Negative Then
  622. fpc_val_int64_shortstr:=-fpc_val_int64_shortstr;
  623. end;
  624. Function fpc_val_qword_shortstr(Const S: ShortString; var Code: ValSInt): QWord; [public, alias:'FPC_VAL_QWORD_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  625. type qwordrec = packed record
  626. l1,l2: longint;
  627. end;
  628. var
  629. u, prev, maxqword: QWord;
  630. base : byte;
  631. negative : boolean;
  632. begin
  633. fpc_val_qword_shortstr:=0;
  634. Code:=InitVal(s,negative,base);
  635. If Negative or (Code>length(s)) Then
  636. Exit;
  637. with qwordrec(maxqword) do
  638. begin
  639. l1 := longint($ffffffff);
  640. l2 := longint($ffffffff);
  641. end;
  642. while Code<=Length(s) do
  643. begin
  644. case s[Code] of
  645. '0'..'9' : u:=Ord(S[Code])-Ord('0');
  646. 'A'..'F' : u:=Ord(S[Code])-(Ord('A')-10);
  647. 'a'..'f' : u:=Ord(S[Code])-(Ord('a')-10);
  648. else
  649. u:=16;
  650. end;
  651. prev := fpc_val_qword_shortstr;
  652. If (u>=base) or
  653. ((QWord(maxqword-u) div QWord(base))<prev) then
  654. Begin
  655. fpc_val_qword_shortstr := 0;
  656. Exit
  657. End;
  658. fpc_val_qword_shortstr:=fpc_val_qword_shortstr*QWord(base) + u;
  659. inc(code);
  660. end;
  661. code := 0;
  662. end;
  663. {$endif CPU64}
  664. Function fpc_Val_Real_ShortStr(const s : shortstring; var code : ValSInt): ValReal; [public, alias:'FPC_VAL_REAL_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  665. var
  666. hd,
  667. esign,sign : valreal;
  668. exponent,i : SizeInt;
  669. flags : byte;
  670. begin
  671. fpc_Val_Real_ShortStr:=0.0;
  672. code:=1;
  673. exponent:=0;
  674. esign:=1;
  675. flags:=0;
  676. sign:=1;
  677. while (code<=length(s)) and (s[code] in [' ',#9]) do
  678. inc(code);
  679. case s[code] of
  680. '+' : inc(code);
  681. '-' : begin
  682. sign:=-1;
  683. inc(code);
  684. end;
  685. end;
  686. while (Code<=Length(s)) and (s[code] in ['0'..'9']) do
  687. begin
  688. { Read integer part }
  689. flags:=flags or 1;
  690. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr*10+(ord(s[code])-ord('0'));
  691. inc(code);
  692. end;
  693. { Decimal ? }
  694. if (s[code]='.') and (length(s)>=code) then
  695. begin
  696. hd:=1.0;
  697. inc(code);
  698. while (s[code] in ['0'..'9']) and (length(s)>=code) do
  699. begin
  700. { Read fractional part. }
  701. flags:=flags or 2;
  702. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr*10+(ord(s[code])-ord('0'));
  703. hd:=hd*10.0;
  704. inc(code);
  705. end;
  706. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr/hd;
  707. end;
  708. { Again, read integer and fractional part}
  709. if flags=0 then
  710. begin
  711. fpc_Val_Real_ShortStr:=0.0;
  712. exit;
  713. end;
  714. { Exponent ? }
  715. if (upcase(s[code])='E') and (length(s)>=code) then
  716. begin
  717. inc(code);
  718. if s[code]='+' then
  719. inc(code)
  720. else
  721. if s[code]='-' then
  722. begin
  723. esign:=-1;
  724. inc(code);
  725. end;
  726. if not(s[code] in ['0'..'9']) or (length(s)<code) then
  727. begin
  728. fpc_Val_Real_ShortStr:=0.0;
  729. exit;
  730. end;
  731. while (s[code] in ['0'..'9']) and (length(s)>=code) do
  732. begin
  733. exponent:=exponent*10;
  734. exponent:=exponent+ord(s[code])-ord('0');
  735. inc(code);
  736. end;
  737. end;
  738. { Calculate Exponent }
  739. {
  740. if esign>0 then
  741. for i:=1 to exponent do
  742. fpc_Val_Real_ShortStr:=Val_Real_ShortStr*10
  743. else
  744. for i:=1 to exponent do
  745. fpc_Val_Real_ShortStr:=Val_Real_ShortStr/10; }
  746. hd:=1.0;
  747. for i:=1 to exponent do
  748. hd:=hd*10.0;
  749. if esign>0 then
  750. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr*hd
  751. else
  752. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr/hd;
  753. { Not all characters are read ? }
  754. if length(s)>=code then
  755. begin
  756. fpc_Val_Real_ShortStr:=0.0;
  757. exit;
  758. end;
  759. { evaluate sign }
  760. fpc_Val_Real_ShortStr:=fpc_Val_Real_ShortStr*sign;
  761. { success ! }
  762. code:=0;
  763. end;
  764. Procedure SetString (Var S : Shortstring; Buf : PChar; Len : SizeInt);
  765. begin
  766. If Len > High(S) then
  767. Len := High(S);
  768. SetLength(S,Len);
  769. If Buf<>Nil then
  770. begin
  771. Move (Buf[0],S[1],Len);
  772. end;
  773. end;
  774. {
  775. $Log$
  776. Revision 1.32 2004-11-17 22:19:04 peter
  777. internconst, internproc and some external declarations moved to interface
  778. Revision 1.31 2004/11/02 22:38:58 jonas
  779. * fixed endianess bug in fpc_val_int64_shortstr() (webtbf/tw2128)
  780. Revision 1.30 2004/05/01 23:55:18 peter
  781. * replace strlenint with sizeint
  782. Revision 1.29 2004/05/01 20:52:50 peter
  783. * ValSInt fixed for 64 bit
  784. Revision 1.28 2004/04/29 18:59:43 peter
  785. * str() helpers now also use valint/valuint
  786. * int64/qword helpers disabled for cpu64
  787. Revision 1.27 2003/02/26 20:04:47 jonas
  788. * fixed shortstring version of setstring
  789. Revision 1.26 2002/10/21 19:52:47 jonas
  790. * fixed some buffer overflow errors in SetString (both short and
  791. ansistring versions) (merged)
  792. Revision 1.25 2002/10/19 17:06:50 michael
  793. + Added check for nil buffer to setstring
  794. Revision 1.24 2002/10/02 18:21:51 peter
  795. * Copy() changed to internal function calling compilerprocs
  796. * FPC_SHORTSTR_COPY renamed to FPC_SHORTSTR_ASSIGN because of the
  797. new copy functions
  798. Revision 1.23 2002/09/14 11:20:50 carl
  799. * Delphi compatibility fix (with string routines)
  800. Revision 1.22 2002/09/07 21:19:00 carl
  801. * cardinal -> longword
  802. Revision 1.21 2002/09/07 15:07:46 peter
  803. * old logs removed and tabs fixed
  804. Revision 1.20 2002/09/02 19:24:41 peter
  805. * array of char support for Str()
  806. Revision 1.19 2002/08/06 20:53:38 michael
  807. + Added support for octal strings (using &)
  808. Revision 1.18 2002/01/24 18:27:06 peter
  809. * lowercase() overloaded
  810. }