stringl.inc 17 KB

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