cclasses.pas 59 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl and Peter Vreman
  4. This module provides some basic classes
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit cclasses;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. cutils,cstreams;
  23. {********************************************
  24. TMemDebug
  25. ********************************************}
  26. type
  27. tmemdebug = class
  28. private
  29. totalmem,
  30. startmem : integer;
  31. infostr : string[40];
  32. public
  33. constructor Create(const s:string);
  34. destructor Destroy;override;
  35. procedure show;
  36. procedure start;
  37. procedure stop;
  38. end;
  39. {*******************************************************
  40. TList (Copied from FCL, exception handling stripped)
  41. ********************************************************}
  42. const
  43. MaxListSize = Maxint div 16;
  44. SListIndexError = 'List index exceeds bounds (%d)';
  45. SListCapacityError = 'The maximum list capacity is reached (%d)';
  46. SListCountError = 'List count too large (%d)';
  47. type
  48. { TList class }
  49. PPointerList = ^TPointerList;
  50. TPointerList = array[0..MaxListSize - 1] of Pointer;
  51. TListSortCompare = function (Item1, Item2: Pointer): Integer;
  52. TList = class(TObject)
  53. private
  54. FList: PPointerList;
  55. FCount: Integer;
  56. FCapacity: Integer;
  57. protected
  58. function Get(Index: Integer): Pointer;
  59. procedure Grow; virtual;
  60. procedure Put(Index: Integer; Item: Pointer);
  61. procedure SetCapacity(NewCapacity: Integer);
  62. procedure SetCount(NewCount: Integer);
  63. public
  64. destructor Destroy; override;
  65. function Add(Item: Pointer): Integer;
  66. procedure Clear; dynamic;
  67. procedure Delete(Index: Integer);
  68. class procedure Error(const Msg: string; Data: Integer); virtual;
  69. procedure Exchange(Index1, Index2: Integer);
  70. function Expand: TList;
  71. function Extract(item: Pointer): Pointer;
  72. function First: Pointer;
  73. procedure Assign(Obj:TList);
  74. function IndexOf(Item: Pointer): Integer;
  75. procedure Insert(Index: Integer; Item: Pointer);
  76. function Last: Pointer;
  77. procedure Move(CurIndex, NewIndex: Integer);
  78. function Remove(Item: Pointer): Integer;
  79. procedure Pack;
  80. procedure Sort(Compare: TListSortCompare);
  81. property Capacity: Integer read FCapacity write SetCapacity;
  82. property Count: Integer read FCount write SetCount;
  83. property Items[Index: Integer]: Pointer read Get write Put; default;
  84. property List: PPointerList read FList;
  85. end;
  86. {********************************************
  87. TLinkedList
  88. ********************************************}
  89. type
  90. TLinkedListItem = class
  91. public
  92. Previous,
  93. Next : TLinkedListItem;
  94. Constructor Create;
  95. Destructor Destroy;override;
  96. Function GetCopy:TLinkedListItem;virtual;
  97. end;
  98. TLinkedListItemClass = class of TLinkedListItem;
  99. TLinkedList = class
  100. private
  101. FCount : integer;
  102. FFirst,
  103. FLast : TLinkedListItem;
  104. FNoClear : boolean;
  105. public
  106. constructor Create;
  107. destructor Destroy;override;
  108. { true when the List is empty }
  109. function Empty:boolean;
  110. { deletes all Items }
  111. procedure Clear;
  112. { inserts an Item }
  113. procedure Insert(Item:TLinkedListItem);
  114. { inserts an Item before Loc }
  115. procedure InsertBefore(Item,Loc : TLinkedListItem);
  116. { inserts an Item after Loc }
  117. procedure InsertAfter(Item,Loc : TLinkedListItem);virtual;
  118. { concats an Item }
  119. procedure Concat(Item:TLinkedListItem);
  120. { deletes an Item }
  121. procedure Remove(Item:TLinkedListItem);
  122. { Gets First Item }
  123. function GetFirst:TLinkedListItem;
  124. { Gets last Item }
  125. function GetLast:TLinkedListItem;
  126. { inserts another List at the begin and make this List empty }
  127. procedure insertList(p : TLinkedList);
  128. { inserts another List after the provided item and make this List empty }
  129. procedure insertListAfter(Item:TLinkedListItem;p : TLinkedList);
  130. { concats another List at the end and make this List empty }
  131. procedure concatList(p : TLinkedList);
  132. { concats another List at the start and makes a copy
  133. the list is ordered in reverse.
  134. }
  135. procedure insertListcopy(p : TLinkedList);
  136. { concats another List at the end and makes a copy }
  137. procedure concatListcopy(p : TLinkedList);
  138. property First:TLinkedListItem read FFirst;
  139. property Last:TLinkedListItem read FLast;
  140. property Count:Integer read FCount;
  141. property NoClear:boolean write FNoClear;
  142. end;
  143. {********************************************
  144. TStringList
  145. ********************************************}
  146. { string containerItem }
  147. TStringListItem = class(TLinkedListItem)
  148. FPStr : PString;
  149. public
  150. constructor Create(const s:string);
  151. destructor Destroy;override;
  152. function GetCopy:TLinkedListItem;override;
  153. function Str:string;
  154. end;
  155. { string container }
  156. TStringList = class(TLinkedList)
  157. private
  158. FDoubles : boolean; { if this is set to true, doubles are allowed }
  159. public
  160. constructor Create;
  161. constructor Create_No_Double;
  162. { inserts an Item }
  163. procedure Insert(const s:string);
  164. { concats an Item }
  165. procedure Concat(const s:string);
  166. { deletes an Item }
  167. procedure Remove(const s:string);
  168. { Gets First Item }
  169. function GetFirst:string;
  170. { Gets last Item }
  171. function GetLast:string;
  172. { true if string is in the container }
  173. function Find(const s:string):TStringListItem;
  174. { inserts an item }
  175. procedure InsertItem(item:TStringListItem);
  176. { concats an item }
  177. procedure ConcatItem(item:TStringListItem);
  178. property Doubles:boolean read FDoubles write FDoubles;
  179. end;
  180. {********************************************
  181. Dictionary
  182. ********************************************}
  183. const
  184. { the real size will be [0..hasharray-1] ! }
  185. hasharraysize = 512;
  186. type
  187. { namedindexobect for use with dictionary and indexarray }
  188. TNamedIndexItem=class
  189. private
  190. { indexarray }
  191. FIndexNr : integer;
  192. FIndexNext : TNamedIndexItem;
  193. { dictionary }
  194. FLeft,
  195. FRight : TNamedIndexItem;
  196. FSpeedValue : cardinal;
  197. { singleList }
  198. FListNext : TNamedIndexItem;
  199. FName : Pstring;
  200. protected
  201. function GetName:string;virtual;
  202. procedure SetName(const n:string);virtual;
  203. public
  204. constructor Create;
  205. constructor CreateName(const n:string);
  206. destructor Destroy;override;
  207. property IndexNr:integer read FIndexNr write FIndexNr;
  208. property IndexNext:TNamedIndexItem read FIndexNext write FIndexNext;
  209. property Name:string read GetName write SetName;
  210. property SpeedValue:cardinal read FSpeedValue;
  211. property ListNext:TNamedIndexItem read FListNext;
  212. property Left:TNamedIndexItem read FLeft write FLeft;
  213. property Right:TNamedIndexItem read FRight write FRight;
  214. end;
  215. Pdictionaryhasharray=^Tdictionaryhasharray;
  216. Tdictionaryhasharray=array[0..hasharraysize-1] of TNamedIndexItem;
  217. TnamedIndexCallback = procedure(p:TNamedIndexItem;arg:pointer) of object;
  218. TnamedIndexStaticCallback = procedure(p:TNamedIndexItem;arg:pointer);
  219. Tdictionary=class
  220. private
  221. FRoot : TNamedIndexItem;
  222. FCount : longint;
  223. FHashArray : Pdictionaryhasharray;
  224. procedure cleartree(var obj:TNamedIndexItem);
  225. function insertNode(NewNode:TNamedIndexItem;var currNode:TNamedIndexItem):TNamedIndexItem;
  226. procedure inserttree(currtree,currroot:TNamedIndexItem);
  227. public
  228. noclear : boolean;
  229. delete_doubles : boolean;
  230. constructor Create;
  231. destructor Destroy;override;
  232. procedure usehash;
  233. procedure clear;
  234. function delete(const s:string):TNamedIndexItem;
  235. function empty:boolean;
  236. procedure foreach(proc2call:TNamedIndexcallback;arg:pointer);
  237. procedure foreach_static(proc2call:TNamedIndexStaticCallback;arg:pointer);
  238. function insert(obj:TNamedIndexItem):TNamedIndexItem;
  239. function replace(oldobj,newobj:TNamedIndexItem):boolean;
  240. function rename(const olds,News : string):TNamedIndexItem;
  241. function search(const s:string):TNamedIndexItem;
  242. function speedsearch(const s:string;SpeedValue:cardinal):TNamedIndexItem;
  243. property Items[const s:string]:TNamedIndexItem read Search;default;
  244. property Count:longint read FCount;
  245. end;
  246. tsingleList=class
  247. First,
  248. last : TNamedIndexItem;
  249. constructor Create;
  250. procedure reset;
  251. procedure clear;
  252. procedure insert(p:TNamedIndexItem);
  253. end;
  254. tindexobjectarray=array[1..16000] of TNamedIndexItem;
  255. pnamedindexobjectarray=^tindexobjectarray;
  256. tindexarray=class
  257. noclear : boolean;
  258. First : TNamedIndexItem;
  259. count : integer;
  260. constructor Create(Agrowsize:integer);
  261. destructor destroy;override;
  262. procedure clear;
  263. procedure foreach(proc2call : Tnamedindexcallback;arg:pointer);
  264. procedure foreach_static(proc2call : Tnamedindexstaticcallback;arg:pointer);
  265. procedure deleteindex(p:TNamedIndexItem);
  266. procedure delete(var p:TNamedIndexItem);
  267. procedure insert(p:TNamedIndexItem);
  268. procedure replace(oldp,newp:TNamedIndexItem);
  269. function search(nr:integer):TNamedIndexItem;
  270. private
  271. growsize,
  272. size : integer;
  273. data : pnamedindexobjectarray;
  274. procedure grow(gsize:integer);
  275. end;
  276. {********************************************
  277. DynamicArray
  278. ********************************************}
  279. const
  280. dynamicblockbasesize = 12;
  281. type
  282. pdynamicblock = ^tdynamicblock;
  283. tdynamicblock = record
  284. pos,
  285. used : integer;
  286. Next : pdynamicblock;
  287. { can't use sizeof(integer) because it crashes gdb }
  288. data : array[0..1024*1024] of byte;
  289. end;
  290. tdynamicarray = class
  291. private
  292. FPosn : integer;
  293. FPosnblock : pdynamicblock;
  294. FBlocksize : integer;
  295. FFirstblock,
  296. FLastblock : pdynamicblock;
  297. procedure grow;
  298. public
  299. constructor Create(Ablocksize:integer);
  300. destructor Destroy;override;
  301. procedure reset;
  302. function size:integer;
  303. procedure align(i:integer);
  304. procedure seek(i:integer);
  305. function read(var d;len:integer):integer;
  306. procedure write(const d;len:integer);
  307. procedure writestr(const s:string);
  308. procedure readstream(f:TCStream;maxlen:longint);
  309. procedure writestream(f:TCStream);
  310. property BlockSize : integer read FBlocksize;
  311. property FirstBlock : PDynamicBlock read FFirstBlock;
  312. property Pos : integer read FPosn;
  313. end;
  314. implementation
  315. {*****************************************************************************
  316. Memory debug
  317. *****************************************************************************}
  318. constructor tmemdebug.create(const s:string);
  319. begin
  320. infostr:=s;
  321. totalmem:=0;
  322. Start;
  323. end;
  324. procedure tmemdebug.start;
  325. begin
  326. {$ifdef Delphi}
  327. startmem:=0;
  328. {$else}
  329. startmem:=memavail;
  330. {$endif Delphi}
  331. end;
  332. procedure tmemdebug.stop;
  333. begin
  334. if startmem<>0 then
  335. begin
  336. {$ifndef Delphi}
  337. inc(TotalMem,memavail-startmem);
  338. {$endif}
  339. startmem:=0;
  340. end;
  341. end;
  342. destructor tmemdebug.destroy;
  343. begin
  344. Stop;
  345. show;
  346. end;
  347. procedure tmemdebug.show;
  348. begin
  349. {$ifndef Delphi}
  350. write('memory [',infostr,'] ');
  351. if TotalMem>0 then
  352. writeln(DStr(TotalMem shr 10),' Kb released')
  353. else
  354. writeln(DStr((-TotalMem) shr 10),' Kb allocated');
  355. {$endif Delphi}
  356. end;
  357. {*****************************************************************************
  358. TList
  359. *****************************************************************************}
  360. Const
  361. // Ratio of Pointer and Word Size.
  362. WordRatio = SizeOf(Pointer) Div SizeOf(Word);
  363. function TList.Get(Index: Integer): Pointer;
  364. begin
  365. If (Index<0) or (Index>=FCount) then
  366. Error(SListIndexError,Index);
  367. Result:=FList^[Index];
  368. end;
  369. procedure TList.Grow;
  370. begin
  371. // Only for compatibility with Delphi. Not needed.
  372. end;
  373. procedure TList.Put(Index: Integer; Item: Pointer);
  374. begin
  375. if (Index<0) or (Index>=FCount) then
  376. Error(SListIndexError,Index);
  377. Flist^[Index]:=Item;
  378. end;
  379. function TList.Extract(item: Pointer): Pointer;
  380. var
  381. i : Integer;
  382. begin
  383. result:=nil;
  384. i:=IndexOf(item);
  385. if i>=0 then
  386. begin
  387. Result:=item;
  388. FList^[i]:=nil;
  389. Delete(i);
  390. end;
  391. end;
  392. procedure TList.SetCapacity(NewCapacity: Integer);
  393. Var NewList,ToFree : PPointerList;
  394. begin
  395. If (NewCapacity<0) or (NewCapacity>MaxListSize) then
  396. Error (SListCapacityError,NewCapacity);
  397. if NewCapacity=FCapacity then
  398. exit;
  399. ReallocMem(FList,SizeOf(Pointer)*NewCapacity);
  400. FCapacity:=NewCapacity;
  401. end;
  402. procedure TList.SetCount(NewCount: Integer);
  403. begin
  404. If (NewCount<0) or (NewCount>MaxListSize)then
  405. Error(SListCountError,NewCount);
  406. If NewCount<FCount then
  407. FCount:=NewCount
  408. else If NewCount>FCount then
  409. begin
  410. If NewCount>FCapacity then
  411. SetCapacity (NewCount);
  412. If FCount<NewCount then
  413. FillWord (Flist^[FCount],(NewCount-FCount)* WordRatio ,0);
  414. FCount:=Newcount;
  415. end;
  416. end;
  417. destructor TList.Destroy;
  418. begin
  419. Self.Clear;
  420. inherited Destroy;
  421. end;
  422. Function TList.Add(Item: Pointer): Integer;
  423. begin
  424. Self.Insert (Count,Item);
  425. Result:=Count-1;
  426. end;
  427. Procedure TList.Clear;
  428. begin
  429. If Assigned(FList) then
  430. begin
  431. FreeMem (Flist,FCapacity*SizeOf(Pointer));
  432. FList:=Nil;
  433. FCapacity:=0;
  434. FCount:=0;
  435. end;
  436. end;
  437. Procedure TList.Delete(Index: Integer);
  438. Var
  439. OldPointer :Pointer;
  440. begin
  441. If (Index<0) or (Index>=FCount) then
  442. Error (SListIndexError,Index);
  443. FCount:=FCount-1;
  444. OldPointer:=Flist^[Index];
  445. System.Move (FList^[Index+1],FList^[Index],(FCount-Index)*SizeOf(Pointer));
  446. // Shrink the list if appropiate
  447. if (FCapacity > 256) and (FCount < FCapacity shr 2) then
  448. begin
  449. FCapacity := FCapacity shr 1;
  450. ReallocMem(FList, SizeOf(Pointer) * FCapacity);
  451. end;
  452. end;
  453. class procedure TList.Error(const Msg: string; Data: Integer);
  454. var
  455. s:string;
  456. p:longint;
  457. begin
  458. p:=pos('%d',Msg);
  459. writeln(copy(Msg,1,pred(p)),Data,copy(Msg,p+3,255));
  460. end;
  461. procedure TList.Exchange(Index1, Index2: Integer);
  462. var Temp : Pointer;
  463. begin
  464. If ((Index1>=FCount) or (Index1<0)) then
  465. Error(SListIndexError,Index1);
  466. If ((Index2>=FCount) or (Index2<0)) then
  467. Error(SListIndexError,Index2);
  468. Temp:=FList^[Index1];
  469. FList^[Index1]:=FList^[Index2];
  470. FList^[Index2]:=Temp;
  471. end;
  472. function TList.Expand: TList;
  473. Var IncSize : Longint;
  474. begin
  475. if FCount<FCapacity then exit;
  476. IncSize:=4;
  477. if FCapacity>3 then IncSize:=IncSize+4;
  478. if FCapacity>8 then IncSize:=IncSize+8;
  479. if FCapacity>127 then Inc(IncSize, FCapacity shr 2);
  480. SetCapacity(FCapacity+IncSize);
  481. Result:=Self;
  482. end;
  483. function TList.First: Pointer;
  484. begin
  485. If FCount=0 then
  486. Result:=Nil
  487. else
  488. Result:=Items[0];
  489. end;
  490. function TList.IndexOf(Item: Pointer): Integer;
  491. begin
  492. Result:=0;
  493. While (Result<FCount) and (Flist^[Result]<>Item) do Result:=Result+1;
  494. If Result=FCount then Result:=-1;
  495. end;
  496. procedure TList.Insert(Index: Integer; Item: Pointer);
  497. begin
  498. If (Index<0) or (Index>FCount )then
  499. Error(SlistIndexError,Index);
  500. IF FCount=FCapacity Then Self.Expand;
  501. If Index<FCount then
  502. System.Move(Flist^[Index],Flist^[Index+1],(FCount-Index)*SizeOf(Pointer));
  503. FList^[Index]:=Item;
  504. FCount:=FCount+1;
  505. end;
  506. function TList.Last: Pointer;
  507. begin
  508. // Wouldn't it be better to return nil if the count is zero ?
  509. If FCount=0 then
  510. Result:=Nil
  511. else
  512. Result:=Items[FCount-1];
  513. end;
  514. procedure TList.Move(CurIndex, NewIndex: Integer);
  515. Var Temp : Pointer;
  516. begin
  517. If ((CurIndex<0) or (CurIndex>Count-1)) then
  518. Error(SListIndexError,CurIndex);
  519. If (NewINdex<0) then
  520. Error(SlistIndexError,NewIndex);
  521. Temp:=FList^[CurIndex];
  522. FList^[CurIndex]:=Nil;
  523. Self.Delete(CurIndex);
  524. // ?? If NewIndex>CurIndex then NewIndex:=NewIndex-1;
  525. // Newindex changes when deleting ??
  526. Self.Insert (NewIndex,Nil);
  527. FList^[NewIndex]:=Temp;
  528. end;
  529. function TList.Remove(Item: Pointer): Integer;
  530. begin
  531. Result:=IndexOf(Item);
  532. If Result<>-1 then
  533. Self.Delete (Result);
  534. end;
  535. Procedure TList.Pack;
  536. Var {Last,I,J,}Runner : Longint;
  537. begin
  538. // Not the fastest; but surely correct
  539. For Runner:=Fcount-1 downto 0 do
  540. if Items[Runner]=Nil then Self.Delete(Runner);
  541. { The following may be faster in case of large and defragmented lists
  542. If count=0 then exit;
  543. Runner:=0;I:=0;
  544. TheLast:=Count;
  545. while runner<count do
  546. begin
  547. // Find first Nil
  548. While (FList^[Runner]<>Nil) and (Runner<Count) do Runner:=Runner+1;
  549. if Runner<Count do
  550. begin
  551. // Start searching for non-nil from last known nil+1
  552. if i<Runner then I:=Runner+1;
  553. While (Flist[I]^=Nil) and (I<Count) do I:=I+1;
  554. // Start looking for last non-nil of block.
  555. J:=I+1;
  556. While (Flist^[J]<>Nil) and (J<Count) do J:=J+1;
  557. // Move block and zero out
  558. Move (Flist^[I],Flist^[Runner],J*SizeOf(Pointer));
  559. FillWord (Flist^[I],(J-I)*WordRatio,0);
  560. // Update Runner and Last to point behind last block
  561. TheLast:=Runner+(J-I);
  562. If J=Count then
  563. begin
  564. // Shortcut, when J=Count we checked all pointers
  565. Runner:=Count
  566. else
  567. begin
  568. Runner:=TheLast;
  569. I:=j;
  570. end;
  571. end;
  572. Count:=TheLast;
  573. }
  574. end;
  575. // Needed by Sort method.
  576. Procedure QuickSort (Flist : PPointerList; L,R : Longint;
  577. Compare : TListSortCompare);
  578. Var I,J : Longint;
  579. P,Q : Pointer;
  580. begin
  581. Repeat
  582. I:=L;
  583. J:=R;
  584. P:=FList^[ (L+R) div 2 ];
  585. repeat
  586. While Compare(P,FList^[i])>0 Do I:=I+1;
  587. While Compare(P,FList^[J])<0 Do J:=J-1;
  588. If I<=J then
  589. begin
  590. Q:=Flist^[I];
  591. Flist^[I]:=FList^[J];
  592. FList^[J]:=Q;
  593. I:=I+1;
  594. J:=j-1;
  595. end;
  596. Until I>J;
  597. If L<J then QuickSort (FList,L,J,Compare);
  598. L:=I;
  599. Until I>=R;
  600. end;
  601. procedure TList.Sort(Compare: TListSortCompare);
  602. begin
  603. If Not Assigned(FList) or (FCount<2) then exit;
  604. QuickSort (Flist, 0, FCount-1,Compare);
  605. end;
  606. procedure TList.Assign(Obj:TList);
  607. // Principle copied from TCollection
  608. var i : Integer;
  609. begin
  610. Clear;
  611. For I:=0 To Obj.Count-1 Do
  612. Add(Obj[i]);
  613. end;
  614. {****************************************************************************
  615. TLinkedListItem
  616. ****************************************************************************}
  617. constructor TLinkedListItem.Create;
  618. begin
  619. Previous:=nil;
  620. Next:=nil;
  621. end;
  622. destructor TLinkedListItem.Destroy;
  623. begin
  624. end;
  625. function TLinkedListItem.GetCopy:TLinkedListItem;
  626. var
  627. p : TLinkedListItem;
  628. l : integer;
  629. begin
  630. p:=TLinkedListItemClass(ClassType).Create;
  631. l:=InstanceSize;
  632. Move(pointer(self)^,pointer(p)^,l);
  633. Result:=p;
  634. end;
  635. {****************************************************************************
  636. TLinkedList
  637. ****************************************************************************}
  638. constructor TLinkedList.Create;
  639. begin
  640. FFirst:=nil;
  641. Flast:=nil;
  642. FCount:=0;
  643. FNoClear:=False;
  644. end;
  645. destructor TLinkedList.destroy;
  646. begin
  647. if not FNoClear then
  648. Clear;
  649. end;
  650. function TLinkedList.empty:boolean;
  651. begin
  652. Empty:=(FFirst=nil);
  653. end;
  654. procedure TLinkedList.Insert(Item:TLinkedListItem);
  655. begin
  656. if FFirst=nil then
  657. begin
  658. FLast:=Item;
  659. Item.Previous:=nil;
  660. Item.Next:=nil;
  661. end
  662. else
  663. begin
  664. FFirst.Previous:=Item;
  665. Item.Previous:=nil;
  666. Item.Next:=FFirst;
  667. end;
  668. FFirst:=Item;
  669. inc(FCount);
  670. end;
  671. procedure TLinkedList.InsertBefore(Item,Loc : TLinkedListItem);
  672. begin
  673. Item.Previous:=Loc.Previous;
  674. Item.Next:=Loc;
  675. Loc.Previous:=Item;
  676. if assigned(Item.Previous) then
  677. Item.Previous.Next:=Item
  678. else
  679. { if we've no next item, we've to adjust FFist }
  680. FFirst:=Item;
  681. inc(FCount);
  682. end;
  683. procedure TLinkedList.InsertAfter(Item,Loc : TLinkedListItem);
  684. begin
  685. Item.Next:=Loc.Next;
  686. Loc.Next:=Item;
  687. Item.Previous:=Loc;
  688. if assigned(Item.Next) then
  689. Item.Next.Previous:=Item
  690. else
  691. { if we've no next item, we've to adjust FLast }
  692. FLast:=Item;
  693. inc(FCount);
  694. end;
  695. procedure TLinkedList.Concat(Item:TLinkedListItem);
  696. begin
  697. if FFirst=nil then
  698. begin
  699. FFirst:=Item;
  700. Item.Previous:=nil;
  701. Item.Next:=nil;
  702. end
  703. else
  704. begin
  705. Flast.Next:=Item;
  706. Item.Previous:=Flast;
  707. Item.Next:=nil;
  708. end;
  709. Flast:=Item;
  710. inc(FCount);
  711. end;
  712. procedure TLinkedList.remove(Item:TLinkedListItem);
  713. begin
  714. if Item=nil then
  715. exit;
  716. if (FFirst=Item) and (Flast=Item) then
  717. begin
  718. FFirst:=nil;
  719. Flast:=nil;
  720. end
  721. else if FFirst=Item then
  722. begin
  723. FFirst:=Item.Next;
  724. if assigned(FFirst) then
  725. FFirst.Previous:=nil;
  726. end
  727. else if Flast=Item then
  728. begin
  729. Flast:=Flast.Previous;
  730. if assigned(Flast) then
  731. Flast.Next:=nil;
  732. end
  733. else
  734. begin
  735. Item.Previous.Next:=Item.Next;
  736. Item.Next.Previous:=Item.Previous;
  737. end;
  738. Item.Next:=nil;
  739. Item.Previous:=nil;
  740. dec(FCount);
  741. end;
  742. procedure TLinkedList.clear;
  743. var
  744. NewNode : TLinkedListItem;
  745. begin
  746. NewNode:=FFirst;
  747. while assigned(NewNode) do
  748. begin
  749. FFirst:=NewNode.Next;
  750. NewNode.Free;
  751. NewNode:=FFirst;
  752. end;
  753. FLast:=nil;
  754. FFirst:=nil;
  755. FCount:=0;
  756. end;
  757. function TLinkedList.GetFirst:TLinkedListItem;
  758. begin
  759. if FFirst=nil then
  760. GetFirst:=nil
  761. else
  762. begin
  763. GetFirst:=FFirst;
  764. if FFirst=FLast then
  765. FLast:=nil;
  766. FFirst:=FFirst.Next;
  767. dec(FCount);
  768. end;
  769. end;
  770. function TLinkedList.GetLast:TLinkedListItem;
  771. begin
  772. if FLast=nil then
  773. Getlast:=nil
  774. else
  775. begin
  776. Getlast:=FLast;
  777. if FLast=FFirst then
  778. FFirst:=nil;
  779. FLast:=FLast.Previous;
  780. dec(FCount);
  781. end;
  782. end;
  783. procedure TLinkedList.insertList(p : TLinkedList);
  784. begin
  785. { empty List ? }
  786. if (p.FFirst=nil) then
  787. exit;
  788. p.Flast.Next:=FFirst;
  789. { we have a double Linked List }
  790. if assigned(FFirst) then
  791. FFirst.Previous:=p.Flast;
  792. FFirst:=p.FFirst;
  793. if (FLast=nil) then
  794. Flast:=p.Flast;
  795. inc(FCount,p.FCount);
  796. { p becomes empty }
  797. p.FFirst:=nil;
  798. p.Flast:=nil;
  799. p.FCount:=0;
  800. end;
  801. procedure TLinkedList.insertListAfter(Item:TLinkedListItem;p : TLinkedList);
  802. begin
  803. { empty List ? }
  804. if (p.FFirst=nil) then
  805. exit;
  806. if (Item=nil) then
  807. begin
  808. { Insert at begin }
  809. InsertList(p);
  810. exit;
  811. end
  812. else
  813. begin
  814. p.FFirst.Previous:=Item;
  815. p.FLast.Next:=Item.Next;
  816. if assigned(Item.Next) then
  817. Item.Next.Previous:=p.FLast
  818. else
  819. FLast:=p.FLast;
  820. Item.Next:=p.FFirst;
  821. inc(FCount,p.FCount);
  822. end;
  823. { p becomes empty }
  824. p.FFirst:=nil;
  825. p.Flast:=nil;
  826. p.FCount:=0;
  827. end;
  828. procedure TLinkedList.concatList(p : TLinkedList);
  829. begin
  830. if (p.FFirst=nil) then
  831. exit;
  832. if FFirst=nil then
  833. FFirst:=p.FFirst
  834. else
  835. begin
  836. FLast.Next:=p.FFirst;
  837. p.FFirst.Previous:=Flast;
  838. end;
  839. Flast:=p.Flast;
  840. inc(FCount,p.FCount);
  841. { make p empty }
  842. p.Flast:=nil;
  843. p.FFirst:=nil;
  844. p.FCount:=0;
  845. end;
  846. procedure TLinkedList.insertListcopy(p : TLinkedList);
  847. var
  848. NewNode,NewNode2 : TLinkedListItem;
  849. begin
  850. NewNode:=p.First;
  851. while assigned(NewNode) do
  852. begin
  853. NewNode2:=NewNode.Getcopy;
  854. if assigned(NewNode2) then
  855. Insert(NewNode2);
  856. NewNode:=NewNode.Next;
  857. end;
  858. end;
  859. procedure TLinkedList.concatListcopy(p : TLinkedList);
  860. var
  861. NewNode,NewNode2 : TLinkedListItem;
  862. begin
  863. NewNode:=p.First;
  864. while assigned(NewNode) do
  865. begin
  866. NewNode2:=NewNode.Getcopy;
  867. if assigned(NewNode2) then
  868. Concat(NewNode2);
  869. NewNode:=NewNode.Next;
  870. end;
  871. end;
  872. {****************************************************************************
  873. TStringListItem
  874. ****************************************************************************}
  875. constructor TStringListItem.Create(const s:string);
  876. begin
  877. inherited Create;
  878. FPStr:=stringdup(s);
  879. end;
  880. destructor TStringListItem.Destroy;
  881. begin
  882. stringdispose(FPStr);
  883. end;
  884. function TStringListItem.Str:string;
  885. begin
  886. Str:=FPStr^;
  887. end;
  888. function TStringListItem.GetCopy:TLinkedListItem;
  889. begin
  890. Result:=(inherited GetCopy);
  891. TStringListItem(Result).FPStr:=stringdup(FPstr^);
  892. end;
  893. {****************************************************************************
  894. TSTRINGList
  895. ****************************************************************************}
  896. constructor tstringList.Create;
  897. begin
  898. inherited Create;
  899. FDoubles:=true;
  900. end;
  901. constructor tstringList.Create_no_double;
  902. begin
  903. inherited Create;
  904. FDoubles:=false;
  905. end;
  906. procedure tstringList.insert(const s : string);
  907. begin
  908. if (s='') or
  909. ((not FDoubles) and (find(s)<>nil)) then
  910. exit;
  911. inherited insert(tstringListItem.create(s));
  912. end;
  913. procedure tstringList.concat(const s : string);
  914. begin
  915. if (s='') or
  916. ((not FDoubles) and (find(s)<>nil)) then
  917. exit;
  918. inherited concat(tstringListItem.create(s));
  919. end;
  920. procedure tstringList.remove(const s : string);
  921. var
  922. p : tstringListItem;
  923. begin
  924. if s='' then
  925. exit;
  926. p:=find(s);
  927. if assigned(p) then
  928. begin
  929. inherited Remove(p);
  930. p.Free;
  931. end;
  932. end;
  933. function tstringList.GetFirst : string;
  934. var
  935. p : tstringListItem;
  936. begin
  937. p:=tstringListItem(inherited GetFirst);
  938. if p=nil then
  939. GetFirst:=''
  940. else
  941. begin
  942. GetFirst:=p.FPStr^;
  943. p.free;
  944. end;
  945. end;
  946. function tstringList.Getlast : string;
  947. var
  948. p : tstringListItem;
  949. begin
  950. p:=tstringListItem(inherited Getlast);
  951. if p=nil then
  952. Getlast:=''
  953. else
  954. begin
  955. Getlast:=p.FPStr^;
  956. p.free;
  957. end;
  958. end;
  959. function tstringList.find(const s:string):TstringListItem;
  960. var
  961. NewNode : tstringListItem;
  962. begin
  963. find:=nil;
  964. if s='' then
  965. exit;
  966. NewNode:=tstringListItem(FFirst);
  967. while assigned(NewNode) do
  968. begin
  969. if NewNode.FPStr^=s then
  970. begin
  971. find:=NewNode;
  972. exit;
  973. end;
  974. NewNode:=tstringListItem(NewNode.Next);
  975. end;
  976. end;
  977. procedure TStringList.InsertItem(item:TStringListItem);
  978. begin
  979. inherited Insert(item);
  980. end;
  981. procedure TStringList.ConcatItem(item:TStringListItem);
  982. begin
  983. inherited Concat(item);
  984. end;
  985. {****************************************************************************
  986. TNamedIndexItem
  987. ****************************************************************************}
  988. constructor TNamedIndexItem.Create;
  989. begin
  990. { index }
  991. Findexnr:=-1;
  992. FindexNext:=nil;
  993. { dictionary }
  994. Fleft:=nil;
  995. Fright:=nil;
  996. FName:=nil;
  997. Fspeedvalue:=cardinal($ffffffff);
  998. { List }
  999. FListNext:=nil;
  1000. end;
  1001. constructor TNamedIndexItem.Createname(const n:string);
  1002. begin
  1003. { index }
  1004. Findexnr:=-1;
  1005. FindexNext:=nil;
  1006. { dictionary }
  1007. Fleft:=nil;
  1008. Fright:=nil;
  1009. fspeedvalue:=getspeedvalue(n);
  1010. {$ifdef compress}
  1011. FName:=stringdup(minilzw_encode(n));
  1012. {$else}
  1013. FName:=stringdup(n);
  1014. {$endif}
  1015. { List }
  1016. FListNext:=nil;
  1017. end;
  1018. destructor TNamedIndexItem.destroy;
  1019. begin
  1020. stringdispose(FName);
  1021. end;
  1022. procedure TNamedIndexItem.setname(const n:string);
  1023. begin
  1024. if assigned(FName) then
  1025. stringdispose(FName);
  1026. fspeedvalue:=getspeedvalue(n);
  1027. {$ifdef compress}
  1028. FName:=stringdup(minilzw_encode(n));
  1029. {$else}
  1030. FName:=stringdup(n);
  1031. {$endif}
  1032. end;
  1033. function TNamedIndexItem.GetName:string;
  1034. begin
  1035. if assigned(FName) then
  1036. {$ifdef compress}
  1037. Getname:=minilzw_decode(FName^)
  1038. {$else}
  1039. Getname:=FName^
  1040. {$endif}
  1041. else
  1042. Getname:='';
  1043. end;
  1044. {****************************************************************************
  1045. TDICTIONARY
  1046. ****************************************************************************}
  1047. constructor Tdictionary.Create;
  1048. begin
  1049. FRoot:=nil;
  1050. FHashArray:=nil;
  1051. noclear:=false;
  1052. delete_doubles:=false;
  1053. end;
  1054. procedure Tdictionary.usehash;
  1055. begin
  1056. if not(assigned(FRoot)) and
  1057. not(assigned(FHashArray)) then
  1058. begin
  1059. New(FHashArray);
  1060. fillchar(FHashArray^,sizeof(FHashArray^),0);
  1061. end;
  1062. end;
  1063. function counttree(p: tnamedindexitem): longint;
  1064. begin
  1065. counttree:=0;
  1066. if not assigned(p) then
  1067. exit;
  1068. result := 1;
  1069. inc(result,counttree(p.fleft));
  1070. inc(result,counttree(p.fright));
  1071. end;
  1072. destructor Tdictionary.destroy;
  1073. begin
  1074. if not noclear then
  1075. clear;
  1076. if assigned(FHashArray) then
  1077. begin
  1078. dispose(FHashArray);
  1079. end;
  1080. end;
  1081. procedure Tdictionary.cleartree(var obj:TNamedIndexItem);
  1082. begin
  1083. if assigned(obj.Fleft) then
  1084. cleartree(obj.FLeft);
  1085. if assigned(obj.FRight) then
  1086. cleartree(obj.FRight);
  1087. obj.free;
  1088. obj:=nil;
  1089. end;
  1090. procedure Tdictionary.clear;
  1091. var
  1092. w : integer;
  1093. begin
  1094. if assigned(FRoot) then
  1095. cleartree(FRoot);
  1096. if assigned(FHashArray) then
  1097. for w:= low(FHashArray^) to high(FHashArray^) do
  1098. if assigned(FHashArray^[w]) then
  1099. cleartree(FHashArray^[w]);
  1100. end;
  1101. function Tdictionary.delete(const s:string):TNamedIndexItem;
  1102. var
  1103. p,SpeedValue : cardinal;
  1104. n : TNamedIndexItem;
  1105. {$ifdef compress}
  1106. senc:string;
  1107. {$else}
  1108. senc:string absolute s;
  1109. {$endif}
  1110. procedure insert_right_bottom(var root,Atree:TNamedIndexItem);
  1111. begin
  1112. while root.FRight<>nil do
  1113. root:=root.FRight;
  1114. root.FRight:=Atree;
  1115. end;
  1116. function delete_from_tree(root:TNamedIndexItem):TNamedIndexItem;
  1117. type
  1118. leftright=(left,right);
  1119. var
  1120. lr : leftright;
  1121. oldroot : TNamedIndexItem;
  1122. begin
  1123. oldroot:=nil;
  1124. while (root<>nil) and (root.SpeedValue<>SpeedValue) do
  1125. begin
  1126. oldroot:=root;
  1127. if SpeedValue<root.SpeedValue then
  1128. begin
  1129. root:=root.FRight;
  1130. lr:=right;
  1131. end
  1132. else
  1133. begin
  1134. root:=root.FLeft;
  1135. lr:=left;
  1136. end;
  1137. end;
  1138. while (root<>nil) and (root.FName^<>senc) do
  1139. begin
  1140. oldroot:=root;
  1141. if senc<root.FName^ then
  1142. begin
  1143. root:=root.FRight;
  1144. lr:=right;
  1145. end
  1146. else
  1147. begin
  1148. root:=root.FLeft;
  1149. lr:=left;
  1150. end;
  1151. end;
  1152. if root<>nil then
  1153. begin
  1154. dec(FCount);
  1155. if root.FLeft<>nil then
  1156. begin
  1157. { Now the Node pointing to root must point to the left
  1158. subtree of root. The right subtree of root must be
  1159. connected to the right bottom of the left subtree.}
  1160. if lr=left then
  1161. oldroot.FLeft:=root.FLeft
  1162. else
  1163. oldroot.FRight:=root.FLeft;
  1164. if root.FRight<>nil then
  1165. insert_right_bottom(root.FLeft,root.FRight);
  1166. end
  1167. else
  1168. begin
  1169. { There is no left subtree. So we can just replace the Node to
  1170. delete with the right subtree.}
  1171. if lr=left then
  1172. oldroot.FLeft:=root.FRight
  1173. else
  1174. oldroot.FRight:=root.FRight;
  1175. end;
  1176. end;
  1177. delete_from_tree:=root;
  1178. end;
  1179. begin
  1180. {$ifdef compress}
  1181. senc:=minilzw_encode(s);
  1182. {$endif}
  1183. SpeedValue:=GetSpeedValue(s);
  1184. n:=FRoot;
  1185. if assigned(FHashArray) then
  1186. begin
  1187. { First, check if the Node to delete directly located under
  1188. the hasharray.}
  1189. p:=SpeedValue mod hasharraysize;
  1190. n:=FHashArray^[p];
  1191. if (n<>nil) and (n.SpeedValue=SpeedValue) and
  1192. (n.FName^=senc) then
  1193. begin
  1194. { The Node to delete is directly located under the
  1195. hasharray. Make the hasharray point to the left
  1196. subtree of the Node and place the right subtree on
  1197. the right-bottom of the left subtree.}
  1198. if n.FLeft<>nil then
  1199. begin
  1200. FHashArray^[p]:=n.FLeft;
  1201. if n.FRight<>nil then
  1202. insert_right_bottom(n.FLeft,n.FRight);
  1203. end
  1204. else
  1205. FHashArray^[p]:=n.FRight;
  1206. delete:=n;
  1207. dec(FCount);
  1208. exit;
  1209. end;
  1210. end
  1211. else
  1212. begin
  1213. { First check if the Node to delete is the root.}
  1214. if (FRoot<>nil) and (n.SpeedValue=SpeedValue) and
  1215. (n.FName^=senc) then
  1216. begin
  1217. if n.FLeft<>nil then
  1218. begin
  1219. FRoot:=n.FLeft;
  1220. if n.FRight<>nil then
  1221. insert_right_bottom(n.FLeft,n.FRight);
  1222. end
  1223. else
  1224. FRoot:=n.FRight;
  1225. delete:=n;
  1226. dec(FCount);
  1227. exit;
  1228. end;
  1229. end;
  1230. delete:=delete_from_tree(n);
  1231. end;
  1232. function Tdictionary.empty:boolean;
  1233. var
  1234. w : integer;
  1235. begin
  1236. if assigned(FHashArray) then
  1237. begin
  1238. empty:=false;
  1239. for w:=low(FHashArray^) to high(FHashArray^) do
  1240. if assigned(FHashArray^[w]) then
  1241. exit;
  1242. empty:=true;
  1243. end
  1244. else
  1245. empty:=(FRoot=nil);
  1246. end;
  1247. procedure Tdictionary.foreach(proc2call:TNamedIndexcallback;arg:pointer);
  1248. procedure a(p:TNamedIndexItem;arg:pointer);
  1249. begin
  1250. proc2call(p,arg);
  1251. if assigned(p.FLeft) then
  1252. a(p.FLeft,arg);
  1253. if assigned(p.FRight) then
  1254. a(p.FRight,arg);
  1255. end;
  1256. var
  1257. i : integer;
  1258. begin
  1259. if assigned(FHashArray) then
  1260. begin
  1261. for i:=low(FHashArray^) to high(FHashArray^) do
  1262. if assigned(FHashArray^[i]) then
  1263. a(FHashArray^[i],arg);
  1264. end
  1265. else
  1266. if assigned(FRoot) then
  1267. a(FRoot,arg);
  1268. end;
  1269. procedure Tdictionary.foreach_static(proc2call:TNamedIndexStaticCallback;arg:pointer);
  1270. procedure a(p:TNamedIndexItem;arg:pointer);
  1271. begin
  1272. proc2call(p,arg);
  1273. if assigned(p.FLeft) then
  1274. a(p.FLeft,arg);
  1275. if assigned(p.FRight) then
  1276. a(p.FRight,arg);
  1277. end;
  1278. var
  1279. i : integer;
  1280. begin
  1281. if assigned(FHashArray) then
  1282. begin
  1283. for i:=low(FHashArray^) to high(FHashArray^) do
  1284. if assigned(FHashArray^[i]) then
  1285. a(FHashArray^[i],arg);
  1286. end
  1287. else
  1288. if assigned(FRoot) then
  1289. a(FRoot,arg);
  1290. end;
  1291. function Tdictionary.replace(oldobj,newobj:TNamedIndexItem):boolean;
  1292. var
  1293. hp : TNamedIndexItem;
  1294. begin
  1295. hp:=nil;
  1296. Replace:=false;
  1297. { must be the same name and hash }
  1298. if (oldobj.FSpeedValue<>newobj.FSpeedValue) or
  1299. (oldobj.FName^<>newobj.FName^) then
  1300. exit;
  1301. { copy tree info }
  1302. newobj.FLeft:=oldobj.FLeft;
  1303. newobj.FRight:=oldobj.FRight;
  1304. { update treeroot }
  1305. if assigned(FHashArray) then
  1306. begin
  1307. hp:=FHashArray^[newobj.FSpeedValue mod hasharraysize];
  1308. if hp=oldobj then
  1309. begin
  1310. FHashArray^[newobj.FSpeedValue mod hasharraysize]:=newobj;
  1311. hp:=nil;
  1312. end;
  1313. end
  1314. else
  1315. begin
  1316. hp:=FRoot;
  1317. if hp=oldobj then
  1318. begin
  1319. FRoot:=newobj;
  1320. hp:=nil;
  1321. end;
  1322. end;
  1323. { update parent entry }
  1324. while assigned(hp) do
  1325. begin
  1326. { is the node to replace the left or right, then
  1327. update this node and stop }
  1328. if hp.FLeft=oldobj then
  1329. begin
  1330. hp.FLeft:=newobj;
  1331. break;
  1332. end;
  1333. if hp.FRight=oldobj then
  1334. begin
  1335. hp.FRight:=newobj;
  1336. break;
  1337. end;
  1338. { First check SpeedValue, to allow a fast insert }
  1339. if hp.SpeedValue>oldobj.SpeedValue then
  1340. hp:=hp.FRight
  1341. else
  1342. if hp.SpeedValue<oldobj.SpeedValue then
  1343. hp:=hp.FLeft
  1344. else
  1345. begin
  1346. if (hp.FName^=oldobj.FName^) then
  1347. begin
  1348. { this can never happend, return error }
  1349. exit;
  1350. end
  1351. else
  1352. if oldobj.FName^>hp.FName^ then
  1353. hp:=hp.FLeft
  1354. else
  1355. hp:=hp.FRight;
  1356. end;
  1357. end;
  1358. Replace:=true;
  1359. end;
  1360. function Tdictionary.insert(obj:TNamedIndexItem):TNamedIndexItem;
  1361. begin
  1362. inc(FCount);
  1363. if assigned(FHashArray) then
  1364. insert:=insertNode(obj,FHashArray^[obj.SpeedValue mod hasharraysize])
  1365. else
  1366. insert:=insertNode(obj,FRoot);
  1367. end;
  1368. function tdictionary.insertNode(NewNode:TNamedIndexItem;var currNode:TNamedIndexItem):TNamedIndexItem;
  1369. begin
  1370. if currNode=nil then
  1371. begin
  1372. currNode:=NewNode;
  1373. insertNode:=NewNode;
  1374. end
  1375. { First check SpeedValue, to allow a fast insert }
  1376. else
  1377. if currNode.SpeedValue>NewNode.SpeedValue then
  1378. insertNode:=insertNode(NewNode,currNode.FRight)
  1379. else
  1380. if currNode.SpeedValue<NewNode.SpeedValue then
  1381. insertNode:=insertNode(NewNode,currNode.FLeft)
  1382. else
  1383. begin
  1384. if currNode.FName^>NewNode.FName^ then
  1385. insertNode:=insertNode(NewNode,currNode.FRight)
  1386. else
  1387. if currNode.FName^<NewNode.FName^ then
  1388. insertNode:=insertNode(NewNode,currNode.FLeft)
  1389. else
  1390. begin
  1391. if (delete_doubles) and
  1392. assigned(currNode) then
  1393. begin
  1394. NewNode.FLeft:=currNode.FLeft;
  1395. NewNode.FRight:=currNode.FRight;
  1396. if delete_doubles then
  1397. begin
  1398. currnode.FLeft:=nil;
  1399. currnode.FRight:=nil;
  1400. currnode.free;
  1401. end;
  1402. currNode:=NewNode;
  1403. insertNode:=NewNode;
  1404. end
  1405. else
  1406. insertNode:=currNode;
  1407. end;
  1408. end;
  1409. end;
  1410. procedure tdictionary.inserttree(currtree,currroot:TNamedIndexItem);
  1411. begin
  1412. if assigned(currtree) then
  1413. begin
  1414. inserttree(currtree.FLeft,currroot);
  1415. inserttree(currtree.FRight,currroot);
  1416. currtree.FRight:=nil;
  1417. currtree.FLeft:=nil;
  1418. insertNode(currtree,currroot);
  1419. end;
  1420. end;
  1421. function tdictionary.rename(const olds,News : string):TNamedIndexItem;
  1422. var
  1423. spdval : cardinal;
  1424. lasthp,
  1425. hp,hp2,hp3 : TNamedIndexItem;
  1426. {$ifdef compress}
  1427. oldsenc,newsenc:string;
  1428. {$else}
  1429. oldsenc:string absolute olds;
  1430. newsenc:string absolute news;
  1431. {$endif}
  1432. begin
  1433. {$ifdef compress}
  1434. oldsenc:=minilzw_encode(olds);
  1435. newsenc:=minilzw_encode(news);
  1436. {$endif}
  1437. spdval:=GetSpeedValue(olds);
  1438. if assigned(FHashArray) then
  1439. hp:=FHashArray^[spdval mod hasharraysize]
  1440. else
  1441. hp:=FRoot;
  1442. lasthp:=nil;
  1443. while assigned(hp) do
  1444. begin
  1445. if spdval>hp.SpeedValue then
  1446. begin
  1447. lasthp:=hp;
  1448. hp:=hp.FLeft
  1449. end
  1450. else
  1451. if spdval<hp.SpeedValue then
  1452. begin
  1453. lasthp:=hp;
  1454. hp:=hp.FRight
  1455. end
  1456. else
  1457. begin
  1458. if (hp.FName^=oldsenc) then
  1459. begin
  1460. { Get in hp2 the replacer for the root or hasharr }
  1461. hp2:=hp.FLeft;
  1462. hp3:=hp.FRight;
  1463. if not assigned(hp2) then
  1464. begin
  1465. hp2:=hp.FRight;
  1466. hp3:=hp.FLeft;
  1467. end;
  1468. { remove entry from the tree }
  1469. if assigned(lasthp) then
  1470. begin
  1471. if lasthp.FLeft=hp then
  1472. lasthp.FLeft:=hp2
  1473. else
  1474. lasthp.FRight:=hp2;
  1475. end
  1476. else
  1477. begin
  1478. if assigned(FHashArray) then
  1479. FHashArray^[spdval mod hasharraysize]:=hp2
  1480. else
  1481. FRoot:=hp2;
  1482. end;
  1483. { reinsert the hp3 in the tree from hp2 }
  1484. inserttree(hp3,hp2);
  1485. { reset Node with New values }
  1486. hp.FLeft:=nil;
  1487. hp.FRight:=nil;
  1488. stringdispose(hp.FName);
  1489. hp.FName:=stringdup(newsenc);
  1490. hp.FSpeedValue:=GetSpeedValue(news);
  1491. { reinsert }
  1492. if assigned(FHashArray) then
  1493. rename:=insertNode(hp,FHashArray^[hp.SpeedValue mod hasharraysize])
  1494. else
  1495. rename:=insertNode(hp,FRoot);
  1496. exit;
  1497. end
  1498. else
  1499. if oldsenc>hp.FName^ then
  1500. begin
  1501. lasthp:=hp;
  1502. hp:=hp.FLeft
  1503. end
  1504. else
  1505. begin
  1506. lasthp:=hp;
  1507. hp:=hp.FRight;
  1508. end;
  1509. end;
  1510. end;
  1511. result := nil;
  1512. end;
  1513. function Tdictionary.search(const s:string):TNamedIndexItem;
  1514. var t:string;
  1515. begin
  1516. search:=speedsearch(s,getspeedvalue(s));
  1517. end;
  1518. function Tdictionary.speedsearch(const s:string;SpeedValue:cardinal):TNamedIndexItem;
  1519. var
  1520. NewNode:TNamedIndexItem;
  1521. {$ifdef compress}
  1522. decn:string;
  1523. {$endif}
  1524. begin
  1525. if assigned(FHashArray) then
  1526. NewNode:=FHashArray^[SpeedValue mod hasharraysize]
  1527. else
  1528. NewNode:=FRoot;
  1529. while assigned(NewNode) do
  1530. begin
  1531. if SpeedValue>NewNode.SpeedValue then
  1532. NewNode:=NewNode.FLeft
  1533. else
  1534. if SpeedValue<NewNode.SpeedValue then
  1535. NewNode:=NewNode.FRight
  1536. else
  1537. begin
  1538. {$ifdef compress}
  1539. decn:=minilzw_decode(newnode.fname^);
  1540. if (decn=s) then
  1541. begin
  1542. speedsearch:=NewNode;
  1543. exit;
  1544. end
  1545. else
  1546. if s>decn then
  1547. NewNode:=NewNode.FLeft
  1548. else
  1549. NewNode:=NewNode.FRight;
  1550. {$else}
  1551. if (NewNode.FName^=s) then
  1552. begin
  1553. speedsearch:=NewNode;
  1554. exit;
  1555. end
  1556. else
  1557. if s>NewNode.FName^ then
  1558. NewNode:=NewNode.FLeft
  1559. else
  1560. NewNode:=NewNode.FRight;
  1561. {$endif}
  1562. end;
  1563. end;
  1564. speedsearch:=nil;
  1565. end;
  1566. {****************************************************************************
  1567. tsingleList
  1568. ****************************************************************************}
  1569. constructor tsingleList.create;
  1570. begin
  1571. First:=nil;
  1572. last:=nil;
  1573. end;
  1574. procedure tsingleList.reset;
  1575. begin
  1576. First:=nil;
  1577. last:=nil;
  1578. end;
  1579. procedure tsingleList.clear;
  1580. var
  1581. hp,hp2 : TNamedIndexItem;
  1582. begin
  1583. hp:=First;
  1584. while assigned(hp) do
  1585. begin
  1586. hp2:=hp;
  1587. hp:=hp.FListNext;
  1588. hp2.free;
  1589. end;
  1590. First:=nil;
  1591. last:=nil;
  1592. end;
  1593. procedure tsingleList.insert(p:TNamedIndexItem);
  1594. begin
  1595. if not assigned(First) then
  1596. First:=p
  1597. else
  1598. last.FListNext:=p;
  1599. last:=p;
  1600. p.FListNext:=nil;
  1601. end;
  1602. {****************************************************************************
  1603. tindexarray
  1604. ****************************************************************************}
  1605. constructor tindexarray.create(Agrowsize:integer);
  1606. begin
  1607. growsize:=Agrowsize;
  1608. size:=0;
  1609. count:=0;
  1610. data:=nil;
  1611. First:=nil;
  1612. noclear:=false;
  1613. end;
  1614. destructor tindexarray.destroy;
  1615. begin
  1616. if assigned(data) then
  1617. begin
  1618. if not noclear then
  1619. clear;
  1620. freemem(data);
  1621. data:=nil;
  1622. end;
  1623. end;
  1624. function tindexarray.search(nr:integer):TNamedIndexItem;
  1625. begin
  1626. if nr<=count then
  1627. search:=data^[nr]
  1628. else
  1629. search:=nil;
  1630. end;
  1631. procedure tindexarray.clear;
  1632. var
  1633. i : integer;
  1634. begin
  1635. for i:=1 to count do
  1636. if assigned(data^[i]) then
  1637. begin
  1638. data^[i].free;
  1639. data^[i]:=nil;
  1640. end;
  1641. count:=0;
  1642. First:=nil;
  1643. end;
  1644. procedure tindexarray.foreach(proc2call : Tnamedindexcallback;arg:pointer);
  1645. var
  1646. i : integer;
  1647. begin
  1648. for i:=1 to count do
  1649. if assigned(data^[i]) then
  1650. proc2call(data^[i],arg);
  1651. end;
  1652. procedure tindexarray.foreach_static(proc2call : Tnamedindexstaticcallback;arg:pointer);
  1653. var
  1654. i : integer;
  1655. begin
  1656. for i:=1 to count do
  1657. if assigned(data^[i]) then
  1658. proc2call(data^[i],arg);
  1659. end;
  1660. procedure tindexarray.grow(gsize:integer);
  1661. var
  1662. osize : integer;
  1663. begin
  1664. osize:=size;
  1665. inc(size,gsize);
  1666. reallocmem(data,size*sizeof(pointer));
  1667. fillchar(data^[osize+1],gsize*sizeof(pointer),0);
  1668. end;
  1669. procedure tindexarray.deleteindex(p:TNamedIndexItem);
  1670. var
  1671. i : integer;
  1672. begin
  1673. i:=p.Findexnr;
  1674. { update counter }
  1675. if i=count then
  1676. dec(count);
  1677. { update Linked List }
  1678. while (i>0) do
  1679. begin
  1680. dec(i);
  1681. if (i>0) and assigned(data^[i]) then
  1682. begin
  1683. data^[i].FindexNext:=data^[p.Findexnr].FindexNext;
  1684. break;
  1685. end;
  1686. end;
  1687. if i=0 then
  1688. First:=p.FindexNext;
  1689. data^[p.FIndexnr]:=nil;
  1690. { clear entry }
  1691. p.FIndexnr:=-1;
  1692. p.FIndexNext:=nil;
  1693. end;
  1694. procedure tindexarray.delete(var p:TNamedIndexItem);
  1695. begin
  1696. deleteindex(p);
  1697. p.free;
  1698. p:=nil;
  1699. end;
  1700. procedure tindexarray.insert(p:TNamedIndexItem);
  1701. var
  1702. i : integer;
  1703. begin
  1704. if p.FIndexnr=-1 then
  1705. begin
  1706. inc(count);
  1707. p.FIndexnr:=count;
  1708. end;
  1709. if p.FIndexnr>count then
  1710. count:=p.FIndexnr;
  1711. if count>size then
  1712. grow(((count div growsize)+1)*growsize);
  1713. Assert(not assigned(data^[p.FIndexnr]) or (p=data^[p.FIndexnr]));
  1714. data^[p.FIndexnr]:=p;
  1715. { update Linked List backward }
  1716. i:=p.FIndexnr;
  1717. while (i>0) do
  1718. begin
  1719. dec(i);
  1720. if (i>0) and assigned(data^[i]) then
  1721. begin
  1722. data^[i].FIndexNext:=p;
  1723. break;
  1724. end;
  1725. end;
  1726. if i=0 then
  1727. First:=p;
  1728. { update Linked List forward }
  1729. i:=p.FIndexnr;
  1730. while (i<=count) do
  1731. begin
  1732. inc(i);
  1733. if (i<=count) and assigned(data^[i]) then
  1734. begin
  1735. p.FIndexNext:=data^[i];
  1736. exit;
  1737. end;
  1738. end;
  1739. if i>count then
  1740. p.FIndexNext:=nil;
  1741. end;
  1742. procedure tindexarray.replace(oldp,newp:TNamedIndexItem);
  1743. var
  1744. i : integer;
  1745. begin
  1746. newp.FIndexnr:=oldp.FIndexnr;
  1747. newp.FIndexNext:=oldp.FIndexNext;
  1748. data^[newp.FIndexnr]:=newp;
  1749. if First=oldp then
  1750. First:=newp;
  1751. { update Linked List backward }
  1752. i:=newp.FIndexnr;
  1753. while (i>0) do
  1754. begin
  1755. dec(i);
  1756. if (i>0) and assigned(data^[i]) then
  1757. begin
  1758. data^[i].FIndexNext:=newp;
  1759. break;
  1760. end;
  1761. end;
  1762. end;
  1763. {****************************************************************************
  1764. tdynamicarray
  1765. ****************************************************************************}
  1766. constructor tdynamicarray.create(Ablocksize:integer);
  1767. begin
  1768. FPosn:=0;
  1769. FPosnblock:=nil;
  1770. FFirstblock:=nil;
  1771. FLastblock:=nil;
  1772. Fblocksize:=Ablocksize;
  1773. grow;
  1774. end;
  1775. destructor tdynamicarray.destroy;
  1776. var
  1777. hp : pdynamicblock;
  1778. begin
  1779. while assigned(FFirstblock) do
  1780. begin
  1781. hp:=FFirstblock;
  1782. FFirstblock:=FFirstblock^.Next;
  1783. Freemem(hp);
  1784. end;
  1785. end;
  1786. function tdynamicarray.size:integer;
  1787. begin
  1788. if assigned(FLastblock) then
  1789. size:=FLastblock^.pos+FLastblock^.used
  1790. else
  1791. size:=0;
  1792. end;
  1793. procedure tdynamicarray.reset;
  1794. var
  1795. hp : pdynamicblock;
  1796. begin
  1797. while assigned(FFirstblock) do
  1798. begin
  1799. hp:=FFirstblock;
  1800. FFirstblock:=FFirstblock^.Next;
  1801. Freemem(hp);
  1802. end;
  1803. FPosn:=0;
  1804. FPosnblock:=nil;
  1805. FFirstblock:=nil;
  1806. FLastblock:=nil;
  1807. grow;
  1808. end;
  1809. procedure tdynamicarray.grow;
  1810. var
  1811. nblock : pdynamicblock;
  1812. begin
  1813. Getmem(nblock,blocksize+dynamicblockbasesize);
  1814. if not assigned(FFirstblock) then
  1815. begin
  1816. FFirstblock:=nblock;
  1817. FPosnblock:=nblock;
  1818. nblock^.pos:=0;
  1819. end
  1820. else
  1821. begin
  1822. FLastblock^.Next:=nblock;
  1823. nblock^.pos:=FLastblock^.pos+FLastblock^.used;
  1824. end;
  1825. nblock^.used:=0;
  1826. nblock^.Next:=nil;
  1827. fillchar(nblock^.data,blocksize,0);
  1828. FLastblock:=nblock;
  1829. end;
  1830. procedure tdynamicarray.align(i:integer);
  1831. var
  1832. j : integer;
  1833. begin
  1834. j:=(FPosn mod i);
  1835. if j<>0 then
  1836. begin
  1837. j:=i-j;
  1838. if FPosnblock^.used+j>blocksize then
  1839. begin
  1840. dec(j,blocksize-FPosnblock^.used);
  1841. FPosnblock^.used:=blocksize;
  1842. grow;
  1843. FPosnblock:=FLastblock;
  1844. end;
  1845. inc(FPosnblock^.used,j);
  1846. inc(FPosn,j);
  1847. end;
  1848. end;
  1849. procedure tdynamicarray.seek(i:integer);
  1850. begin
  1851. if (i<FPosnblock^.pos) or (i>=FPosnblock^.pos+blocksize) then
  1852. begin
  1853. { set FPosnblock correct if the size is bigger then
  1854. the current block }
  1855. if FPosnblock^.pos>i then
  1856. FPosnblock:=FFirstblock;
  1857. while assigned(FPosnblock) do
  1858. begin
  1859. if FPosnblock^.pos+blocksize>i then
  1860. break;
  1861. FPosnblock:=FPosnblock^.Next;
  1862. end;
  1863. { not found ? then increase blocks }
  1864. if not assigned(FPosnblock) then
  1865. begin
  1866. repeat
  1867. { the current FLastblock is now also fully used }
  1868. FLastblock^.used:=blocksize;
  1869. grow;
  1870. FPosnblock:=FLastblock;
  1871. until FPosnblock^.pos+blocksize>=i;
  1872. end;
  1873. end;
  1874. FPosn:=i;
  1875. if FPosn mod blocksize>FPosnblock^.used then
  1876. FPosnblock^.used:=FPosn mod blocksize;
  1877. end;
  1878. procedure tdynamicarray.write(const d;len:integer);
  1879. var
  1880. p : pchar;
  1881. i,j : integer;
  1882. begin
  1883. p:=pchar(@d);
  1884. while (len>0) do
  1885. begin
  1886. i:=FPosn mod blocksize;
  1887. if i+len>=blocksize then
  1888. begin
  1889. j:=blocksize-i;
  1890. move(p^,FPosnblock^.data[i],j);
  1891. inc(p,j);
  1892. inc(FPosn,j);
  1893. dec(len,j);
  1894. FPosnblock^.used:=blocksize;
  1895. if assigned(FPosnblock^.Next) then
  1896. FPosnblock:=FPosnblock^.Next
  1897. else
  1898. begin
  1899. grow;
  1900. FPosnblock:=FLastblock;
  1901. end;
  1902. end
  1903. else
  1904. begin
  1905. move(p^,FPosnblock^.data[i],len);
  1906. inc(p,len);
  1907. inc(FPosn,len);
  1908. i:=FPosn mod blocksize;
  1909. if i>FPosnblock^.used then
  1910. FPosnblock^.used:=i;
  1911. len:=0;
  1912. end;
  1913. end;
  1914. end;
  1915. procedure tdynamicarray.writestr(const s:string);
  1916. begin
  1917. write(s[1],length(s));
  1918. end;
  1919. function tdynamicarray.read(var d;len:integer):integer;
  1920. var
  1921. p : pchar;
  1922. i,j,res : integer;
  1923. begin
  1924. res:=0;
  1925. p:=pchar(@d);
  1926. while (len>0) do
  1927. begin
  1928. i:=FPosn mod blocksize;
  1929. if i+len>=FPosnblock^.used then
  1930. begin
  1931. j:=FPosnblock^.used-i;
  1932. move(FPosnblock^.data[i],p^,j);
  1933. inc(p,j);
  1934. inc(FPosn,j);
  1935. inc(res,j);
  1936. dec(len,j);
  1937. if assigned(FPosnblock^.Next) then
  1938. FPosnblock:=FPosnblock^.Next
  1939. else
  1940. break;
  1941. end
  1942. else
  1943. begin
  1944. move(FPosnblock^.data[i],p^,len);
  1945. inc(p,len);
  1946. inc(FPosn,len);
  1947. inc(res,len);
  1948. len:=0;
  1949. end;
  1950. end;
  1951. read:=res;
  1952. end;
  1953. procedure tdynamicarray.readstream(f:TCStream;maxlen:longint);
  1954. var
  1955. i,left : integer;
  1956. begin
  1957. if maxlen=-1 then
  1958. maxlen:=maxlongint;
  1959. repeat
  1960. left:=blocksize-FPosnblock^.used;
  1961. if left>maxlen then
  1962. left:=maxlen;
  1963. i:=f.Read(FPosnblock^.data[FPosnblock^.used],left);
  1964. dec(maxlen,i);
  1965. inc(FPosnblock^.used,i);
  1966. if FPosnblock^.used=blocksize then
  1967. begin
  1968. if assigned(FPosnblock^.Next) then
  1969. FPosnblock:=FPosnblock^.Next
  1970. else
  1971. begin
  1972. grow;
  1973. FPosnblock:=FLastblock;
  1974. end;
  1975. end;
  1976. until (i<left) or (maxlen=0);
  1977. end;
  1978. procedure tdynamicarray.writestream(f:TCStream);
  1979. var
  1980. hp : pdynamicblock;
  1981. begin
  1982. hp:=FFirstblock;
  1983. while assigned(hp) do
  1984. begin
  1985. f.Write(hp^.data,hp^.used);
  1986. hp:=hp^.Next;
  1987. end;
  1988. end;
  1989. end.
  1990. {
  1991. $Log$
  1992. Revision 1.35 2004-06-20 08:55:28 florian
  1993. * logs truncated
  1994. Revision 1.34 2004/06/16 20:07:07 florian
  1995. * dwarf branch merged
  1996. Revision 1.33 2004/05/24 17:30:09 peter
  1997. * allow setting of name in dictionary always. Otherwise it is never
  1998. possible to create an item with a name and rename before insert
  1999. this is used in the symtable to hide the current symbol
  2000. Revision 1.32 2004/05/23 14:31:31 peter
  2001. * count fixes for tlinkedlist
  2002. Revision 1.31 2004/04/28 18:02:54 peter
  2003. * add TList to cclasses, remove classes dependency from t_win32
  2004. Revision 1.30.2.3 2004/05/02 14:27:21 peter
  2005. * use sizeof(pointer) instead of 4
  2006. }