stringl.inc 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962
  1. {
  2. $Id$
  3. This file is part of the Free Component Library (FCL)
  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. {* TStrings *}
  13. {****************************************************************************}
  14. // Function to quote text. Should move maybe to sysutils !!
  15. // Also, it is not clear at this point what exactly should be done.
  16. { //!! is used to mark unsupported things. }
  17. Function QuoteString (Const S : String; Quote : String) : String;
  18. Var I,J : Longint;
  19. begin
  20. I:=0;
  21. J:=0;
  22. Result:=S;
  23. While I<Length(S) do
  24. begin
  25. I:=I+1;
  26. J:=J+1;
  27. if S[i]=Quote then
  28. begin
  29. System.Insert(Result,Quote,J);
  30. J:=J+1;
  31. end;
  32. end;
  33. Result:=Quote+Result+Quote;
  34. end;
  35. function TStrings.GetCommaText: string;
  36. Var I : Longint;
  37. begin
  38. result:='';
  39. For i:=0 to count-1 do
  40. begin
  41. Result:=Result+QuoteString (Strings[I],'"');
  42. if I<Count-1 then Result:=Result+',';
  43. end;
  44. If Length(Result)=0 then Result:='""';
  45. end;
  46. function TStrings.GetName(Index: Integer): string;
  47. Var L : longint;
  48. begin
  49. Result:=Strings[Index];
  50. L:=Pos('=',Result);
  51. If L<>0 then
  52. Result:=Copy(Result,1,L-1)
  53. else
  54. Result:='';
  55. end;
  56. Function TStrings.GetValue(const Name: string): string;
  57. Var L : longint;
  58. begin
  59. Result:='';
  60. L:=IndexOfName(Name);
  61. If L<>-1 then
  62. begin
  63. Result:=Strings[L];
  64. L:=Pos('=',Result);
  65. System.Delete (Result,1,L);
  66. end;
  67. end;
  68. Procedure TStrings.ReadData(Reader: TReader);
  69. begin
  70. end;
  71. Function GetQuotedString (Var P : Pchar) : AnsiString;
  72. Var P1,L : Pchar;
  73. begin
  74. Result:='';
  75. P1:=P+1;
  76. While P1^<>#0 do
  77. begin
  78. If (P1^='"') and (P1[1]<>'"') then
  79. break;
  80. P1:=P1+1;
  81. If P1^='"' then P1:=P1+1;
  82. end;
  83. // P1 points to last quote, or to #0;
  84. P:=P+1;
  85. If P1-P>0 then
  86. begin
  87. SetLength(Result,(P1-P));
  88. L:=Pointer(Result);
  89. Move (P^,L^,P1-P);
  90. P:=P1+1;
  91. end;
  92. end;
  93. Function GetNextQuotedChar (P : PChar; Var S : String): Boolean;
  94. Var PS,L : PChar;
  95. begin
  96. Result:=False;
  97. If P^=#0 then exit;
  98. S:='';
  99. While (p^<>#0) and (byte(p^)<=byte(' ')) do P:=P+1;
  100. PS:=P;
  101. If P^='"' then
  102. S:=GetQuotedString(P)
  103. else
  104. begin
  105. While (p^>' ') and (P^<>',') do P:=P+1;
  106. Setlength (S,P-PS);
  107. L:=Pointer(S);
  108. Move (PS^,L,P-PS);
  109. end;
  110. Result:=True;
  111. end;
  112. Procedure TStrings.SetCommaText(const Value: string);
  113. Var P : Pointer;
  114. S : String;
  115. begin
  116. Self.Clear;
  117. P:=Pointer(Value);
  118. While GetNextQuotedChar (P,S) do Add (S);
  119. end;
  120. Procedure TStrings.SetStringsAdapter(const Value: IStringsAdapter);
  121. begin
  122. end;
  123. Procedure TStrings.SetValue(const Name, Value: string);
  124. Var L : longint;
  125. begin
  126. L:=IndexOfName(Name);
  127. if L=-1 then
  128. Add (Name+'='+Value)
  129. else
  130. Strings[L]:=Name+'='+value;
  131. end;
  132. Procedure TStrings.WriteData(Writer: TWriter);
  133. begin
  134. end;
  135. Procedure TStrings.DefineProperties(Filer: TFiler);
  136. begin
  137. end;
  138. Procedure TStrings.Error(const Msg: string; Data: Integer);
  139. begin
  140. //!! Need to get correct address !!
  141. Raise EStringListError.CreateFmt(Msg,[Data]);
  142. end;
  143. Function TStrings.GetCapacity: Integer;
  144. begin
  145. Result:=Count;
  146. end;
  147. Function TStrings.GetObject(Index: Integer): TObject;
  148. begin
  149. Result:=Nil;
  150. end;
  151. Function TStrings.GetTextStr: string;
  152. Const
  153. {$ifdef linux}
  154. NewLineSize=1;
  155. {$else}
  156. NewLineSize=2;
  157. {$endif}
  158. Var P : Pchar;
  159. I,L : Longint;
  160. S : String;
  161. begin
  162. // Determine needed place
  163. L:=0;
  164. For I:=0 to count-1 do
  165. L:=L+Length(Strings[I])+NewLineSize;
  166. Setlength(Result,L);
  167. P:=Pointer(Result);
  168. For i:=0 To count-1 do
  169. begin
  170. S:=Strings[I];
  171. L:=Length(S);
  172. if L<>0 then
  173. System.Move(Pointer(S)^,P^,L);
  174. P:=P+L;
  175. {$ifndef linux}
  176. p[0]:=#13;
  177. p[1]:=#10;
  178. {$else}
  179. p[0]:=#10;
  180. {$endif}
  181. P:=P+NewLineSize;
  182. end;
  183. end;
  184. Procedure TStrings.Put(Index: Integer; const S: string);
  185. Var Obj : TObject;
  186. begin
  187. Obj:=Objects[Index];
  188. Delete(Index);
  189. InsertObject(Index,S,Obj);
  190. end;
  191. Procedure TStrings.PutObject(Index: Integer; AObject: TObject);
  192. begin
  193. // Empty.
  194. end;
  195. Procedure TStrings.SetCapacity(NewCapacity: Integer);
  196. begin
  197. // Empty.
  198. end;
  199. Procedure TStrings.SetTextStr(const Value: string);
  200. begin
  201. SetText(PChar(Value));
  202. end;
  203. Procedure TStrings.SetUpdateState(Updating: Boolean);
  204. begin
  205. end;
  206. destructor TSTrings.Destroy;
  207. begin
  208. inherited destroy;
  209. end;
  210. Function TStrings.Add(const S: string): Integer;
  211. begin
  212. Result:=Count;
  213. Insert (Count,S);
  214. end;
  215. Function TStrings.AddObject(const S: string; AObject: TObject): Integer;
  216. begin
  217. Result:=Add(S);
  218. Objects[result]:=AObject;
  219. end;
  220. Procedure TStrings.Append(const S: string);
  221. begin
  222. Add (S);
  223. end;
  224. Procedure TStrings.AddStrings(TheStrings: TStrings);
  225. Var Runner : longint;
  226. begin
  227. For Runner:=0 to TheStrings.Count-1 do
  228. self.AddObject (Thestrings[Runner],TheStrings.Objects[Runner]);
  229. end;
  230. Procedure TStrings.Assign(Source: TPersistent);
  231. begin
  232. If Source is TStrings then
  233. begin
  234. clear;
  235. AddStrings(TStrings(Source));
  236. exit;
  237. end;
  238. Inherited Assign(Source);
  239. end;
  240. Procedure TStrings.BeginUpdate;
  241. begin
  242. end;
  243. Procedure TStrings.EndUpdate;
  244. begin
  245. end;
  246. Function TStrings.Equals(TheStrings: TStrings): Boolean;
  247. Var Runner,Nr : Longint;
  248. begin
  249. Result:=False;
  250. Nr:=Self.Count;
  251. if Nr<>TheStrings.Count then exit;
  252. For Runner:=0 to Nr-1 do
  253. If Strings[Runner]<>TheStrings[Runner] then exit;
  254. Result:=True;
  255. end;
  256. Procedure TStrings.Exchange(Index1, Index2: Integer);
  257. Var
  258. Obj : TObject;
  259. Str : String;
  260. begin
  261. Obj:=Objects[Index1];
  262. Str:=Strings[Index1];
  263. Objects[Index1]:=Objects[Index2];
  264. Strings[Index1]:=Strings[Index2];
  265. Objects[Index2]:=Obj;
  266. Strings[Index2]:=Str;
  267. end;
  268. Function TStrings.GetText: PChar;
  269. begin
  270. Result:=StrNew(Pchar(Self.Text));
  271. end;
  272. Function TStrings.IndexOf(const S: string): Integer;
  273. begin
  274. Result:=0;
  275. While (Result<Count) and (Strings[Result]<>S) do Result:=Result+1;
  276. if Result=Count then Result:=-1;
  277. end;
  278. Function TStrings.IndexOfName(const Name: string): Integer;
  279. Var len : longint;
  280. begin
  281. Result:=0;
  282. while (Result<Count) do
  283. begin
  284. len:=pos('=',Strings[Result])-1;
  285. if (len>0) and (Name=Copy(Strings[Result],1,Len)) then exit;
  286. inc(result);
  287. end;
  288. result:=-1;
  289. end;
  290. Function TStrings.IndexOfObject(AObject: TObject): Integer;
  291. begin
  292. Result:=0;
  293. While (Result<count) and (Objects[Result]<>AObject) do Result:=Result+1;
  294. If Result=Count then Result:=-1;
  295. end;
  296. Procedure TStrings.InsertObject(Index: Integer; const S: string;
  297. AObject: TObject);
  298. begin
  299. Insert (Index,S);
  300. Objects[Index]:=AObject;
  301. end;
  302. Procedure TStrings.LoadFromFile(const FileName: string);
  303. Var TheStream : TFileStream;
  304. begin
  305. TheStream:=TFileStream.Create(FileName,fmOpenRead);
  306. LoadFromStream(TheStream);
  307. TheStream.Free;
  308. end;
  309. Procedure TStrings.LoadFromStream(Stream: TStream);
  310. {
  311. Borlands method is no goed, since a pipe for
  312. Instance doesn't have a size.
  313. So we must do it the hard way.
  314. }
  315. Const
  316. BufSize = 1024;
  317. Var
  318. Buffer : Pointer;
  319. BytesRead,
  320. BufLen : Longint;
  321. begin
  322. // reread into a buffer
  323. Buffer:=Nil;
  324. BufLen:=0;
  325. Repeat
  326. ReAllocMem(Buffer,BufLen+BufSize);
  327. BytesRead:=Stream.Read((Buffer+BufLen)^,BufSize);
  328. inc(BufLen,BufSize);
  329. Until BytesRead<>BufSize;
  330. // Null-terminate !!
  331. Pchar(Buffer)[BufLen-BufSize+BytesRead]:=#0;
  332. Text:=PChar(Buffer);
  333. FreeMem(Buffer);
  334. end;
  335. Procedure TStrings.Move(CurIndex, NewIndex: Integer);
  336. Var
  337. Obj : TObject;
  338. Str : String;
  339. begin
  340. Obj:=Objects[CurIndex];
  341. Str:=Strings[CurIndex];
  342. Delete(Curindex);
  343. InsertObject(NewIndex,Str,Obj);
  344. end;
  345. Procedure TStrings.SaveToFile(const FileName: string);
  346. Var TheStream : TFileStream;
  347. begin
  348. TheStream:=TFileStream.Create(FileName,fmCreate);
  349. SaveToStream(TheStream);
  350. TheStream.Free;
  351. end;
  352. Procedure TStrings.SaveToStream(Stream: TStream);
  353. Var
  354. S : String;
  355. begin
  356. S:=Text;
  357. Stream.Write(Pointer(S)^,Length(S));
  358. end;
  359. Function GetNextLine (Var P : Pchar; Var S : String) : Boolean;
  360. Var PS : PChar;
  361. begin
  362. S:='';
  363. Result:=False;
  364. If P^=#0 then exit;
  365. PS:=P;
  366. While not (P^ in [#0,#10,#13]) do P:=P+1;
  367. SetLength (S,P-PS);
  368. System.Move (PS^,Pointer(S)^,P-PS);
  369. If P^=#13 then P:=P+1;
  370. If P^=#10 then
  371. P:=P+1; // Point to character after #10(#13)
  372. Result:=True;
  373. end;
  374. Procedure TStrings.SetText(TheText: PChar);
  375. Var S : String;
  376. begin
  377. Clear;
  378. While GetNextLine (TheText,S) do
  379. Add(S);
  380. end;
  381. {****************************************************************************}
  382. {* TStringList *}
  383. {****************************************************************************}
  384. Procedure TStringList.ExchangeItems(Index1, Index2: Integer);
  385. Var P1,P2 : Pointer;
  386. begin
  387. P1:=Pointer(Flist^[Index1].FString);
  388. P2:=Pointer(Flist^[Index1].FObject);
  389. Pointer(Flist^[Index1].Fstring):=Pointer(Flist^[Index2].Fstring);
  390. Pointer(Flist^[Index1].FObject):=Pointer(Flist^[Index2].FObject);
  391. Pointer(Flist^[Index2].Fstring):=P1;
  392. Pointer(Flist^[Index2].FObject):=P2;
  393. end;
  394. Procedure TStringList.Grow;
  395. Var Extra : Longint;
  396. begin
  397. If FCapacity>64 then
  398. Extra:=FCapacity Div 4
  399. Else If FCapacity>8 Then
  400. Extra:=16
  401. Else
  402. Extra:=4;
  403. SetCapacity(FCapacity+Extra);
  404. end;
  405. Procedure TStringList.QuickSort(L, R: Integer);
  406. Var I,J : Longint;
  407. Pivot : String;
  408. begin
  409. Repeat;
  410. I:=L;
  411. J:=R;
  412. Pivot:=Flist^[(L+R) div 2].FString;
  413. Repeat
  414. While AnsiCompareText(Flist^[I].Fstring,Pivot)<0 do Inc(I);
  415. While AnsiCompareText(Flist^[J].Fstring,Pivot)>0 do Dec(J);
  416. If I<=J then
  417. begin
  418. ExchangeItems(I,J); // No check, indices are correct.
  419. Inc(I);
  420. Dec(j);
  421. end;
  422. until I>J;
  423. If L<J then QuickSort(L,J);
  424. L:=I;
  425. Until I>=R;
  426. end;
  427. Procedure TStringList.InsertItem(Index: Integer; const S: string);
  428. begin
  429. Changing;
  430. If FCount=Fcapacity then Grow;
  431. If Index<FCount then
  432. System.Move (FList^[Index],FList^[Index+1],
  433. (FCount-Index)*SizeOf(TStringItem));
  434. Pointer(Flist^[Index].Fstring):=Nil; // Needed to initialize...
  435. Flist^[Index].FString:=S;
  436. Flist^[Index].Fobject:=Nil;
  437. Inc(FCount);
  438. Changed;
  439. end;
  440. Procedure TStringList.SetSorted(Value: Boolean);
  441. begin
  442. If FSorted<>Value then
  443. begin
  444. If Value then sort;
  445. FSorted:=VAlue
  446. end;
  447. end;
  448. Procedure TStringList.Changed;
  449. begin
  450. If (FUpdateCount=0) Then
  451. If Assigned(FOnChange) then
  452. FOnchange(Self);
  453. end;
  454. Procedure TStringList.Changing;
  455. begin
  456. If FUpdateCount=0 then
  457. if Assigned(FOnChanging) then
  458. FOnchanging(Self);
  459. end;
  460. Function TStringList.Get(Index: Integer): string;
  461. begin
  462. If (Index<0) or (INdex>=Fcount) then
  463. Error (SListIndexError,Index);
  464. Result:=Flist^[Index].FString;
  465. end;
  466. Function TStringList.GetCapacity: Integer;
  467. begin
  468. Result:=FCapacity;
  469. end;
  470. Function TStringList.GetCount: Integer;
  471. begin
  472. Result:=FCount;
  473. end;
  474. Function TStringList.GetObject(Index: Integer): TObject;
  475. begin
  476. If (Index<0) or (INdex>=Fcount) then
  477. Error (SListIndexError,Index);
  478. Result:=Flist^[Index].FObject;
  479. end;
  480. Procedure TStringList.Put(Index: Integer; const S: string);
  481. begin
  482. If Sorted then
  483. Error(SSortedListError,0);
  484. If (Index<0) or (INdex>=Fcount) then
  485. Error (SListIndexError,Index);
  486. Changing;
  487. Flist^[Index].FString:=S;
  488. Changed;
  489. end;
  490. Procedure TStringList.PutObject(Index: Integer; AObject: TObject);
  491. begin
  492. If (Index<0) or (INdex>=Fcount) then
  493. Error (SListIndexError,Index);
  494. Changing;
  495. Flist^[Index].FObject:=AObject;
  496. Changed;
  497. end;
  498. Procedure TStringList.SetCapacity(NewCapacity: Integer);
  499. Var NewList : Pointer;
  500. MSize : Longint;
  501. begin
  502. If (NewCapacity<0) then
  503. Error (SListCapacityError,NewCapacity);
  504. If NewCapacity>FCapacity then
  505. begin
  506. GetMem (NewList,NewCapacity*SizeOf(TStringItem));
  507. If NewList=Nil then
  508. Error (SListCapacityError,NewCapacity);
  509. If Assigned(FList) then
  510. begin
  511. MSize:=FCapacity*Sizeof(TStringItem);
  512. System.Move (FList^,NewList^,MSize);
  513. FillWord (Pchar(NewList)[MSize],(NewCapacity-FCapacity)*WordRatio, 0);
  514. FreeMem (Flist,MSize);
  515. end;
  516. Flist:=NewList;
  517. FCapacity:=NewCapacity;
  518. end
  519. else if NewCapacity<FCapacity then
  520. begin
  521. NewList:=Flist+NewCapacity*SizeOf(TStringItem);
  522. FreeMem (NewList, (FCapacity-NewCapacity)*SizeOf(TStringItem));
  523. FCapacity:=NewCapacity;
  524. end;
  525. end;
  526. Procedure TStringList.SetUpdateState(Updating: Boolean);
  527. begin
  528. If Updating then
  529. Changing
  530. else
  531. Changed
  532. end;
  533. destructor TStringList.Destroy;
  534. Var I : Longint;
  535. begin
  536. FOnChange:=Nil;
  537. FOnChanging:=Nil;
  538. // This will force a dereference. Can be done better...
  539. For I:=0 to FCount-1 do
  540. FList^[I].FString:='';
  541. FCount:=0;
  542. SetCapacity(0);
  543. Inherited destroy;
  544. end;
  545. Function TStringList.Add(const S: string): Integer;
  546. begin
  547. If Not Sorted then
  548. Result:=FCount
  549. else
  550. If Find (S,Result) then
  551. Case DUplicates of
  552. DupIgnore : Exit;
  553. DupError : Error(SDuplicateString,0)
  554. end;
  555. InsertItem (Result,S);
  556. end;
  557. Procedure TStringList.Clear;
  558. Var I : longint;
  559. begin
  560. For I:=0 to FCount-1 do
  561. Flist^[I].FString:='';
  562. FCount:=0;
  563. SetCapacity(0);
  564. end;
  565. Procedure TStringList.Delete(Index: Integer);
  566. begin
  567. If (Index<0) or (Index>=FCount) then
  568. Error(SlistINdexError,Index);
  569. Flist^[Index].FString:='';
  570. Dec(FCount);
  571. If Index<FCount then
  572. System.Move(Flist^[Index+1],
  573. Flist^[Index],
  574. (Fcount-Index)*SizeOf(TStringItem));
  575. end;
  576. Procedure TStringList.Exchange(Index1, Index2: Integer);
  577. begin
  578. If (Index1<0) or (Index1>=FCount) then
  579. Error(SListIndexError,Index1);
  580. If (Index2<0) or (Index2>=FCount) then
  581. Error(SListIndexError,Index1);
  582. Changing;
  583. ExchangeItems(Index1,Index2);
  584. changed;
  585. end;
  586. Function TStringList.Find(const S: string; var Index: Integer): Boolean;
  587. { Searches for the first string <= S, returns True if exact match,
  588. sets index to the index f the found string. }
  589. Var I,L,R,Temp : Longint;
  590. begin
  591. Result:=False;
  592. // Use binary search.
  593. L:=0;
  594. R:=FCount-1;
  595. While L<=R do
  596. begin
  597. I:=(L+R) div 2;
  598. Temp:=AnsiCompareText(FList^ [I].FString,S);
  599. If Temp<0 then
  600. L:=I+1
  601. else
  602. begin
  603. R:=I-1;
  604. If Temp=0 then
  605. begin
  606. Result:=True;
  607. If Duplicates<>DupAccept then L:=I;
  608. end;
  609. end;
  610. end;
  611. Index:=L;
  612. end;
  613. Function TStringList.IndexOf(const S: string): Integer;
  614. begin
  615. If Not Sorted then
  616. Result:=Inherited indexOf(S)
  617. else
  618. // faster using binary search...
  619. If Not Find (S,Result) then
  620. Result:=-1;
  621. end;
  622. Procedure TStringList.Insert(Index: Integer; const S: string);
  623. begin
  624. If Sorted then
  625. Error (SSortedListError,0)
  626. else
  627. If (Index<0) or (Index>FCount) then
  628. Error (SListIndexError,Index)
  629. else
  630. InsertItem (Index,S);
  631. end;
  632. Procedure TStringList.Sort;
  633. begin
  634. If Not Sorted and (FCount>1) then
  635. begin
  636. Changing;
  637. QuickSOrt(0,FCount-1);
  638. Changed;
  639. end;
  640. end;
  641. {
  642. $Log$
  643. Revision 1.10 2000-01-07 01:24:33 peter
  644. * updated copyright to 2000
  645. Revision 1.9 2000/01/06 01:20:33 peter
  646. * moved out of packages/ back to topdir
  647. Revision 1.1 2000/01/03 19:33:08 peter
  648. * moved to packages dir
  649. Revision 1.7 1999/12/22 01:08:18 peter
  650. * use reallocmem/freemem/getmem from the heapmanager
  651. Revision 1.6 1999/11/25 13:28:13 michael
  652. + Fixed bug in settext
  653. Revision 1.5 1999/07/07 12:34:01 peter
  654. * removed debug writeln
  655. Revision 1.4 1999/05/26 13:22:23 michael
  656. + Fixed insertitem
  657. Revision 1.3 1999/04/27 07:46:18 michael
  658. * Fixed bug that caused error in loadfromstream when last line in stream has not CRLF pair
  659. Revision 1.2 1999/04/15 07:51:45 michael
  660. + Bugfix in strings.Loadfromstream
  661. Revision 1.1 1999/04/13 08:52:28 michael
  662. + Moved strings.inc to stringl.inc, to avoid conflict with strings unit
  663. Revision 1.15 1999/04/08 10:18:56 peter
  664. * makefile updates
  665. }