astrings.inc 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by Michael Van Canneyt,
  4. member of the Free Pascal development team.
  5. This file implements AnsiStrings for FPC
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. { This will release some functions for special shortstring support }
  13. { define EXTRAANSISHORT}
  14. {
  15. This file contains the implementation of the AnsiString type,
  16. and all things that are needed for it.
  17. AnsiString is defined as a 'silent' pchar :
  18. a pchar that points to :
  19. @-8 : SizeInt for reference count;
  20. @-4 : SizeInt for size;
  21. @ : String + Terminating #0;
  22. Pchar(Ansistring) is a valid typecast.
  23. So AS[i] is converted to the address @AS+i-1.
  24. Constants should be assigned a reference count of -1
  25. Meaning that they can't be disposed of.
  26. }
  27. (*
  28. Type
  29. PAnsiRec = ^TAnsiRec;
  30. TAnsiRec = Packed Record
  31. Ref,
  32. Len : SizeInt;
  33. First : Char;
  34. end;
  35. Const
  36. AnsiRecLen = SizeOf(TAnsiRec);
  37. FirstOff = SizeOf(TAnsiRec)-1;
  38. *)
  39. {****************************************************************************
  40. Internal functions, not in interface.
  41. ****************************************************************************}
  42. (*
  43. Function NewAnsiString(Len : SizeInt) : Pointer;
  44. {
  45. Allocate a new AnsiString on the heap.
  46. initialize it to zero length and reference count 1.
  47. }
  48. Var
  49. P : Pointer;
  50. begin
  51. { request a multiple of 16 because the heap manager alloctes anyways chunks of 16 bytes }
  52. GetMem(P,Len+AnsiRecLen);
  53. If P<>Nil then
  54. begin
  55. PAnsiRec(P)^.Ref:=1; { Set reference count }
  56. PAnsiRec(P)^.Len:=0; { Initial length }
  57. PAnsiRec(P)^.First:=#0; { Terminating #0 }
  58. inc(p,firstoff); { Points to string now }
  59. end;
  60. NewAnsiString:=P;
  61. end;
  62. Procedure DisposeAnsiString(Var S : Pointer); {$IFNDEF VER2_0} Inline; {$ENDIF}
  63. {
  64. Deallocates a AnsiString From the heap.
  65. }
  66. begin
  67. If S=Nil then
  68. exit;
  69. Dec (S,FirstOff);
  70. FreeMem (S);
  71. S:=Nil;
  72. end;
  73. {$ifndef FPC_SYSTEM_HAS_ANSISTR_DECR_REF}
  74. Procedure fpc_ansistr_decr_ref (Var S : Pointer); [Public,Alias:'FPC_ANSISTR_DECR_REF']; compilerproc;
  75. {
  76. Decreases the ReferenceCount of a non constant ansistring;
  77. If the reference count is zero, deallocate the string;
  78. }
  79. Type
  80. pSizeInt = ^SizeInt;
  81. Var
  82. l : pSizeInt;
  83. Begin
  84. { Zero string }
  85. If S=Nil then exit;
  86. { check for constant strings ...}
  87. l:=@PAnsiRec(S-FirstOff)^.Ref;
  88. If l^<0 then exit;
  89. { declocked does a MT safe dec and returns true, if the counter is 0 }
  90. If declocked(l^) then
  91. { Ref count dropped to zero }
  92. DisposeAnsiString (S); { Remove...}
  93. end;
  94. {$endif FPC_SYSTEM_HAS_ANSISTR_DECR_REF}
  95. { also define alias for internal use in the system unit }
  96. Procedure fpc_ansistr_decr_ref (Var S : Pointer); [external name 'FPC_ANSISTR_DECR_REF'];
  97. Procedure fpc_AnsiStr_Incr_Ref (S : Pointer); [Public,Alias:'FPC_ANSISTR_INCR_REF']; compilerproc; {$IFNDEF VER2_0} Inline; {$ENDIF}
  98. Begin
  99. If S=Nil then
  100. exit;
  101. { Let's be paranoid : Constant string ??}
  102. If PAnsiRec(S-FirstOff)^.Ref<0 then exit;
  103. inclocked(PAnsiRec(S-FirstOff)^.Ref);
  104. end;
  105. { also define alias which can be used inside the system unit }
  106. Procedure fpc_AnsiStr_Incr_Ref (S : Pointer); [external name 'FPC_ANSISTR_INCR_REF'];
  107. *)
  108. Procedure fpc_AnsiStr_Assign (Var DestS : jlobject;S2 : jlobject); compilerproc;
  109. {
  110. Assigns S2 to S1 (S1:=S2), taking in account reference counts.
  111. }
  112. begin
  113. (*
  114. if DestS=S2 then
  115. exit;
  116. If S2<>nil then
  117. If PAnsiRec(S2-FirstOff)^.Ref>0 then
  118. inclocked(PAnsiRec(S2-FirstOff)^.ref);
  119. { Decrease the reference count on the old S1 }
  120. fpc_ansistr_decr_ref (DestS);
  121. { And finally, have DestS pointing to S2 (or its copy) }
  122. DestS:=S2;
  123. *)
  124. end;
  125. (*
  126. { alias for internal use }
  127. Procedure fpc_AnsiStr_Assign (Var S1 : Pointer;S2 : Pointer);[external name 'FPC_ANSISTR_ASSIGN'];
  128. *)
  129. function fpc_AnsiStr_Concat (const S1,S2 : AnsiString): ansistring; compilerproc;
  130. (*
  131. Var
  132. Size,Location : SizeInt;
  133. pc : pchar;
  134. *)
  135. begin
  136. (*
  137. { only assign if s1 or s2 is empty }
  138. if (S1='') then
  139. begin
  140. result:=s2;
  141. exit;
  142. end;
  143. if (S2='') then
  144. begin
  145. result:=s1;
  146. exit;
  147. end;
  148. Location:=Length(S1);
  149. Size:=length(S2);
  150. SetLength(result,Size+Location);
  151. pc:=pchar(result);
  152. Move(S1[1],pc^,Location);
  153. inc(pc,location);
  154. Move(S2[1],pc^,Size+1);
  155. *)
  156. end;
  157. (*
  158. function fpc_AnsiStr_Concat_multi (const sarr:array of Ansistring): ansistring; compilerproc;
  159. Var
  160. i : Longint;
  161. p : pointer;
  162. pc : pchar;
  163. Size,NewLen : SizeInt;
  164. begin
  165. { First calculate size of the result so we can do
  166. a single call to SetLength() }
  167. NewLen:=0;
  168. for i:=low(sarr) to high(sarr) do
  169. inc(NewLen,length(sarr[i]));
  170. SetLength(result,NewLen);
  171. pc:=pchar(result);
  172. for i:=low(sarr) to high(sarr) do
  173. begin
  174. p:=pointer(sarr[i]);
  175. if assigned(p) then
  176. begin
  177. Size:=length(ansistring(p));
  178. Move(pchar(p)^,pc^,Size+1);
  179. inc(pc,size);
  180. end;
  181. end;
  182. end;
  183. *)
  184. (*
  185. {$ifndef FPC_STRTOSHORTSTRINGPROC}
  186. { the following declaration has exactly the same effect as }
  187. { procedure fpc_AnsiStr_To_ShortStr (Var S1 : ShortString;S2 : Pointer); }
  188. { which is what the old helper was, so we don't need an extra implementation }
  189. { of the old helper (JM) }
  190. function fpc_AnsiStr_To_ShortStr (high_of_res: SizeInt;const S2 : Ansistring): shortstring;[Public, alias: 'FPC_ANSISTR_TO_SHORTSTR']; compilerproc;
  191. {
  192. Converts a AnsiString to a ShortString;
  193. }
  194. Var
  195. Size : SizeInt;
  196. begin
  197. if S2='' then
  198. fpc_AnsiStr_To_ShortStr:=''
  199. else
  200. begin
  201. Size:=Length(S2);
  202. If Size>high_of_res then
  203. Size:=high_of_res;
  204. Move (S2[1],fpc_AnsiStr_To_ShortStr[1],Size);
  205. byte(fpc_AnsiStr_To_ShortStr[0]):=byte(Size);
  206. end;
  207. end;
  208. {$else FPC_STRTOSHORTSTRINGPROC}
  209. procedure fpc_AnsiStr_To_ShortStr (out res: shortstring; const S2 : Ansistring);[Public, alias: 'FPC_ANSISTR_TO_SHORTSTR']; compilerproc;
  210. {
  211. Converts a AnsiString to a ShortString;
  212. }
  213. Var
  214. Size : SizeInt;
  215. begin
  216. if S2='' then
  217. res:=''
  218. else
  219. begin
  220. Size:=Length(S2);
  221. If Size>high(res) then
  222. Size:=high(res);
  223. Move (S2[1],res[1],Size);
  224. byte(res[0]):=byte(Size);
  225. end;
  226. end;
  227. {$endif FPC_STRTOSHORTSTRINGPROC}
  228. Function fpc_ShortStr_To_AnsiStr (Const S2 : ShortString): ansistring; compilerproc;
  229. {
  230. Converts a ShortString to a AnsiString;
  231. }
  232. Var
  233. Size : SizeInt;
  234. begin
  235. Size:=Length(S2);
  236. Setlength (fpc_ShortStr_To_AnsiStr,Size);
  237. if Size>0 then
  238. Move(S2[1],Pointer(fpc_ShortStr_To_AnsiStr)^,Size);
  239. end;
  240. *)
  241. Function fpc_Char_To_AnsiStr(const c : Char): AnsiString; compilerproc;
  242. {
  243. Converts a Char to a AnsiString;
  244. }
  245. begin
  246. (*
  247. Setlength (fpc_Char_To_AnsiStr,1);
  248. PByte(Pointer(fpc_Char_To_AnsiStr))^:=byte(c);
  249. { Terminating Zero }
  250. PByte(Pointer(fpc_Char_To_AnsiStr)+1)^:=0;
  251. *)
  252. end;
  253. (*
  254. Function fpc_PChar_To_AnsiStr(const p : pchar): ansistring; compilerproc;
  255. Var
  256. L : SizeInt;
  257. begin
  258. if (not assigned(p)) or (p[0]=#0) Then
  259. L := 0
  260. else
  261. l:=IndexChar(p^,-1,#0);
  262. SetLength(fpc_PChar_To_AnsiStr,L);
  263. if L > 0 then
  264. Move (P[0],Pointer(fpc_PChar_To_AnsiStr)^,L)
  265. end;
  266. *)
  267. Function fpc_CharArray_To_AnsiStr(const arr: array of char; zerobased: boolean = true): ansistring; compilerproc;
  268. (*
  269. var
  270. i : SizeInt;
  271. *)
  272. begin
  273. (*
  274. if (zerobased) then
  275. begin
  276. if (arr[0]=#0) Then
  277. i := 0
  278. else
  279. begin
  280. i:=IndexChar(arr,high(arr)+1,#0);
  281. if i = -1 then
  282. i := high(arr)+1;
  283. end;
  284. end
  285. else
  286. i := high(arr)+1;
  287. SetLength(fpc_CharArray_To_AnsiStr,i);
  288. if i > 0 then
  289. Move (arr[0],Pointer(fpc_CharArray_To_AnsiStr)^,i);
  290. *)
  291. end;
  292. procedure fpc_ansistr_to_chararray(out res: array of char; const src: ansistring); compilerproc;
  293. (*
  294. var
  295. len: SizeInt;
  296. *)
  297. begin
  298. (*
  299. len := length(src);
  300. if len > length(res) then
  301. len := length(res);
  302. {$r-}
  303. { make sure we don't try to access element 1 of the ansistring if it's nil }
  304. if len > 0 then
  305. move(src[1],res[0],len);
  306. { fpc_big_chararray is defined as array[0..0], see compproc.inc why }
  307. fillchar(res[len],length(res)-len,0);
  308. {$ifdef RangeCheckWasOn}
  309. {$r+}
  310. {$endif}
  311. *)
  312. end;
  313. function fpc_ansistr_setchar(const s: AnsiString; const index: longint; const ch: ansichar): AnsiString; compilerproc;
  314. begin
  315. end;
  316. Function fpc_AnsiStr_Compare(const S1,S2 : AnsiString): SizeInt; compilerproc;
  317. {
  318. Compares 2 AnsiStrings;
  319. The result is
  320. <0 if S1<S2
  321. 0 if S1=S2
  322. >0 if S1>S2
  323. }
  324. (*
  325. Var
  326. MaxI,Temp : SizeInt;
  327. *)
  328. begin
  329. (*
  330. if pointer(S1)=pointer(S2) then
  331. begin
  332. result:=0;
  333. exit;
  334. end;
  335. Maxi:=Length(S1);
  336. temp:=Length(S2);
  337. If MaxI>Temp then
  338. MaxI:=Temp;
  339. if MaxI>0 then
  340. begin
  341. result:=CompareByte(S1[1],S2[1],MaxI);
  342. if result=0 then
  343. result:=Length(S1)-Length(S2);
  344. end
  345. else
  346. result:=Length(S1)-Length(S2);
  347. *)
  348. end;
  349. Function fpc_AnsiStr_Compare_equal(const S1,S2 : AnsiString): SizeInt; compilerproc;
  350. {
  351. Compares 2 AnsiStrings for equality/inequality only;
  352. The result is
  353. 0 if S1=S2
  354. <>0 if S1<>S2
  355. }
  356. (*
  357. Var
  358. MaxI,Temp : SizeInt;
  359. *)
  360. begin
  361. (*
  362. if pointer(S1)=pointer(S2) then
  363. begin
  364. result:=0;
  365. exit;
  366. end;
  367. Maxi:=Length(S1);
  368. temp:=Length(S2);
  369. Result := Maxi - temp;
  370. if Result = 0 then
  371. if MaxI>0 then
  372. result:=CompareByte(S1[1],S2[1],MaxI);
  373. *)
  374. end;
  375. Procedure fpc_AnsiStr_SetLength (Var S : AnsiString; l : SizeInt); compilerproc;
  376. {
  377. Sets The length of string S to L.
  378. Makes sure S is unique, and contains enough room.
  379. }
  380. (*
  381. Var
  382. Temp : Pointer;
  383. lens, lena,
  384. movelen : SizeInt;
  385. *)
  386. begin
  387. (*
  388. if (l>0) then
  389. begin
  390. if Pointer(S)=nil then
  391. begin
  392. GetMem(Pointer(S),AnsiRecLen+L);
  393. PAnsiRec(S)^.Ref:=1;
  394. inc(Pointer(S),firstoff);
  395. end
  396. else if PAnsiRec(Pointer(S)-FirstOff)^.Ref=1 then
  397. begin
  398. Dec(Pointer(S),FirstOff);
  399. lens:=MemSize(Pointer(s));
  400. lena:=AnsiRecLen+L;
  401. { allow shrinking string if that saves at least half of current size }
  402. if (lena>lens) or ((lens>32) and (lena<=(lens div 2))) then
  403. reallocmem(pointer(S),AnsiRecLen+L);
  404. Inc(Pointer(S),FirstOff);
  405. end
  406. else
  407. begin
  408. { Reallocation is needed... }
  409. Temp:=Pointer(NewAnsiString(L));
  410. { also move terminating null }
  411. lens:=succ(length(s));
  412. if l < lens then
  413. movelen := l
  414. else
  415. movelen := lens;
  416. Move(Pointer(S)^,Temp^,movelen);
  417. { ref count dropped to zero in the mean time? }
  418. If (PAnsiRec(Pointer(S)-FirstOff)^.Ref > 0) and
  419. declocked(PAnsiRec(Pointer(S)-FirstOff)^.Ref) then
  420. freemem(PAnsiRec(Pointer(s)-FirstOff));
  421. Pointer(S):=Temp;
  422. end;
  423. { Force nil termination in case it gets shorter }
  424. PByte(Pointer(S)+l)^:=0;
  425. PAnsiRec(Pointer(S)-FirstOff)^.Len:=l;
  426. end
  427. else
  428. begin
  429. { Length=0 }
  430. if Pointer(S)<>nil then
  431. fpc_ansistr_decr_ref (Pointer(S));
  432. Pointer(S):=Nil;
  433. end;
  434. *)
  435. end;
  436. {*****************************************************************************
  437. Public functions, In interface.
  438. *****************************************************************************}
  439. (*
  440. function fpc_truely_ansistr_unique(Var S : Pointer): Pointer;
  441. Var
  442. SNew : Pointer;
  443. L : SizeInt;
  444. begin
  445. L:=PAnsiRec(Pointer(S)-FirstOff)^.len;
  446. SNew:=NewAnsiString (L);
  447. Move (Pointer(S)^,SNew^,L+1);
  448. PAnsiRec(SNew-FirstOff)^.len:=L;
  449. fpc_ansistr_decr_ref (Pointer(S)); { Thread safe }
  450. pointer(S):=SNew;
  451. pointer(result):=SNew;
  452. end;
  453. *)
  454. {$ifndef FPC_SYSTEM_HAS_ANSISTR_UNIQUE}
  455. // MV: inline the basic checks for case that S is already unique.
  456. // Rest is too complex to inline, so factor that out as a call.
  457. Function fpc_ansistr_Unique(Var S : jlobject): jlobject; compilerproc;
  458. {
  459. Make sure reference count of S is 1,
  460. using copy-on-write semantics.
  461. }
  462. begin
  463. (*
  464. pointer(result) := pointer(s);
  465. If Pointer(S)=Nil then
  466. exit;
  467. if PAnsiRec(Pointer(S)-Firstoff)^.Ref<>1 then
  468. result:=fpc_truely_ansistr_unique(s);
  469. *)
  470. end;
  471. {$endif FPC_SYSTEM_HAS_ANSISTR_UNIQUE}
  472. Procedure fpc_ansistr_append_char(Var S : AnsiString;c : char); compilerproc;
  473. begin
  474. (*
  475. SetLength(S,length(S)+1);
  476. // avoid unique call
  477. PChar(Pointer(S)+length(S)-1)^:=c;
  478. PByte(Pointer(S)+length(S))^:=0; { Terminating Zero }
  479. *)
  480. end;
  481. Procedure fpc_ansistr_append_shortstring(Var S : AnsiString;const Str : ShortString); compilerproc;
  482. (*
  483. var
  484. ofs : SizeInt;
  485. *)
  486. begin
  487. (*
  488. if Str='' then
  489. exit;
  490. ofs:=Length(S);
  491. SetLength(S,ofs+length(Str));
  492. { the pbyte cast avoids an unique call which isn't necessary because SetLength was just called }
  493. move(Str[1],(pointer(S)+ofs)^,length(Str));
  494. PByte(Pointer(S)+length(S))^:=0; { Terminating Zero }
  495. *)
  496. end;
  497. Procedure fpc_ansistr_append_ansistring(Var S : AnsiString;const Str : AnsiString); compilerproc;
  498. (*
  499. var
  500. ofs, strlength: SizeInt;
  501. samestring: boolean;
  502. *)
  503. begin
  504. (*
  505. if Str='' then
  506. exit;
  507. samestring := pointer(s) = pointer(str);
  508. { needed in case s and str are the same string }
  509. strlength := length(str);
  510. ofs:=Length(S);
  511. SetLength(S,ofs+strlength);
  512. { the pbyte cast avoids an unique call which isn't necessary because SetLength was just called }
  513. if not(samestring) then
  514. move(Str[1],(pointer(S)+ofs)^,strlength+1)
  515. else
  516. { the setlength may have relocated the string, so str may no longer be valid }
  517. move(S[1],(pointer(S)+ofs)^,strlength+1)
  518. *)
  519. end;
  520. Function Fpc_Ansistr_Copy (Const S : AnsiString; Index,Size : SizeInt) : AnsiString;compilerproc;
  521. (*
  522. var
  523. ResultAddress : Pointer;
  524. *)
  525. begin
  526. (*
  527. ResultAddress:=Nil;
  528. dec(index);
  529. if Index < 0 then
  530. Index := 0;
  531. { Check Size. Accounts for Zero-length S, the double check is needed because
  532. Size can be maxint and will get <0 when adding index }
  533. if (Size>Length(S)) or
  534. (Index+Size>Length(S)) then
  535. Size:=Length(S)-Index;
  536. If Size>0 then
  537. begin
  538. If Index<0 Then
  539. Index:=0;
  540. ResultAddress:=Pointer(NewAnsiString (Size));
  541. if ResultAddress<>Nil then
  542. begin
  543. Move (Pointer(Pointer(S)+index)^,ResultAddress^,Size);
  544. PAnsiRec(ResultAddress-FirstOff)^.Len:=Size;
  545. PByte(ResultAddress+Size)^:=0;
  546. end;
  547. end;
  548. fpc_ansistr_decr_ref(Pointer(fpc_ansistr_copy));
  549. Pointer(fpc_ansistr_Copy):=ResultAddress;
  550. *)
  551. end;
  552. Function Pos (Const Substr : ShortString; Const Source : AnsiString) : SizeInt;
  553. (*
  554. var
  555. i,MaxLen : SizeInt;
  556. pc : pchar;
  557. *)
  558. begin
  559. (*
  560. Pos:=0;
  561. if Length(SubStr)>0 then
  562. begin
  563. MaxLen:=Length(source)-Length(SubStr);
  564. i:=0;
  565. pc:=@source[1];
  566. while (i<=MaxLen) do
  567. begin
  568. inc(i);
  569. if (SubStr[1]=pc^) and
  570. (CompareByte(Substr[1],pc^,Length(SubStr))=0) then
  571. begin
  572. Pos:=i;
  573. exit;
  574. end;
  575. inc(pc);
  576. end;
  577. end;
  578. *)
  579. end;
  580. Function Pos (Const Substr : AnsiString; Const Source : AnsiString) : SizeInt;
  581. (*
  582. var
  583. i,MaxLen : SizeInt;
  584. pc : pchar;
  585. *)
  586. begin
  587. (*
  588. Pos:=0;
  589. if Length(SubStr)>0 then
  590. begin
  591. MaxLen:=Length(source)-Length(SubStr);
  592. i:=0;
  593. pc:=@source[1];
  594. while (i<=MaxLen) do
  595. begin
  596. inc(i);
  597. if (SubStr[1]=pc^) and
  598. (CompareByte(Substr[1],pc^,Length(SubStr))=0) then
  599. begin
  600. Pos:=i;
  601. exit;
  602. end;
  603. inc(pc);
  604. end;
  605. end;
  606. *)
  607. end;
  608. { Faster version for a char alone. Must be implemented because }
  609. { pos(c: char; const s: shortstring) also exists, so otherwise }
  610. { using pos(char,pchar) will always call the shortstring version }
  611. { (exact match for first argument), also with $h+ (JM) }
  612. Function Pos (c : Char; Const s : AnsiString) : SizeInt;
  613. (*
  614. var
  615. i: SizeInt;
  616. pc : pchar;
  617. *)
  618. begin
  619. (*
  620. pc:=@s[1];
  621. for i:=1 to length(s) do
  622. begin
  623. if pc^=c then
  624. begin
  625. pos:=i;
  626. exit;
  627. end;
  628. inc(pc);
  629. end;
  630. pos:=0;
  631. *)
  632. end;
  633. (*
  634. {$ifndef FPUNONE}
  635. Function fpc_Val_Real_AnsiStr(Const S : AnsiString; out Code : ValSInt): ValReal; [public, alias:'FPC_VAL_REAL_ANSISTR']; compilerproc;
  636. Var
  637. SS : String;
  638. begin
  639. fpc_Val_Real_AnsiStr := 0;
  640. if length(S) > 255 then
  641. code := 256
  642. else
  643. begin
  644. SS := S;
  645. Val(SS,fpc_Val_Real_AnsiStr,code);
  646. end;
  647. end;
  648. {$endif}
  649. Function fpc_Val_Currency_AnsiStr(Const S : AnsiString; out Code : ValSInt): Currency; [public, alias:'FPC_VAL_CURRENCY_ANSISTR']; compilerproc;
  650. Var
  651. SS : String;
  652. begin
  653. if length(S) > 255 then
  654. begin
  655. fpc_Val_Currency_AnsiStr := 0;
  656. code := 256;
  657. end
  658. else
  659. begin
  660. SS := S;
  661. Val(SS,fpc_Val_Currency_AnsiStr,code);
  662. end;
  663. end;
  664. Function fpc_Val_UInt_AnsiStr (Const S : AnsiString; out Code : ValSInt): ValUInt; [public, alias:'FPC_VAL_UINT_ANSISTR']; compilerproc;
  665. Var
  666. SS : ShortString;
  667. begin
  668. fpc_Val_UInt_AnsiStr := 0;
  669. if length(S) > 255 then
  670. code := 256
  671. else
  672. begin
  673. SS := S;
  674. Val(SS,fpc_Val_UInt_AnsiStr,code);
  675. end;
  676. end;
  677. Function fpc_Val_SInt_AnsiStr (DestSize: SizeInt; Const S : AnsiString; out Code : ValSInt): ValSInt; [public, alias:'FPC_VAL_SINT_ANSISTR']; compilerproc;
  678. Var
  679. SS : ShortString;
  680. begin
  681. fpc_Val_SInt_AnsiStr:=0;
  682. if length(S)>255 then
  683. code:=256
  684. else
  685. begin
  686. SS := S;
  687. fpc_Val_SInt_AnsiStr := int_Val_SInt_ShortStr(DestSize,SS,Code);
  688. end;
  689. end;
  690. {$ifndef CPU64}
  691. Function fpc_Val_qword_AnsiStr (Const S : AnsiString; out Code : ValSInt): qword; [public, alias:'FPC_VAL_QWORD_ANSISTR']; compilerproc;
  692. Var
  693. SS : ShortString;
  694. begin
  695. fpc_Val_qword_AnsiStr:=0;
  696. if length(S)>255 then
  697. code:=256
  698. else
  699. begin
  700. SS := S;
  701. Val(SS,fpc_Val_qword_AnsiStr,Code);
  702. end;
  703. end;
  704. Function fpc_Val_int64_AnsiStr (Const S : AnsiString; out Code : ValSInt): Int64; [public, alias:'FPC_VAL_INT64_ANSISTR']; compilerproc;
  705. Var
  706. SS : ShortString;
  707. begin
  708. fpc_Val_int64_AnsiStr:=0;
  709. if length(S)>255 then
  710. code:=256
  711. else
  712. begin
  713. SS := s;
  714. Val(SS,fpc_Val_int64_AnsiStr,Code);
  715. end;
  716. end;
  717. {$endif CPU64}
  718. {$ifndef FPUNONE}
  719. procedure fpc_AnsiStr_Float(d : ValReal;len,fr,rt : SizeInt;out s : ansistring);[public,alias:'FPC_ANSISTR_FLOAT']; compilerproc; {$IFNDEF VER2_0} Inline; {$ENDIF}
  720. var
  721. ss: ShortString;
  722. begin
  723. str_real(len,fr,d,treal_type(rt),ss);
  724. s:=ss;
  725. end;
  726. {$endif}
  727. procedure fpc_ansistr_enum(ordinal,len:sizeint;typinfo,ord2strindex:pointer;out s:ansistring);[public,alias:'FPC_ANSISTR_ENUM'];compilerproc; {$IFNDEF VER2_0} Inline; {$ENDIF}
  728. var ss:shortstring;
  729. begin
  730. fpc_shortstr_enum(ordinal,len,typinfo,ord2strindex,ss);
  731. s:=ss;
  732. end;
  733. procedure fpc_ansistr_bool(b : boolean;len:sizeint;out s:ansistring);[public,alias:'FPC_ANSISTR_BOOL'];compilerproc; {$IFNDEF VER2_0} Inline; {$ENDIF}
  734. var
  735. ss:shortstring;
  736. begin
  737. fpc_shortstr_bool(b,len,ss);
  738. s:=ss;
  739. end;
  740. function fpc_val_enum_ansistr(str2ordindex:pointer;const s:ansistring;out code:valsint):longint; [public, alias:'FPC_VAL_ENUM_ANSISTR']; compilerproc;
  741. begin
  742. fpc_val_enum_ansistr:=fpc_val_enum_shortstr(str2ordindex,s,code);
  743. end;
  744. {$ifdef FPC_HAS_STR_CURRENCY}
  745. procedure fpc_AnsiStr_Currency(c : currency;len,fr : SizeInt;out s : ansistring);[public,alias:'FPC_ANSISTR_CURRENCY']; compilerproc; {$IFNDEF VER2_0} Inline; {$ENDIF}
  746. var
  747. ss: ShortString;
  748. begin
  749. str(c:len:fr,ss);
  750. s:=ss;
  751. end;
  752. {$endif FPC_HAS_STR_CURRENCY}
  753. Procedure fpc_AnsiStr_UInt(v : ValUInt;Len : SizeInt; out S : AnsiString);[Public,Alias : 'FPC_ANSISTR_VALUINT']; compilerproc; {$IFNDEF VER2_0} Inline; {$ENDIF}
  754. Var
  755. SS : ShortString;
  756. begin
  757. str(v:Len,SS);
  758. S:=SS;
  759. end;
  760. Procedure fpc_AnsiStr_SInt(v : ValSInt;Len : SizeInt; out S : AnsiString);[Public,Alias : 'FPC_ANSISTR_VALSINT']; compilerproc; {$IFNDEF VER2_0} Inline; {$ENDIF}
  761. Var
  762. SS : ShortString;
  763. begin
  764. str (v:Len,SS);
  765. S:=SS;
  766. end;
  767. {$ifndef CPU64}
  768. Procedure fpc_AnsiStr_QWord(v : QWord;Len : SizeInt; out S : AnsiString);[Public,Alias : 'FPC_ANSISTR_QWORD']; compilerproc; {$IFNDEF VER2_0} Inline; {$ENDIF}
  769. Var
  770. SS : ShortString;
  771. begin
  772. str(v:Len,SS);
  773. S:=SS;
  774. end;
  775. Procedure fpc_AnsiStr_Int64(v : Int64; Len : SizeInt; out S : AnsiString);[Public,Alias : 'FPC_ANSISTR_INT64']; compilerproc; {$IFNDEF VER2_0} Inline; {$ENDIF}
  776. Var
  777. SS : ShortString;
  778. begin
  779. str (v:Len,SS);
  780. S:=SS;
  781. end;
  782. {$endif CPU64}
  783. Procedure Delete (Var S : AnsiString; Index,Size: SizeInt);
  784. Var
  785. LS : SizeInt;
  786. begin
  787. ls:=Length(S);
  788. If (Index>LS) or (Index<=0) or (Size<=0) then
  789. exit;
  790. UniqueString (S);
  791. If (Size>LS-Index) then // Size+Index gives overflow ??
  792. Size:=LS-Index+1;
  793. If (Size<=LS-Index) then
  794. begin
  795. Dec(Index);
  796. Move(PByte(Pointer(S))[Index+Size],PByte(Pointer(S))[Index],LS-Index-Size+1);
  797. end;
  798. Setlength(S,LS-Size);
  799. end;
  800. Procedure Insert (Const Source : AnsiString; Var S : AnsiString; Index : SizeInt);
  801. var
  802. Temp : AnsiString;
  803. LS : SizeInt;
  804. begin
  805. If Length(Source)=0 then
  806. exit;
  807. if index <= 0 then
  808. index := 1;
  809. Ls:=Length(S);
  810. if index > LS then
  811. index := LS+1;
  812. Dec(Index);
  813. Pointer(Temp) := NewAnsiString(Length(Source)+LS);
  814. SetLength(Temp,Length(Source)+LS);
  815. If Index>0 then
  816. move (Pointer(S)^,Pointer(Temp)^,Index);
  817. Move (Pointer(Source)^,PByte(Temp)[Index],Length(Source));
  818. If (LS-Index)>0 then
  819. Move(PByte(Pointer(S))[Index],PByte(temp)[Length(Source)+index],LS-Index);
  820. S:=Temp;
  821. end;
  822. Function StringOfChar(c : char;l : SizeInt) : AnsiString;
  823. begin
  824. SetLength(StringOfChar,l);
  825. FillChar(Pointer(StringOfChar)^,Length(StringOfChar),c);
  826. end;
  827. Procedure SetString (Out S : AnsiString; Buf : PChar; Len : SizeInt); {$IFNDEF VER2_0} Inline; {$ENDIF}
  828. begin
  829. SetLength(S,Len);
  830. If (Buf<>Nil) then
  831. Move (Buf^,Pointer(S)^,Len);
  832. end;
  833. Procedure SetString (Out S : AnsiString; Buf : PWideChar; Len : SizeInt);
  834. begin
  835. if (Buf<>nil) and (Len>0) then
  836. widestringmanager.Wide2AnsiMoveProc(Buf,S,Len)
  837. else
  838. SetLength(S, Len);
  839. end;
  840. *)
  841. function upcase(const s : ansistring) : ansistring;
  842. (*
  843. var
  844. i : SizeInt;
  845. *)
  846. begin
  847. (*
  848. Setlength(result,length(s));
  849. for i := 1 to length (s) do
  850. result[i] := upcase(s[i]);
  851. *)
  852. end;
  853. function lowercase(const s : ansistring) : ansistring;
  854. (*
  855. var
  856. i : SizeInt;
  857. *)
  858. begin
  859. (*
  860. Setlength(result,length(s));
  861. for i := 1 to length (s) do
  862. result[i] := lowercase(s[i]);
  863. *)
  864. end;