astrings.pp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1993,97 by Michael Van Canneyt,
  5. member of the Free Pascal development team.
  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. { ---------------------------------------------------------------------
  13. This units implements AnsiStrings for FPC
  14. ---------------------------------------------------------------------}
  15. {
  16. This file contains the implementation of the LongString type,
  17. and all things that are needed for it.
  18. AnsiSTring is defined as a 'silent' pchar :
  19. a pchar that points to :
  20. @-12 : Longint for maximum size;
  21. @-8 : Longint for size;
  22. @-4 : Longint for reference count;
  23. @ : String + Terminating #0;
  24. Pchar(Ansistring) is a valid typecast.
  25. So AS[i] is converted to the address @AS+i-1.
  26. Constants should be assigned a reference count of -1
  27. Meaning that they can't be disposed of.
  28. }
  29. {$ifdef astrings_unit}
  30. { Compile as a separate unit - development only}
  31. unit astrings;
  32. Interface
  33. Type AnsiString = Pointer;
  34. ShortString = string;
  35. {$i textrec.inc}
  36. { Internal functions, will not appear in systemh.inc }
  37. Function NewAnsiString (Len : Longint) : AnsiString;
  38. Procedure DisposeAnsiString (Var S : AnsiString);
  39. Procedure Decr_Ansi_Ref (Var S : AnsiString);
  40. Procedure Incr_Ansi_Ref (Var S : AnsiString);
  41. Procedure AssignAnsiString (Var S1 : AnsiString; S2 : AnsiString);
  42. Procedure Ansi_String_Concat (Var S1 : AnsiString; Const S2 : AnsiString);
  43. Procedure Ansi_ShortString_Concat (Var S1: AnsiString; Const S2 : ShortString);
  44. Procedure Ansi_To_ShortString (Var S1 : ShortString; Const S2 : AnsiString; maxlen : longint);
  45. Procedure Short_To_AnsiString (Var S1 : AnsiString; Const S2 : ShortString);
  46. Function AnsiCompare (Const S1,S2 : AnsiString): Longint;
  47. Function AnsiCompare (Const S1 : AnsiString; Const S2 : ShortString): Longint;
  48. Procedure SetCharAtIndex (Var S : AnsiString; Index : Longint; C : CHar);
  49. { Public functions, Will end up in systemh.inc }
  50. Procedure SetLength (Var S : AnsiString; l : Longint);
  51. Procedure UniqueAnsiString (Var S : AnsiString);
  52. Procedure Write_Text_AnsiString (Len : Longint; T : Textrec; Var S : AnsiString);
  53. Function Length (Const S : AnsiString) : Longint;
  54. Function Copy (Const S : AnsiString; Index,Size : Longint) : AnsiString;
  55. Function Pos (Const Substr : AnsiString; Const Source : AnsiString) : Longint;
  56. Procedure Insert (Const Source : AnsiString; Var S : AnsiString; Index : Longint);
  57. Procedure Delete (Var S : AnsiString; Index,Size: Longint);
  58. Procedure Val (Const S : AnsiString; var R : real; Var Code : Integer);
  59. {Procedure Val (Const S : AnsiString; var D : Double; Var Code : Integer);}
  60. Procedure Val (Const S : AnsiString; var E : Extended; Code : Integer);
  61. Procedure Val (Const S : AnsiString; var C : Cardinal; Code : Integer);
  62. Procedure Val (Const S : AnsiString; var L : Longint; Var Code : Integer);
  63. Procedure Val (Const S : AnsiString; var W : Word; Var Code : Integer);
  64. Procedure Val (Const S : AnsiString; var I : Integer; Var Code : Integer);
  65. Procedure Val (Const S : AnsiString; var B : Byte; Var Code : Integer);
  66. Procedure Val (Const S : AnsiString; var SI : ShortInt; Var Code : Integer);
  67. Procedure Str (Const R : Real;Len, fr : longint; Var S : AnsiString);
  68. {Procedure Str (Const D : Double;Len,fr : longint; Var S : AnsiString);}
  69. Procedure Str (Const E : Extended;Len,fr : longint; Var S : AnsiString);
  70. Procedure Str (Const C : Cardinal;len : Longint; Var S : AnsiString);
  71. Procedure Str (Const L : LongInt;len : longint; Var S : AnsiString);
  72. Procedure Str (Const W : Word;len : longint; Var S : AnsiString);
  73. Procedure Str (Const I : Integer;len : Longint; Var S : AnsiString);
  74. Procedure Str (Const B : Byte; Len : longint; Var S : AnsiString);
  75. Procedure Str (Const SI : ShortInt; Len : longint; Var S : AnsiString);
  76. Implementation
  77. {$endif}
  78. {$PACKRECORDS 1}
  79. Type TAnsiRec = Record
  80. Maxlen, len, ref : Longint;
  81. First : Char;
  82. end;
  83. PAnsiRec = ^TAnsiRec;
  84. PLongint = ^Longint;
  85. PByte = ^Byte;
  86. Const AnsiRecLen = SizeOf(TAnsiRec);
  87. FirstOff = SizeOf(TAnsiRec)-1;
  88. { ---------------------------------------------------------------------
  89. Internal functions, not in interface.
  90. ---------------------------------------------------------------------}
  91. Procedure DumpAnsiRec ( S : Ansistring);
  92. begin
  93. If Pointer(S)=Nil then
  94. Writeln ('String is nil')
  95. Else
  96. Begin
  97. Dec (Longint(S),FirstOff);
  98. With PansiRec(S)^ do
  99. begin
  100. Writeln ('MAxlen : ',maxlen);
  101. Writeln ('Len : ',len);
  102. Writeln ('Ref : ',ref);
  103. end;
  104. end;
  105. end;
  106. Function NewAnsiString (Len : Longint) : AnsiString;
  107. {
  108. Allocate a new AnsiString on the heap.
  109. initialize it to zero length and reference count 1.
  110. }
  111. Var P : Pointer;
  112. begin
  113. GetMem(P,Len+AnsiRecLen);
  114. If P<>Nil then
  115. begin
  116. PAnsiRec(P)^.Maxlen:=Len; { Maximal length }
  117. PAnsiRec(P)^.Len:=0; { Initial length }
  118. PAnsiRec(P)^.Ref:=1; { Set reference count }
  119. PAnsiRec(P)^.First:=#0; { Terminating #0 }
  120. P:=P+FirstOff; { Points to string now }
  121. end;
  122. NewAnsiString:=P;
  123. end;
  124. Procedure Decr_Ansi_Ref (Var S : AnsiString);
  125. {
  126. Decreases the ReferenceCount of a non constant ansistring;
  127. If the reference count is zero, deallocate the string;
  128. }
  129. Begin
  130. If Pointer(S)=Nil then exit; { Zero string }
  131. { check for constant strings ...}
  132. If PansiRec(Pointer(S)-FirstOff)^.Ref<0 then exit;
  133. Dec(PAnsiRec(Pointer(S)-FirstOff)^.Ref);
  134. If PAnsiRec(Pointer(S)-FirstOff)^.Ref=0 then
  135. { Ref count dropped to zero }
  136. DisposeAnsiString (S); { Remove...}
  137. end;
  138. Procedure Incr_Ansi_Ref (Var S : AnsiString);
  139. Begin
  140. If Pointer(S)=Nil then exit;
  141. { Let's be paranoid : Constant string ??}
  142. If PansiRec(Pointer(S)-FirstOff)^.Ref<0 then exit;
  143. inc(PAnsiRec(Pointer(S)-FirstOff)^.Ref);
  144. end;
  145. Procedure UniqueAnsiString (Var S : AnsiString);
  146. {
  147. Make sure reference count of S is 1,
  148. using copy-on-write semantics.
  149. }
  150. Var SNew : Pointer;
  151. begin
  152. If Pointer(S)=Nil then exit;
  153. if PAnsiRec(Pointer(S)-Firstoff)^.Ref>1 then
  154. begin
  155. SNew:=Pointer(NewAnsiString (PAnsiRec(Pointer(S)-FirstOff)^.len));
  156. Move (Pointer(S)^,SNew^,PAnsiRec(Pointer(S)-FirstOff)^.len+1);
  157. PAnsiRec(SNew-8)^.len:=PAnsiRec(Pchar(S)-FirstOff)^.len;
  158. Decr_Ansi_Ref (S); { Thread safe }
  159. Pchar(S):=Pchar(SNew);
  160. end;
  161. end;
  162. Procedure DisposeAnsiString (Var S : AnsiString);
  163. {
  164. Deallocates a AnsiString From the heap.
  165. }
  166. begin
  167. If Pointer(S)=Nil then exit;
  168. Dec (Longint(S),FirstOff);
  169. FreeMem (S,PAnsiRec(Pointer(S))^.Maxlen+AnsiRecLen);
  170. Pointer(S):=Nil;
  171. end;
  172. Procedure AssignAnsiString (Var S1 : AnsiString; S2 : AnsiString);
  173. {
  174. Assigns S2 to S1 (S1:=S2), taking in account reference counts.
  175. If S2 is a constant string, a new S1 is allocated on the heap.
  176. }
  177. Var Temp : Pointer;
  178. begin
  179. If Pointer(S2)<>nil then
  180. begin
  181. If PAnsiRec(Pointer(S2)-FirstOff)^.Ref<0 then
  182. begin
  183. { S2 is a constant string, Create new string with copy. }
  184. Temp:=Pointer(NewAnsiString(PansiRec(Pointer(S2)-FirstOff)^.Len));
  185. Move (Pointer(S2)^,Temp^,PAnsiRec(Pointer(S2)-FirstOff)^.len+1);
  186. PAnsiRec(Temp-FirstOff)^.Len:=PAnsiRec(Pointer(S2)-FirstOff)^.len;
  187. S2:=Temp;
  188. end
  189. else
  190. Inc(PAnsiRec(Pointer(S2)-FirstOff)^.ref)
  191. end;
  192. { Decrease the reference count on the old S1 }
  193. Decr_Ansi_Ref (S1);
  194. { And finally, have S1 pointing to S2 (or its copy) }
  195. Pointer(S1):=Pointer(S2);
  196. end;
  197. Procedure Ansi_String_Concat (Var S1 : AnsiString; Const S2 : AnsiString);
  198. {
  199. Concatenates 2 AnsiStrings : S1+S2.
  200. Result Goes to S1;
  201. }
  202. Var Size,Location : Longint;
  203. begin
  204. if Pointer(S2)=Nil then exit;
  205. if (Pointer(S1)=Nil) then
  206. AssignAnsiString(S1,S2)
  207. else
  208. begin
  209. Size:=PAnsiRec(Pointer(S2)-FirstOff)^.Len;
  210. Location:=Length(S1);
  211. { Setlength takes case of uniqueness
  212. and alllocated memory. We need to use length,
  213. to take into account possibility of S1=Nil }
  214. SetLength (S1,Size+Location);
  215. Move (Pointer(S2)^,Pointer(Pointer(S1)+location)^,Size+1);
  216. end;
  217. end;
  218. Procedure Ansi_ShortString_Concat (Var S1: AnsiString; Const S2 : ShortString);
  219. {
  220. Concatenates a Ansi with a short string; : S2 + S2
  221. }
  222. Var Size,Location : Longint;
  223. begin
  224. Size:=byte(S2[0]);
  225. Location:=Length(S1);
  226. If Size=0 then exit;
  227. { Setlength takes case of uniqueness
  228. and alllocated memory. We need to use length,
  229. to take into account possibility of S1=Nil }
  230. SetLength (S1,Size+Length(S1));
  231. Move (S2[1],Pointer(Pointer(S1)+Location)^,Size);
  232. PByte( Pointer(S1)+length(S1) )^:=0; { Terminating Zero }
  233. end;
  234. Procedure Ansi_To_ShortString (Var S1 : ShortString; Const S2 : AnsiString; Maxlen : Longint);
  235. {
  236. Converts a AnsiString to a ShortString;
  237. if maxlen<>-1, the resulting string has maximal length maxlen
  238. else a default length of 255 is taken.
  239. }
  240. Var Size : Longint;
  241. begin
  242. Size:=PAnsiRec(Pointer(S2)-FirstOff)^.Len;
  243. if maxlen=-1 then maxlen:=255;
  244. If Size>maxlen then Size:=maxlen;
  245. Move (Pointer(S2)^,S1[1],Size);
  246. byte(S1[0]):=Size;
  247. end;
  248. Procedure Short_To_AnsiString (Var S1 : AnsiString; Const S2 : ShortString);
  249. {
  250. Converts a ShortString to a AnsiString;
  251. }
  252. Var Size : Longint;
  253. begin
  254. Size:=Byte(S2[0]);
  255. Setlength (S1,Size);
  256. Move (S2[1],Pointer(S1)^,Size);
  257. PByte(Pointer(S1)+Size)^:=0; { Terminating Zero }
  258. end;
  259. Function AnsiCompare (Const S1,S2 : AnsiString): Longint;
  260. {
  261. Compares 2 AnsiStrings;
  262. The result is
  263. <0 if S1<S2
  264. 0 if S1=S2
  265. >0 if S1>S2
  266. }
  267. Var i,MaxI,Temp : Longint;
  268. begin
  269. Temp:=0;
  270. i:=0;
  271. MaxI:=Length(S1);
  272. if MaxI>Length(S2) then MaxI:=Length(S2);
  273. While (i<MaxI) and (Temp=0) do
  274. begin
  275. Temp:= PByte(Pointer(S1)+I)^ - PByte(Pointer(S2)+i)^;
  276. inc(i);
  277. end;
  278. if temp=0 then temp:=Length(S1)-Length(S2);
  279. AnsiCompare:=Temp;
  280. end;
  281. Function AnsiCompare (Const S1 : AnsiString; Const S2 : ShortString): Longint;
  282. {
  283. Compares a AnsiString with a ShortString;
  284. The result is
  285. <0 if S1<S2
  286. 0 if S1=S2
  287. >0 if S1>S2
  288. }
  289. Var i,MaxI,Temp : Longint;
  290. begin
  291. Temp:=0;
  292. i:=0;
  293. MaxI:=Length(S1);
  294. if MaxI>byte(S2[0]) then MaxI:=Byte(S2[0]);
  295. While (i<MaxI) and (Temp=0) do
  296. begin
  297. Temp:= PByte(Pointer(S1)+I)^ - Byte(S2[i+1]);
  298. inc(i);
  299. end;
  300. AnsiCompare:=Temp;
  301. end;
  302. Procedure Write_Text_AnsiString (Len : Longint; T : TextRec; Var S : AnsiString);
  303. {
  304. Writes a AnsiString to the Text file T
  305. }
  306. begin
  307. end;
  308. Procedure SetCharAtIndex (Var S : AnsiString; Index : Longint; C : CHar);
  309. begin
  310. if Index<=Length(S) then
  311. begin
  312. UniqueAnsiString(S);
  313. Pbyte(Pointer(S)+index-1)^:=Byte(C);
  314. end;
  315. end;
  316. { ---------------------------------------------------------------------
  317. Public functions, In interface.
  318. ---------------------------------------------------------------------}
  319. Function Length (Const S : AnsiString) : Longint;
  320. {
  321. Returns the length of an AnsiString.
  322. Takes in acount that zero strings are NIL;
  323. }
  324. begin
  325. If Pointer(S)=Nil then
  326. Length:=0
  327. else
  328. Length:=PAnsiRec(Pointer(S)-FirstOff)^.Len;
  329. end;
  330. Procedure SetLength (Var S : AnsiString; l : Longint);
  331. {
  332. Sets The length of string S to L.
  333. Makes sure S is unique, and contains enough room.
  334. }
  335. Var Temp : Pointer;
  336. begin
  337. If (S=Nil) and (l>0) then
  338. begin
  339. { Need a complete new string...}
  340. S:=NewAnsiString(l);
  341. PAnsiRec(Pointer(S)-FirstOff)^.Len:=l;
  342. PAnsiRec(Pointer(S)-FirstOff)^.Len:=l;
  343. PByte (Pointer(S)+l)^:=0;
  344. end
  345. else if l>0 then
  346. begin
  347. If (PAnsiRec(Pointer(S)-FirstOff)^.Maxlen < L) or
  348. (PAnsiRec(Pointer(S)-FirstOff)^.Ref <> 1) then
  349. begin
  350. { Reallocation is needed... }
  351. Temp:=Pointer(NewAnsiString(L));
  352. if Length(S)>0 then
  353. Move (S^,Temp^,Length(S)+1);
  354. Decr_Ansi_ref (S);
  355. S:=Temp;
  356. end;
  357. PAnsiRec(Pointer(S)-FirstOff)^.Len:=l
  358. end
  359. else
  360. { Length=0 }
  361. begin
  362. Decr_Ansi_Ref (S);
  363. S:=Nil;
  364. end;
  365. end;
  366. Function Copy (Const S : AnsiString; Index,Size : Longint) : AnsiString;
  367. var ResultAddress : Pointer;
  368. begin
  369. ResultAddress:=Nil;
  370. dec(index);
  371. { Check Size. Accounts for Zero-length S }
  372. if Length(S)<Index+Size then
  373. Size:=Length(S)-Index;
  374. If Size>0 then
  375. begin
  376. ResultAddress:=Pointer(NewAnsiString (Size));
  377. if ResultAddress<>Nil then
  378. begin
  379. Move (Pointer(Pointer(S)+index)^,ResultAddress^,Size);
  380. PAnsiRec(ResultAddress-FirstOff)^.Len:=Size;
  381. PByte(ResultAddress+Size)^:=0;
  382. end;
  383. end;
  384. Copy:=ResultAddress
  385. end;
  386. Function Pos (Const Substr : AnsiString; Const Source : AnsiString) : Longint;
  387. var i,j : longint;
  388. e : boolean;
  389. s : Pointer;
  390. begin
  391. i := 0;
  392. j := 0;
  393. e := true;
  394. if Plongint(substr)^=0 then e := false;
  395. while (e) and (i <= length (Source) - length (substr)) do
  396. begin
  397. inc (i);
  398. S:=Pointer(copy(Source,i,length(Substr)));
  399. if AnsiCompare(substr,s)=0 then
  400. begin
  401. j := i;
  402. e := false;
  403. end;
  404. DisposeAnsiString(AnsiString(S));
  405. end;
  406. pos := j;
  407. end;
  408. Procedure Val (Const S : AnsiString; var R : real; Var Code : Integer);
  409. Var SS : String;
  410. begin
  411. Ansi_To_ShortString (SS,S,255);
  412. System.Val(SS,R,Code);
  413. end;
  414. {
  415. Procedure Val (Const S : AnsiString; var D : Double; Var Code : Integer);
  416. Var SS : ShortString;
  417. begin
  418. Ansi_To_ShortString (SS,S,255);
  419. Val(SS,D,Code);
  420. end;
  421. }
  422. Procedure Val (Const S : AnsiString; var E : Extended; Code : Integer);
  423. Var SS : ShortString;
  424. begin
  425. Ansi_To_ShortString (SS,S,255);
  426. System.Val(SS,E,Code);
  427. end;
  428. Procedure Val (Const S : AnsiString; var C : Cardinal; Code : Integer);
  429. Var SS : ShortString;
  430. begin
  431. Ansi_To_ShortString (SS,S,255);
  432. System.Val(SS,C,Code);
  433. end;
  434. Procedure Val (Const S : AnsiString; var L : Longint; Var Code : Integer);
  435. Var SS : ShortString;
  436. begin
  437. Ansi_To_ShortString (SS,S,255);
  438. System.Val(SS,L,Code);
  439. end;
  440. Procedure Val (Const S : AnsiString; var W : Word; Var Code : Integer);
  441. Var SS : ShortString;
  442. begin
  443. Ansi_To_ShortString (SS,S,255);
  444. System.Val(SS,W,Code);
  445. end;
  446. Procedure Val (Const S : AnsiString; var I : Integer; Var Code : Integer);
  447. Var SS : ShortString;
  448. begin
  449. Ansi_To_ShortString (SS,S,255);
  450. System.Val(SS,I,Code);
  451. end;
  452. Procedure Val (Const S : AnsiString; var B : Byte; Var Code : Integer);
  453. Var SS : ShortString;
  454. begin
  455. Ansi_To_ShortString (SS,S,255);
  456. System.Val(SS,B,Code);
  457. end;
  458. Procedure Val (Const S : AnsiString; var SI : ShortInt; Var Code : Integer);
  459. Var SS : ShortString;
  460. begin
  461. Ansi_To_ShortString (SS,S,255);
  462. System.Val(SS,SI,Code);
  463. end;
  464. Procedure Str (Const R : Real;Len,fr : Longint; Var S : AnsiString);
  465. Var SS : ShortString;
  466. begin
  467. {int_Str_Real (R,Len,fr,SS);}
  468. Short_To_AnsiString (S,SS);
  469. end;
  470. {
  471. Procedure Str (Const D : Double;Len,fr: Longint; Var S : AnsiString);
  472. Var SS : ShortString;
  473. begin
  474. {int_Str_Double (D,Len,fr,SS);}
  475. Short_To_AnsiString (S,SS);
  476. end;
  477. }
  478. Procedure Str (Const E : Extended;Lenf,Fr: Longint; Var S : AnsiString);
  479. Var SS : ShortString;
  480. begin
  481. {int_Str_Extended (E,Len,fr,SS);}
  482. Short_To_AnsiString (S,SS);
  483. end;
  484. Procedure Str (Const C : Cardinal;Len : Longint; Var S : AnsiString);
  485. begin
  486. end;
  487. Procedure Str (Const L : Longint; Len : Longint; Var S : AnsiString);
  488. Var SS : ShortString;
  489. begin
  490. {int_Str_Longint (L,Len,fr,SS);}
  491. Short_To_AnsiString (S,SS);
  492. end;
  493. Procedure Str (Const W : Word;Len : Longint; Var S : AnsiString);
  494. begin
  495. end;
  496. Procedure Str (Const I : Integer;Len : Longint; Var S : AnsiString);
  497. begin
  498. end;
  499. Procedure Str (Const B : Byte; Len : Longint; Var S : AnsiString);
  500. begin
  501. end;
  502. Procedure Str (Const SI : ShortInt; Len : Longint; Var S : AnsiString);
  503. begin
  504. end;
  505. Procedure Delete (Var S : AnsiString; Index,Size: Longint);
  506. begin
  507. if index<=0 then
  508. begin
  509. Size:=Size+index-1;
  510. index:=1;
  511. end;
  512. if (Index<=length(s)) and (Size>0) then
  513. begin
  514. UniqueAnsiString (S);
  515. if Size+Index>Length(S) then
  516. Size:=Length(s)-Index+1;
  517. Setlength(s,Length(s)-Size);
  518. if Index<=Length(s) then
  519. Move(Pointer(Pointer(S)+Index+Size-1)^,
  520. Pointer(Pointer(s)+Index-1)^,Length(s)-Index+2)
  521. else
  522. Pbyte(Pointer(S)+Length(S))^:=0;
  523. end;
  524. end;
  525. Procedure Insert (Const Source : AnsiString; Var S : AnsiString; Index : Longint);
  526. var s3,s4 : Pointer;
  527. begin
  528. If Length(Source)=0 then exit;
  529. if index <= 0 then index := 1;
  530. s3 := Pointer(copy(s,index,length(s)));
  531. if index > Length(s) then
  532. index := Length(S)+1;
  533. SetLength(s,index - 1);
  534. s4 := Pointer ( NewAnsiString(PansiRec(Pointer(Source)-Firstoff)^.len) );
  535. Ansi_String_Concat(AnsiString(s4),Source);
  536. if S4<>Nil then
  537. Ansi_String_Concat(AnsiString(S4),AnsiString(s3));
  538. Ansi_String_Concat(S,AnsiString(S4));
  539. Decr_ansi_ref (AnsiString(S3));
  540. Decr_ansi_ref (AnsiString(S4));
  541. end;
  542. {$ifdef astrings_unit}
  543. end.
  544. {$endif}
  545. {
  546. $Log$
  547. Revision 1.2 1998-05-12 10:42:44 peter
  548. * moved getopts to inc/, all supported OS's need argc,argv exported
  549. + strpas, strlen are now exported in the systemunit
  550. * removed logs
  551. * removed $ifdef ver_above
  552. }