cclasses.pas 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412
  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. end;
  245. tsingleList=class
  246. First,
  247. last : TNamedIndexItem;
  248. constructor Create;
  249. procedure reset;
  250. procedure clear;
  251. procedure insert(p:TNamedIndexItem);
  252. end;
  253. tindexobjectarray=array[1..16000] of TNamedIndexItem;
  254. pnamedindexobjectarray=^tindexobjectarray;
  255. tindexarray=class
  256. noclear : boolean;
  257. First : TNamedIndexItem;
  258. count : integer;
  259. constructor Create(Agrowsize:integer);
  260. destructor destroy;override;
  261. procedure clear;
  262. procedure foreach(proc2call : Tnamedindexcallback;arg:pointer);
  263. procedure foreach_static(proc2call : Tnamedindexstaticcallback;arg:pointer);
  264. procedure deleteindex(p:TNamedIndexItem);
  265. procedure delete(var p:TNamedIndexItem);
  266. procedure insert(p:TNamedIndexItem);
  267. procedure replace(oldp,newp:TNamedIndexItem);
  268. function search(nr:integer):TNamedIndexItem;
  269. private
  270. growsize,
  271. size : integer;
  272. data : pnamedindexobjectarray;
  273. procedure grow(gsize:integer);
  274. end;
  275. {********************************************
  276. DynamicArray
  277. ********************************************}
  278. const
  279. dynamicblockbasesize = 12;
  280. type
  281. pdynamicblock = ^tdynamicblock;
  282. tdynamicblock = record
  283. pos,
  284. used : integer;
  285. Next : pdynamicblock;
  286. { can't use sizeof(integer) because it crashes gdb }
  287. data : array[0..1024*1024] of byte;
  288. end;
  289. tdynamicarray = class
  290. private
  291. FPosn : integer;
  292. FPosnblock : pdynamicblock;
  293. FBlocksize : integer;
  294. FFirstblock,
  295. FLastblock : pdynamicblock;
  296. procedure grow;
  297. public
  298. constructor Create(Ablocksize:integer);
  299. destructor Destroy;override;
  300. procedure reset;
  301. function size:integer;
  302. procedure align(i:integer);
  303. procedure seek(i:integer);
  304. function read(var d;len:integer):integer;
  305. procedure write(const d;len:integer);
  306. procedure writestr(const s:string);
  307. procedure readstream(f:TCStream;maxlen:longint);
  308. procedure writestream(f:TCStream);
  309. property BlockSize : integer read FBlocksize;
  310. property FirstBlock : PDynamicBlock read FFirstBlock;
  311. property Pos : integer read FPosn;
  312. end;
  313. implementation
  314. {*****************************************************************************
  315. Memory debug
  316. *****************************************************************************}
  317. constructor tmemdebug.create(const s:string);
  318. begin
  319. infostr:=s;
  320. totalmem:=0;
  321. Start;
  322. end;
  323. procedure tmemdebug.start;
  324. begin
  325. {$ifdef Delphi}
  326. startmem:=0;
  327. {$else}
  328. startmem:=memavail;
  329. {$endif Delphi}
  330. end;
  331. procedure tmemdebug.stop;
  332. begin
  333. if startmem<>0 then
  334. begin
  335. {$ifndef Delphi}
  336. inc(TotalMem,memavail-startmem);
  337. {$endif}
  338. startmem:=0;
  339. end;
  340. end;
  341. destructor tmemdebug.destroy;
  342. begin
  343. Stop;
  344. show;
  345. end;
  346. procedure tmemdebug.show;
  347. begin
  348. {$ifndef Delphi}
  349. write('memory [',infostr,'] ');
  350. if TotalMem>0 then
  351. writeln(DStr(TotalMem shr 10),' Kb released')
  352. else
  353. writeln(DStr((-TotalMem) shr 10),' Kb allocated');
  354. {$endif Delphi}
  355. end;
  356. {*****************************************************************************
  357. TList
  358. *****************************************************************************}
  359. Const
  360. // Ratio of Pointer and Word Size.
  361. WordRatio = SizeOf(Pointer) Div SizeOf(Word);
  362. function TList.Get(Index: Integer): Pointer;
  363. begin
  364. If (Index<0) or (Index>=FCount) then
  365. Error(SListIndexError,Index);
  366. Result:=FList^[Index];
  367. end;
  368. procedure TList.Grow;
  369. begin
  370. // Only for compatibility with Delphi. Not needed.
  371. end;
  372. procedure TList.Put(Index: Integer; Item: Pointer);
  373. begin
  374. if (Index<0) or (Index>=FCount) then
  375. Error(SListIndexError,Index);
  376. Flist^[Index]:=Item;
  377. end;
  378. function TList.Extract(item: Pointer): Pointer;
  379. var
  380. i : Integer;
  381. begin
  382. result:=nil;
  383. i:=IndexOf(item);
  384. if i>=0 then
  385. begin
  386. Result:=item;
  387. FList^[i]:=nil;
  388. Delete(i);
  389. end;
  390. end;
  391. procedure TList.SetCapacity(NewCapacity: Integer);
  392. Var NewList,ToFree : PPointerList;
  393. begin
  394. If (NewCapacity<0) or (NewCapacity>MaxListSize) then
  395. Error (SListCapacityError,NewCapacity);
  396. if NewCapacity=FCapacity then
  397. exit;
  398. ReallocMem(FList,SizeOf(Pointer)*NewCapacity);
  399. FCapacity:=NewCapacity;
  400. end;
  401. procedure TList.SetCount(NewCount: Integer);
  402. begin
  403. If (NewCount<0) or (NewCount>MaxListSize)then
  404. Error(SListCountError,NewCount);
  405. If NewCount<FCount then
  406. FCount:=NewCount
  407. else If NewCount>FCount then
  408. begin
  409. If NewCount>FCapacity then
  410. SetCapacity (NewCount);
  411. If FCount<NewCount then
  412. FillWord (Flist^[FCount],(NewCount-FCount)* WordRatio ,0);
  413. FCount:=Newcount;
  414. end;
  415. end;
  416. destructor TList.Destroy;
  417. begin
  418. Self.Clear;
  419. inherited Destroy;
  420. end;
  421. Function TList.Add(Item: Pointer): Integer;
  422. begin
  423. Self.Insert (Count,Item);
  424. Result:=Count-1;
  425. end;
  426. Procedure TList.Clear;
  427. begin
  428. If Assigned(FList) then
  429. begin
  430. FreeMem (Flist,FCapacity*SizeOf(Pointer));
  431. FList:=Nil;
  432. FCapacity:=0;
  433. FCount:=0;
  434. end;
  435. end;
  436. Procedure TList.Delete(Index: Integer);
  437. Var
  438. OldPointer :Pointer;
  439. begin
  440. If (Index<0) or (Index>=FCount) then
  441. Error (SListIndexError,Index);
  442. FCount:=FCount-1;
  443. OldPointer:=Flist^[Index];
  444. System.Move (FList^[Index+1],FList^[Index],(FCount-Index)*SizeOf(Pointer));
  445. // Shrink the list if appropiate
  446. if (FCapacity > 256) and (FCount < FCapacity shr 2) then
  447. begin
  448. FCapacity := FCapacity shr 1;
  449. ReallocMem(FList, SizeOf(Pointer) * FCapacity);
  450. end;
  451. end;
  452. class procedure TList.Error(const Msg: string; Data: Integer);
  453. var
  454. s:string;
  455. p:longint;
  456. begin
  457. p:=pos('%d',Msg);
  458. writeln(copy(Msg,1,pred(p)),Data,copy(Msg,p+3,255));
  459. end;
  460. procedure TList.Exchange(Index1, Index2: Integer);
  461. var Temp : Pointer;
  462. begin
  463. If ((Index1>=FCount) or (Index1<0)) then
  464. Error(SListIndexError,Index1);
  465. If ((Index2>=FCount) or (Index2<0)) then
  466. Error(SListIndexError,Index2);
  467. Temp:=FList^[Index1];
  468. FList^[Index1]:=FList^[Index2];
  469. FList^[Index2]:=Temp;
  470. end;
  471. function TList.Expand: TList;
  472. Var IncSize : Longint;
  473. begin
  474. if FCount<FCapacity then exit;
  475. IncSize:=4;
  476. if FCapacity>3 then IncSize:=IncSize+4;
  477. if FCapacity>8 then IncSize:=IncSize+8;
  478. if FCapacity>127 then Inc(IncSize, FCapacity shr 2);
  479. SetCapacity(FCapacity+IncSize);
  480. Result:=Self;
  481. end;
  482. function TList.First: Pointer;
  483. begin
  484. If FCount=0 then
  485. Result:=Nil
  486. else
  487. Result:=Items[0];
  488. end;
  489. function TList.IndexOf(Item: Pointer): Integer;
  490. begin
  491. Result:=0;
  492. While (Result<FCount) and (Flist^[Result]<>Item) do Result:=Result+1;
  493. If Result=FCount then Result:=-1;
  494. end;
  495. procedure TList.Insert(Index: Integer; Item: Pointer);
  496. begin
  497. If (Index<0) or (Index>FCount )then
  498. Error(SlistIndexError,Index);
  499. IF FCount=FCapacity Then Self.Expand;
  500. If Index<FCount then
  501. System.Move(Flist^[Index],Flist^[Index+1],(FCount-Index)*SizeOf(Pointer));
  502. FList^[Index]:=Item;
  503. FCount:=FCount+1;
  504. end;
  505. function TList.Last: Pointer;
  506. begin
  507. // Wouldn't it be better to return nil if the count is zero ?
  508. If FCount=0 then
  509. Result:=Nil
  510. else
  511. Result:=Items[FCount-1];
  512. end;
  513. procedure TList.Move(CurIndex, NewIndex: Integer);
  514. Var Temp : Pointer;
  515. begin
  516. If ((CurIndex<0) or (CurIndex>Count-1)) then
  517. Error(SListIndexError,CurIndex);
  518. If (NewINdex<0) then
  519. Error(SlistIndexError,NewIndex);
  520. Temp:=FList^[CurIndex];
  521. FList^[CurIndex]:=Nil;
  522. Self.Delete(CurIndex);
  523. // ?? If NewIndex>CurIndex then NewIndex:=NewIndex-1;
  524. // Newindex changes when deleting ??
  525. Self.Insert (NewIndex,Nil);
  526. FList^[NewIndex]:=Temp;
  527. end;
  528. function TList.Remove(Item: Pointer): Integer;
  529. begin
  530. Result:=IndexOf(Item);
  531. If Result<>-1 then
  532. Self.Delete (Result);
  533. end;
  534. Procedure TList.Pack;
  535. Var {Last,I,J,}Runner : Longint;
  536. begin
  537. // Not the fastest; but surely correct
  538. For Runner:=Fcount-1 downto 0 do
  539. if Items[Runner]=Nil then Self.Delete(Runner);
  540. { The following may be faster in case of large and defragmented lists
  541. If count=0 then exit;
  542. Runner:=0;I:=0;
  543. TheLast:=Count;
  544. while runner<count do
  545. begin
  546. // Find first Nil
  547. While (FList^[Runner]<>Nil) and (Runner<Count) do Runner:=Runner+1;
  548. if Runner<Count do
  549. begin
  550. // Start searching for non-nil from last known nil+1
  551. if i<Runner then I:=Runner+1;
  552. While (Flist[I]^=Nil) and (I<Count) do I:=I+1;
  553. // Start looking for last non-nil of block.
  554. J:=I+1;
  555. While (Flist^[J]<>Nil) and (J<Count) do J:=J+1;
  556. // Move block and zero out
  557. Move (Flist^[I],Flist^[Runner],J*SizeOf(Pointer));
  558. FillWord (Flist^[I],(J-I)*WordRatio,0);
  559. // Update Runner and Last to point behind last block
  560. TheLast:=Runner+(J-I);
  561. If J=Count then
  562. begin
  563. // Shortcut, when J=Count we checked all pointers
  564. Runner:=Count
  565. else
  566. begin
  567. Runner:=TheLast;
  568. I:=j;
  569. end;
  570. end;
  571. Count:=TheLast;
  572. }
  573. end;
  574. // Needed by Sort method.
  575. Procedure QuickSort (Flist : PPointerList; L,R : Longint;
  576. Compare : TListSortCompare);
  577. Var I,J : Longint;
  578. P,Q : Pointer;
  579. begin
  580. Repeat
  581. I:=L;
  582. J:=R;
  583. P:=FList^[ (L+R) div 2 ];
  584. repeat
  585. While Compare(P,FList^[i])>0 Do I:=I+1;
  586. While Compare(P,FList^[J])<0 Do J:=J-1;
  587. If I<=J then
  588. begin
  589. Q:=Flist^[I];
  590. Flist^[I]:=FList^[J];
  591. FList^[J]:=Q;
  592. I:=I+1;
  593. J:=j-1;
  594. end;
  595. Until I>J;
  596. If L<J then QuickSort (FList,L,J,Compare);
  597. L:=I;
  598. Until I>=R;
  599. end;
  600. procedure TList.Sort(Compare: TListSortCompare);
  601. begin
  602. If Not Assigned(FList) or (FCount<2) then exit;
  603. QuickSort (Flist, 0, FCount-1,Compare);
  604. end;
  605. procedure TList.Assign(Obj:TList);
  606. // Principle copied from TCollection
  607. var i : Integer;
  608. begin
  609. Clear;
  610. For I:=0 To Obj.Count-1 Do
  611. Add(Obj[i]);
  612. end;
  613. {****************************************************************************
  614. TLinkedListItem
  615. ****************************************************************************}
  616. constructor TLinkedListItem.Create;
  617. begin
  618. Previous:=nil;
  619. Next:=nil;
  620. end;
  621. destructor TLinkedListItem.Destroy;
  622. begin
  623. end;
  624. function TLinkedListItem.GetCopy:TLinkedListItem;
  625. var
  626. p : TLinkedListItem;
  627. l : integer;
  628. begin
  629. p:=TLinkedListItemClass(ClassType).Create;
  630. l:=InstanceSize;
  631. Move(pointer(self)^,pointer(p)^,l);
  632. Result:=p;
  633. end;
  634. {****************************************************************************
  635. TLinkedList
  636. ****************************************************************************}
  637. constructor TLinkedList.Create;
  638. begin
  639. FFirst:=nil;
  640. Flast:=nil;
  641. FCount:=0;
  642. FNoClear:=False;
  643. end;
  644. destructor TLinkedList.destroy;
  645. begin
  646. if not FNoClear then
  647. Clear;
  648. end;
  649. function TLinkedList.empty:boolean;
  650. begin
  651. Empty:=(FFirst=nil);
  652. end;
  653. procedure TLinkedList.Insert(Item:TLinkedListItem);
  654. begin
  655. if FFirst=nil then
  656. begin
  657. FLast:=Item;
  658. Item.Previous:=nil;
  659. Item.Next:=nil;
  660. end
  661. else
  662. begin
  663. FFirst.Previous:=Item;
  664. Item.Previous:=nil;
  665. Item.Next:=FFirst;
  666. end;
  667. FFirst:=Item;
  668. inc(FCount);
  669. end;
  670. procedure TLinkedList.InsertBefore(Item,Loc : TLinkedListItem);
  671. begin
  672. Item.Previous:=Loc.Previous;
  673. Item.Next:=Loc;
  674. Loc.Previous:=Item;
  675. if assigned(Item.Previous) then
  676. Item.Previous.Next:=Item
  677. else
  678. { if we've no next item, we've to adjust FFist }
  679. FFirst:=Item;
  680. inc(FCount);
  681. end;
  682. procedure TLinkedList.InsertAfter(Item,Loc : TLinkedListItem);
  683. begin
  684. Item.Next:=Loc.Next;
  685. Loc.Next:=Item;
  686. Item.Previous:=Loc;
  687. if assigned(Item.Next) then
  688. Item.Next.Previous:=Item
  689. else
  690. { if we've no next item, we've to adjust FLast }
  691. FLast:=Item;
  692. inc(FCount);
  693. end;
  694. procedure TLinkedList.Concat(Item:TLinkedListItem);
  695. begin
  696. if FFirst=nil then
  697. begin
  698. FFirst:=Item;
  699. Item.Previous:=nil;
  700. Item.Next:=nil;
  701. end
  702. else
  703. begin
  704. Flast.Next:=Item;
  705. Item.Previous:=Flast;
  706. Item.Next:=nil;
  707. end;
  708. Flast:=Item;
  709. inc(FCount);
  710. end;
  711. procedure TLinkedList.remove(Item:TLinkedListItem);
  712. begin
  713. if Item=nil then
  714. exit;
  715. if (FFirst=Item) and (Flast=Item) then
  716. begin
  717. FFirst:=nil;
  718. Flast:=nil;
  719. end
  720. else if FFirst=Item then
  721. begin
  722. FFirst:=Item.Next;
  723. if assigned(FFirst) then
  724. FFirst.Previous:=nil;
  725. end
  726. else if Flast=Item then
  727. begin
  728. Flast:=Flast.Previous;
  729. if assigned(Flast) then
  730. Flast.Next:=nil;
  731. end
  732. else
  733. begin
  734. Item.Previous.Next:=Item.Next;
  735. Item.Next.Previous:=Item.Previous;
  736. end;
  737. Item.Next:=nil;
  738. Item.Previous:=nil;
  739. dec(FCount);
  740. end;
  741. procedure TLinkedList.clear;
  742. var
  743. NewNode : TLinkedListItem;
  744. begin
  745. NewNode:=FFirst;
  746. while assigned(NewNode) do
  747. begin
  748. FFirst:=NewNode.Next;
  749. NewNode.Free;
  750. NewNode:=FFirst;
  751. end;
  752. FLast:=nil;
  753. FFirst:=nil;
  754. FCount:=0;
  755. end;
  756. function TLinkedList.GetFirst:TLinkedListItem;
  757. begin
  758. if FFirst=nil then
  759. GetFirst:=nil
  760. else
  761. begin
  762. GetFirst:=FFirst;
  763. if FFirst=FLast then
  764. FLast:=nil;
  765. FFirst:=FFirst.Next;
  766. dec(FCount);
  767. end;
  768. end;
  769. function TLinkedList.GetLast:TLinkedListItem;
  770. begin
  771. if FLast=nil then
  772. Getlast:=nil
  773. else
  774. begin
  775. Getlast:=FLast;
  776. if FLast=FFirst then
  777. FFirst:=nil;
  778. FLast:=FLast.Previous;
  779. dec(FCount);
  780. end;
  781. end;
  782. procedure TLinkedList.insertList(p : TLinkedList);
  783. begin
  784. { empty List ? }
  785. if (p.FFirst=nil) then
  786. exit;
  787. p.Flast.Next:=FFirst;
  788. { we have a double Linked List }
  789. if assigned(FFirst) then
  790. FFirst.Previous:=p.Flast;
  791. FFirst:=p.FFirst;
  792. if (FLast=nil) then
  793. Flast:=p.Flast;
  794. inc(FCount,p.FCount);
  795. { p becomes empty }
  796. p.FFirst:=nil;
  797. p.Flast:=nil;
  798. p.FCount:=0;
  799. end;
  800. procedure TLinkedList.insertListAfter(Item:TLinkedListItem;p : TLinkedList);
  801. begin
  802. { empty List ? }
  803. if (p.FFirst=nil) then
  804. exit;
  805. if (Item=nil) then
  806. begin
  807. { Insert at begin }
  808. InsertList(p);
  809. exit;
  810. end
  811. else
  812. begin
  813. p.FFirst.Previous:=Item;
  814. p.FLast.Next:=Item.Next;
  815. if assigned(Item.Next) then
  816. Item.Next.Previous:=p.FLast
  817. else
  818. FLast:=p.FLast;
  819. Item.Next:=p.FFirst;
  820. inc(FCount,p.FCount);
  821. end;
  822. { p becomes empty }
  823. p.FFirst:=nil;
  824. p.Flast:=nil;
  825. p.FCount:=0;
  826. end;
  827. procedure TLinkedList.concatList(p : TLinkedList);
  828. begin
  829. if (p.FFirst=nil) then
  830. exit;
  831. if FFirst=nil then
  832. FFirst:=p.FFirst
  833. else
  834. begin
  835. FLast.Next:=p.FFirst;
  836. p.FFirst.Previous:=Flast;
  837. end;
  838. Flast:=p.Flast;
  839. inc(FCount,p.FCount);
  840. { make p empty }
  841. p.Flast:=nil;
  842. p.FFirst:=nil;
  843. p.FCount:=0;
  844. end;
  845. procedure TLinkedList.insertListcopy(p : TLinkedList);
  846. var
  847. NewNode,NewNode2 : TLinkedListItem;
  848. begin
  849. NewNode:=p.First;
  850. while assigned(NewNode) do
  851. begin
  852. NewNode2:=NewNode.Getcopy;
  853. if assigned(NewNode2) then
  854. Insert(NewNode2);
  855. NewNode:=NewNode.Next;
  856. end;
  857. end;
  858. procedure TLinkedList.concatListcopy(p : TLinkedList);
  859. var
  860. NewNode,NewNode2 : TLinkedListItem;
  861. begin
  862. NewNode:=p.First;
  863. while assigned(NewNode) do
  864. begin
  865. NewNode2:=NewNode.Getcopy;
  866. if assigned(NewNode2) then
  867. Concat(NewNode2);
  868. NewNode:=NewNode.Next;
  869. end;
  870. end;
  871. {****************************************************************************
  872. TStringListItem
  873. ****************************************************************************}
  874. constructor TStringListItem.Create(const s:string);
  875. begin
  876. inherited Create;
  877. FPStr:=stringdup(s);
  878. end;
  879. destructor TStringListItem.Destroy;
  880. begin
  881. stringdispose(FPStr);
  882. end;
  883. function TStringListItem.Str:string;
  884. begin
  885. Str:=FPStr^;
  886. end;
  887. function TStringListItem.GetCopy:TLinkedListItem;
  888. begin
  889. Result:=(inherited GetCopy);
  890. TStringListItem(Result).FPStr:=stringdup(FPstr^);
  891. end;
  892. {****************************************************************************
  893. TSTRINGList
  894. ****************************************************************************}
  895. constructor tstringList.Create;
  896. begin
  897. inherited Create;
  898. FDoubles:=true;
  899. end;
  900. constructor tstringList.Create_no_double;
  901. begin
  902. inherited Create;
  903. FDoubles:=false;
  904. end;
  905. procedure tstringList.insert(const s : string);
  906. begin
  907. if (s='') or
  908. ((not FDoubles) and (find(s)<>nil)) then
  909. exit;
  910. inherited insert(tstringListItem.create(s));
  911. end;
  912. procedure tstringList.concat(const s : string);
  913. begin
  914. if (s='') or
  915. ((not FDoubles) and (find(s)<>nil)) then
  916. exit;
  917. inherited concat(tstringListItem.create(s));
  918. end;
  919. procedure tstringList.remove(const s : string);
  920. var
  921. p : tstringListItem;
  922. begin
  923. if s='' then
  924. exit;
  925. p:=find(s);
  926. if assigned(p) then
  927. begin
  928. inherited Remove(p);
  929. p.Free;
  930. end;
  931. end;
  932. function tstringList.GetFirst : string;
  933. var
  934. p : tstringListItem;
  935. begin
  936. p:=tstringListItem(inherited GetFirst);
  937. if p=nil then
  938. GetFirst:=''
  939. else
  940. begin
  941. GetFirst:=p.FPStr^;
  942. p.free;
  943. end;
  944. end;
  945. function tstringList.Getlast : string;
  946. var
  947. p : tstringListItem;
  948. begin
  949. p:=tstringListItem(inherited Getlast);
  950. if p=nil then
  951. Getlast:=''
  952. else
  953. begin
  954. Getlast:=p.FPStr^;
  955. p.free;
  956. end;
  957. end;
  958. function tstringList.find(const s:string):TstringListItem;
  959. var
  960. NewNode : tstringListItem;
  961. begin
  962. find:=nil;
  963. if s='' then
  964. exit;
  965. NewNode:=tstringListItem(FFirst);
  966. while assigned(NewNode) do
  967. begin
  968. if NewNode.FPStr^=s then
  969. begin
  970. find:=NewNode;
  971. exit;
  972. end;
  973. NewNode:=tstringListItem(NewNode.Next);
  974. end;
  975. end;
  976. procedure TStringList.InsertItem(item:TStringListItem);
  977. begin
  978. inherited Insert(item);
  979. end;
  980. procedure TStringList.ConcatItem(item:TStringListItem);
  981. begin
  982. inherited Concat(item);
  983. end;
  984. {****************************************************************************
  985. TNamedIndexItem
  986. ****************************************************************************}
  987. constructor TNamedIndexItem.Create;
  988. begin
  989. { index }
  990. Findexnr:=-1;
  991. FindexNext:=nil;
  992. { dictionary }
  993. Fleft:=nil;
  994. Fright:=nil;
  995. FName:=nil;
  996. Fspeedvalue:=cardinal($ffffffff);
  997. { List }
  998. FListNext:=nil;
  999. end;
  1000. constructor TNamedIndexItem.Createname(const n:string);
  1001. begin
  1002. { index }
  1003. Findexnr:=-1;
  1004. FindexNext:=nil;
  1005. { dictionary }
  1006. Fleft:=nil;
  1007. Fright:=nil;
  1008. fspeedvalue:=getspeedvalue(n);
  1009. {$ifdef compress}
  1010. FName:=stringdup(minilzw_encode(n));
  1011. {$else}
  1012. FName:=stringdup(n);
  1013. {$endif}
  1014. { List }
  1015. FListNext:=nil;
  1016. end;
  1017. destructor TNamedIndexItem.destroy;
  1018. begin
  1019. stringdispose(FName);
  1020. end;
  1021. procedure TNamedIndexItem.setname(const n:string);
  1022. begin
  1023. if assigned(FName) then
  1024. stringdispose(FName);
  1025. fspeedvalue:=getspeedvalue(n);
  1026. {$ifdef compress}
  1027. FName:=stringdup(minilzw_encode(n));
  1028. {$else}
  1029. FName:=stringdup(n);
  1030. {$endif}
  1031. end;
  1032. function TNamedIndexItem.GetName:string;
  1033. begin
  1034. if assigned(FName) then
  1035. {$ifdef compress}
  1036. Getname:=minilzw_decode(FName^)
  1037. {$else}
  1038. Getname:=FName^
  1039. {$endif}
  1040. else
  1041. Getname:='';
  1042. end;
  1043. {****************************************************************************
  1044. TDICTIONARY
  1045. ****************************************************************************}
  1046. constructor Tdictionary.Create;
  1047. begin
  1048. FRoot:=nil;
  1049. FHashArray:=nil;
  1050. noclear:=false;
  1051. delete_doubles:=false;
  1052. end;
  1053. procedure Tdictionary.usehash;
  1054. begin
  1055. if not(assigned(FRoot)) and
  1056. not(assigned(FHashArray)) then
  1057. begin
  1058. New(FHashArray);
  1059. fillchar(FHashArray^,sizeof(FHashArray^),0);
  1060. end;
  1061. end;
  1062. function counttree(p: tnamedindexitem): longint;
  1063. begin
  1064. counttree:=0;
  1065. if not assigned(p) then
  1066. exit;
  1067. result := 1;
  1068. inc(result,counttree(p.fleft));
  1069. inc(result,counttree(p.fright));
  1070. end;
  1071. destructor Tdictionary.destroy;
  1072. begin
  1073. if not noclear then
  1074. clear;
  1075. if assigned(FHashArray) then
  1076. begin
  1077. dispose(FHashArray);
  1078. end;
  1079. end;
  1080. procedure Tdictionary.cleartree(var obj:TNamedIndexItem);
  1081. begin
  1082. if assigned(obj.Fleft) then
  1083. cleartree(obj.FLeft);
  1084. if assigned(obj.FRight) then
  1085. cleartree(obj.FRight);
  1086. obj.free;
  1087. obj:=nil;
  1088. end;
  1089. procedure Tdictionary.clear;
  1090. var
  1091. w : integer;
  1092. begin
  1093. if assigned(FRoot) then
  1094. cleartree(FRoot);
  1095. if assigned(FHashArray) then
  1096. for w:= low(FHashArray^) to high(FHashArray^) do
  1097. if assigned(FHashArray^[w]) then
  1098. cleartree(FHashArray^[w]);
  1099. end;
  1100. function Tdictionary.delete(const s:string):TNamedIndexItem;
  1101. var
  1102. p,SpeedValue : cardinal;
  1103. n : TNamedIndexItem;
  1104. {$ifdef compress}
  1105. senc:string;
  1106. {$else}
  1107. senc:string absolute s;
  1108. {$endif}
  1109. procedure insert_right_bottom(var root,Atree:TNamedIndexItem);
  1110. begin
  1111. while root.FRight<>nil do
  1112. root:=root.FRight;
  1113. root.FRight:=Atree;
  1114. end;
  1115. function delete_from_tree(root:TNamedIndexItem):TNamedIndexItem;
  1116. type
  1117. leftright=(left,right);
  1118. var
  1119. lr : leftright;
  1120. oldroot : TNamedIndexItem;
  1121. begin
  1122. oldroot:=nil;
  1123. while (root<>nil) and (root.SpeedValue<>SpeedValue) do
  1124. begin
  1125. oldroot:=root;
  1126. if SpeedValue<root.SpeedValue then
  1127. begin
  1128. root:=root.FRight;
  1129. lr:=right;
  1130. end
  1131. else
  1132. begin
  1133. root:=root.FLeft;
  1134. lr:=left;
  1135. end;
  1136. end;
  1137. while (root<>nil) and (root.FName^<>senc) do
  1138. begin
  1139. oldroot:=root;
  1140. if senc<root.FName^ then
  1141. begin
  1142. root:=root.FRight;
  1143. lr:=right;
  1144. end
  1145. else
  1146. begin
  1147. root:=root.FLeft;
  1148. lr:=left;
  1149. end;
  1150. end;
  1151. if root<>nil then
  1152. begin
  1153. dec(FCount);
  1154. if root.FLeft<>nil then
  1155. begin
  1156. { Now the Node pointing to root must point to the left
  1157. subtree of root. The right subtree of root must be
  1158. connected to the right bottom of the left subtree.}
  1159. if lr=left then
  1160. oldroot.FLeft:=root.FLeft
  1161. else
  1162. oldroot.FRight:=root.FLeft;
  1163. if root.FRight<>nil then
  1164. insert_right_bottom(root.FLeft,root.FRight);
  1165. end
  1166. else
  1167. begin
  1168. { There is no left subtree. So we can just replace the Node to
  1169. delete with the right subtree.}
  1170. if lr=left then
  1171. oldroot.FLeft:=root.FRight
  1172. else
  1173. oldroot.FRight:=root.FRight;
  1174. end;
  1175. end;
  1176. delete_from_tree:=root;
  1177. end;
  1178. begin
  1179. {$ifdef compress}
  1180. senc:=minilzw_encode(s);
  1181. {$endif}
  1182. SpeedValue:=GetSpeedValue(s);
  1183. n:=FRoot;
  1184. if assigned(FHashArray) then
  1185. begin
  1186. { First, check if the Node to delete directly located under
  1187. the hasharray.}
  1188. p:=SpeedValue mod hasharraysize;
  1189. n:=FHashArray^[p];
  1190. if (n<>nil) and (n.SpeedValue=SpeedValue) and
  1191. (n.FName^=senc) then
  1192. begin
  1193. { The Node to delete is directly located under the
  1194. hasharray. Make the hasharray point to the left
  1195. subtree of the Node and place the right subtree on
  1196. the right-bottom of the left subtree.}
  1197. if n.FLeft<>nil then
  1198. begin
  1199. FHashArray^[p]:=n.FLeft;
  1200. if n.FRight<>nil then
  1201. insert_right_bottom(n.FLeft,n.FRight);
  1202. end
  1203. else
  1204. FHashArray^[p]:=n.FRight;
  1205. delete:=n;
  1206. dec(FCount);
  1207. exit;
  1208. end;
  1209. end
  1210. else
  1211. begin
  1212. { First check if the Node to delete is the root.}
  1213. if (FRoot<>nil) and (n.SpeedValue=SpeedValue) and
  1214. (n.FName^=senc) then
  1215. begin
  1216. if n.FLeft<>nil then
  1217. begin
  1218. FRoot:=n.FLeft;
  1219. if n.FRight<>nil then
  1220. insert_right_bottom(n.FLeft,n.FRight);
  1221. end
  1222. else
  1223. FRoot:=n.FRight;
  1224. delete:=n;
  1225. dec(FCount);
  1226. exit;
  1227. end;
  1228. end;
  1229. delete:=delete_from_tree(n);
  1230. end;
  1231. function Tdictionary.empty:boolean;
  1232. var
  1233. w : integer;
  1234. begin
  1235. if assigned(FHashArray) then
  1236. begin
  1237. empty:=false;
  1238. for w:=low(FHashArray^) to high(FHashArray^) do
  1239. if assigned(FHashArray^[w]) then
  1240. exit;
  1241. empty:=true;
  1242. end
  1243. else
  1244. empty:=(FRoot=nil);
  1245. end;
  1246. procedure Tdictionary.foreach(proc2call:TNamedIndexcallback;arg:pointer);
  1247. procedure a(p:TNamedIndexItem;arg:pointer);
  1248. begin
  1249. proc2call(p,arg);
  1250. if assigned(p.FLeft) then
  1251. a(p.FLeft,arg);
  1252. if assigned(p.FRight) then
  1253. a(p.FRight,arg);
  1254. end;
  1255. var
  1256. i : integer;
  1257. begin
  1258. if assigned(FHashArray) then
  1259. begin
  1260. for i:=low(FHashArray^) to high(FHashArray^) do
  1261. if assigned(FHashArray^[i]) then
  1262. a(FHashArray^[i],arg);
  1263. end
  1264. else
  1265. if assigned(FRoot) then
  1266. a(FRoot,arg);
  1267. end;
  1268. procedure Tdictionary.foreach_static(proc2call:TNamedIndexStaticCallback;arg:pointer);
  1269. procedure a(p:TNamedIndexItem;arg:pointer);
  1270. begin
  1271. proc2call(p,arg);
  1272. if assigned(p.FLeft) then
  1273. a(p.FLeft,arg);
  1274. if assigned(p.FRight) then
  1275. a(p.FRight,arg);
  1276. end;
  1277. var
  1278. i : integer;
  1279. begin
  1280. if assigned(FHashArray) then
  1281. begin
  1282. for i:=low(FHashArray^) to high(FHashArray^) do
  1283. if assigned(FHashArray^[i]) then
  1284. a(FHashArray^[i],arg);
  1285. end
  1286. else
  1287. if assigned(FRoot) then
  1288. a(FRoot,arg);
  1289. end;
  1290. function Tdictionary.replace(oldobj,newobj:TNamedIndexItem):boolean;
  1291. var
  1292. hp : TNamedIndexItem;
  1293. begin
  1294. hp:=nil;
  1295. Replace:=false;
  1296. { must be the same name and hash }
  1297. if (oldobj.FSpeedValue<>newobj.FSpeedValue) or
  1298. (oldobj.FName^<>newobj.FName^) then
  1299. exit;
  1300. { copy tree info }
  1301. newobj.FLeft:=oldobj.FLeft;
  1302. newobj.FRight:=oldobj.FRight;
  1303. { update treeroot }
  1304. if assigned(FHashArray) then
  1305. begin
  1306. hp:=FHashArray^[newobj.FSpeedValue mod hasharraysize];
  1307. if hp=oldobj then
  1308. begin
  1309. FHashArray^[newobj.FSpeedValue mod hasharraysize]:=newobj;
  1310. hp:=nil;
  1311. end;
  1312. end
  1313. else
  1314. begin
  1315. hp:=FRoot;
  1316. if hp=oldobj then
  1317. begin
  1318. FRoot:=newobj;
  1319. hp:=nil;
  1320. end;
  1321. end;
  1322. { update parent entry }
  1323. while assigned(hp) do
  1324. begin
  1325. { is the node to replace the left or right, then
  1326. update this node and stop }
  1327. if hp.FLeft=oldobj then
  1328. begin
  1329. hp.FLeft:=newobj;
  1330. break;
  1331. end;
  1332. if hp.FRight=oldobj then
  1333. begin
  1334. hp.FRight:=newobj;
  1335. break;
  1336. end;
  1337. { First check SpeedValue, to allow a fast insert }
  1338. if hp.SpeedValue>oldobj.SpeedValue then
  1339. hp:=hp.FRight
  1340. else
  1341. if hp.SpeedValue<oldobj.SpeedValue then
  1342. hp:=hp.FLeft
  1343. else
  1344. begin
  1345. if (hp.FName^=oldobj.FName^) then
  1346. begin
  1347. { this can never happend, return error }
  1348. exit;
  1349. end
  1350. else
  1351. if oldobj.FName^>hp.FName^ then
  1352. hp:=hp.FLeft
  1353. else
  1354. hp:=hp.FRight;
  1355. end;
  1356. end;
  1357. Replace:=true;
  1358. end;
  1359. function Tdictionary.insert(obj:TNamedIndexItem):TNamedIndexItem;
  1360. begin
  1361. inc(FCount);
  1362. if assigned(FHashArray) then
  1363. insert:=insertNode(obj,FHashArray^[obj.SpeedValue mod hasharraysize])
  1364. else
  1365. insert:=insertNode(obj,FRoot);
  1366. end;
  1367. function tdictionary.insertNode(NewNode:TNamedIndexItem;var currNode:TNamedIndexItem):TNamedIndexItem;
  1368. begin
  1369. if currNode=nil then
  1370. begin
  1371. currNode:=NewNode;
  1372. insertNode:=NewNode;
  1373. end
  1374. { First check SpeedValue, to allow a fast insert }
  1375. else
  1376. if currNode.SpeedValue>NewNode.SpeedValue then
  1377. insertNode:=insertNode(NewNode,currNode.FRight)
  1378. else
  1379. if currNode.SpeedValue<NewNode.SpeedValue then
  1380. insertNode:=insertNode(NewNode,currNode.FLeft)
  1381. else
  1382. begin
  1383. if currNode.FName^>NewNode.FName^ then
  1384. insertNode:=insertNode(NewNode,currNode.FRight)
  1385. else
  1386. if currNode.FName^<NewNode.FName^ then
  1387. insertNode:=insertNode(NewNode,currNode.FLeft)
  1388. else
  1389. begin
  1390. if (delete_doubles) and
  1391. assigned(currNode) then
  1392. begin
  1393. NewNode.FLeft:=currNode.FLeft;
  1394. NewNode.FRight:=currNode.FRight;
  1395. if delete_doubles then
  1396. begin
  1397. currnode.FLeft:=nil;
  1398. currnode.FRight:=nil;
  1399. currnode.free;
  1400. end;
  1401. currNode:=NewNode;
  1402. insertNode:=NewNode;
  1403. end
  1404. else
  1405. insertNode:=currNode;
  1406. end;
  1407. end;
  1408. end;
  1409. procedure tdictionary.inserttree(currtree,currroot:TNamedIndexItem);
  1410. begin
  1411. if assigned(currtree) then
  1412. begin
  1413. inserttree(currtree.FLeft,currroot);
  1414. inserttree(currtree.FRight,currroot);
  1415. currtree.FRight:=nil;
  1416. currtree.FLeft:=nil;
  1417. insertNode(currtree,currroot);
  1418. end;
  1419. end;
  1420. function tdictionary.rename(const olds,News : string):TNamedIndexItem;
  1421. var
  1422. spdval : cardinal;
  1423. lasthp,
  1424. hp,hp2,hp3 : TNamedIndexItem;
  1425. {$ifdef compress}
  1426. oldsenc,newsenc:string;
  1427. {$else}
  1428. oldsenc:string absolute olds;
  1429. newsenc:string absolute news;
  1430. {$endif}
  1431. begin
  1432. {$ifdef compress}
  1433. oldsenc:=minilzw_encode(olds);
  1434. newsenc:=minilzw_encode(news);
  1435. {$endif}
  1436. spdval:=GetSpeedValue(olds);
  1437. if assigned(FHashArray) then
  1438. hp:=FHashArray^[spdval mod hasharraysize]
  1439. else
  1440. hp:=FRoot;
  1441. lasthp:=nil;
  1442. while assigned(hp) do
  1443. begin
  1444. if spdval>hp.SpeedValue then
  1445. begin
  1446. lasthp:=hp;
  1447. hp:=hp.FLeft
  1448. end
  1449. else
  1450. if spdval<hp.SpeedValue then
  1451. begin
  1452. lasthp:=hp;
  1453. hp:=hp.FRight
  1454. end
  1455. else
  1456. begin
  1457. if (hp.FName^=oldsenc) then
  1458. begin
  1459. { Get in hp2 the replacer for the root or hasharr }
  1460. hp2:=hp.FLeft;
  1461. hp3:=hp.FRight;
  1462. if not assigned(hp2) then
  1463. begin
  1464. hp2:=hp.FRight;
  1465. hp3:=hp.FLeft;
  1466. end;
  1467. { remove entry from the tree }
  1468. if assigned(lasthp) then
  1469. begin
  1470. if lasthp.FLeft=hp then
  1471. lasthp.FLeft:=hp2
  1472. else
  1473. lasthp.FRight:=hp2;
  1474. end
  1475. else
  1476. begin
  1477. if assigned(FHashArray) then
  1478. FHashArray^[spdval mod hasharraysize]:=hp2
  1479. else
  1480. FRoot:=hp2;
  1481. end;
  1482. { reinsert the hp3 in the tree from hp2 }
  1483. inserttree(hp3,hp2);
  1484. { reset Node with New values }
  1485. hp.FLeft:=nil;
  1486. hp.FRight:=nil;
  1487. stringdispose(hp.FName);
  1488. hp.FName:=stringdup(newsenc);
  1489. hp.FSpeedValue:=GetSpeedValue(news);
  1490. { reinsert }
  1491. if assigned(FHashArray) then
  1492. rename:=insertNode(hp,FHashArray^[hp.SpeedValue mod hasharraysize])
  1493. else
  1494. rename:=insertNode(hp,FRoot);
  1495. exit;
  1496. end
  1497. else
  1498. if oldsenc>hp.FName^ then
  1499. begin
  1500. lasthp:=hp;
  1501. hp:=hp.FLeft
  1502. end
  1503. else
  1504. begin
  1505. lasthp:=hp;
  1506. hp:=hp.FRight;
  1507. end;
  1508. end;
  1509. end;
  1510. result := nil;
  1511. end;
  1512. function Tdictionary.search(const s:string):TNamedIndexItem;
  1513. var t:string;
  1514. begin
  1515. search:=speedsearch(s,getspeedvalue(s));
  1516. end;
  1517. function Tdictionary.speedsearch(const s:string;SpeedValue:cardinal):TNamedIndexItem;
  1518. var
  1519. NewNode:TNamedIndexItem;
  1520. {$ifdef compress}
  1521. decn:string;
  1522. {$endif}
  1523. begin
  1524. if assigned(FHashArray) then
  1525. NewNode:=FHashArray^[SpeedValue mod hasharraysize]
  1526. else
  1527. NewNode:=FRoot;
  1528. while assigned(NewNode) do
  1529. begin
  1530. if SpeedValue>NewNode.SpeedValue then
  1531. NewNode:=NewNode.FLeft
  1532. else
  1533. if SpeedValue<NewNode.SpeedValue then
  1534. NewNode:=NewNode.FRight
  1535. else
  1536. begin
  1537. {$ifdef compress}
  1538. decn:=minilzw_decode(newnode.fname^);
  1539. if (decn=s) then
  1540. begin
  1541. speedsearch:=NewNode;
  1542. exit;
  1543. end
  1544. else
  1545. if s>decn then
  1546. NewNode:=NewNode.FLeft
  1547. else
  1548. NewNode:=NewNode.FRight;
  1549. {$else}
  1550. if (NewNode.FName^=s) then
  1551. begin
  1552. speedsearch:=NewNode;
  1553. exit;
  1554. end
  1555. else
  1556. if s>NewNode.FName^ then
  1557. NewNode:=NewNode.FLeft
  1558. else
  1559. NewNode:=NewNode.FRight;
  1560. {$endif}
  1561. end;
  1562. end;
  1563. speedsearch:=nil;
  1564. end;
  1565. {****************************************************************************
  1566. tsingleList
  1567. ****************************************************************************}
  1568. constructor tsingleList.create;
  1569. begin
  1570. First:=nil;
  1571. last:=nil;
  1572. end;
  1573. procedure tsingleList.reset;
  1574. begin
  1575. First:=nil;
  1576. last:=nil;
  1577. end;
  1578. procedure tsingleList.clear;
  1579. var
  1580. hp,hp2 : TNamedIndexItem;
  1581. begin
  1582. hp:=First;
  1583. while assigned(hp) do
  1584. begin
  1585. hp2:=hp;
  1586. hp:=hp.FListNext;
  1587. hp2.free;
  1588. end;
  1589. First:=nil;
  1590. last:=nil;
  1591. end;
  1592. procedure tsingleList.insert(p:TNamedIndexItem);
  1593. begin
  1594. if not assigned(First) then
  1595. First:=p
  1596. else
  1597. last.FListNext:=p;
  1598. last:=p;
  1599. p.FListNext:=nil;
  1600. end;
  1601. {****************************************************************************
  1602. tindexarray
  1603. ****************************************************************************}
  1604. constructor tindexarray.create(Agrowsize:integer);
  1605. begin
  1606. growsize:=Agrowsize;
  1607. size:=0;
  1608. count:=0;
  1609. data:=nil;
  1610. First:=nil;
  1611. noclear:=false;
  1612. end;
  1613. destructor tindexarray.destroy;
  1614. begin
  1615. if assigned(data) then
  1616. begin
  1617. if not noclear then
  1618. clear;
  1619. freemem(data);
  1620. data:=nil;
  1621. end;
  1622. end;
  1623. function tindexarray.search(nr:integer):TNamedIndexItem;
  1624. begin
  1625. if nr<=count then
  1626. search:=data^[nr]
  1627. else
  1628. search:=nil;
  1629. end;
  1630. procedure tindexarray.clear;
  1631. var
  1632. i : integer;
  1633. begin
  1634. for i:=1 to count do
  1635. if assigned(data^[i]) then
  1636. begin
  1637. data^[i].free;
  1638. data^[i]:=nil;
  1639. end;
  1640. count:=0;
  1641. First:=nil;
  1642. end;
  1643. procedure tindexarray.foreach(proc2call : Tnamedindexcallback;arg:pointer);
  1644. var
  1645. i : integer;
  1646. begin
  1647. for i:=1 to count do
  1648. if assigned(data^[i]) then
  1649. proc2call(data^[i],arg);
  1650. end;
  1651. procedure tindexarray.foreach_static(proc2call : Tnamedindexstaticcallback;arg:pointer);
  1652. var
  1653. i : integer;
  1654. begin
  1655. for i:=1 to count do
  1656. if assigned(data^[i]) then
  1657. proc2call(data^[i],arg);
  1658. end;
  1659. procedure tindexarray.grow(gsize:integer);
  1660. var
  1661. osize : integer;
  1662. begin
  1663. osize:=size;
  1664. inc(size,gsize);
  1665. reallocmem(data,size*sizeof(pointer));
  1666. fillchar(data^[osize+1],gsize*sizeof(pointer),0);
  1667. end;
  1668. procedure tindexarray.deleteindex(p:TNamedIndexItem);
  1669. var
  1670. i : integer;
  1671. begin
  1672. i:=p.Findexnr;
  1673. { update counter }
  1674. if i=count then
  1675. dec(count);
  1676. { update Linked List }
  1677. while (i>0) do
  1678. begin
  1679. dec(i);
  1680. if (i>0) and assigned(data^[i]) then
  1681. begin
  1682. data^[i].FindexNext:=data^[p.Findexnr].FindexNext;
  1683. break;
  1684. end;
  1685. end;
  1686. if i=0 then
  1687. First:=p.FindexNext;
  1688. data^[p.FIndexnr]:=nil;
  1689. { clear entry }
  1690. p.FIndexnr:=-1;
  1691. p.FIndexNext:=nil;
  1692. end;
  1693. procedure tindexarray.delete(var p:TNamedIndexItem);
  1694. begin
  1695. deleteindex(p);
  1696. p.free;
  1697. p:=nil;
  1698. end;
  1699. procedure tindexarray.insert(p:TNamedIndexItem);
  1700. var
  1701. i : integer;
  1702. begin
  1703. if p.FIndexnr=-1 then
  1704. begin
  1705. inc(count);
  1706. p.FIndexnr:=count;
  1707. end;
  1708. if p.FIndexnr>count then
  1709. count:=p.FIndexnr;
  1710. if count>size then
  1711. grow(((count div growsize)+1)*growsize);
  1712. Assert(not assigned(data^[p.FIndexnr]) or (p=data^[p.FIndexnr]));
  1713. data^[p.FIndexnr]:=p;
  1714. { update Linked List backward }
  1715. i:=p.FIndexnr;
  1716. while (i>0) do
  1717. begin
  1718. dec(i);
  1719. if (i>0) and assigned(data^[i]) then
  1720. begin
  1721. data^[i].FIndexNext:=p;
  1722. break;
  1723. end;
  1724. end;
  1725. if i=0 then
  1726. First:=p;
  1727. { update Linked List forward }
  1728. i:=p.FIndexnr;
  1729. while (i<=count) do
  1730. begin
  1731. inc(i);
  1732. if (i<=count) and assigned(data^[i]) then
  1733. begin
  1734. p.FIndexNext:=data^[i];
  1735. exit;
  1736. end;
  1737. end;
  1738. if i>count then
  1739. p.FIndexNext:=nil;
  1740. end;
  1741. procedure tindexarray.replace(oldp,newp:TNamedIndexItem);
  1742. var
  1743. i : integer;
  1744. begin
  1745. newp.FIndexnr:=oldp.FIndexnr;
  1746. newp.FIndexNext:=oldp.FIndexNext;
  1747. data^[newp.FIndexnr]:=newp;
  1748. if First=oldp then
  1749. First:=newp;
  1750. { update Linked List backward }
  1751. i:=newp.FIndexnr;
  1752. while (i>0) do
  1753. begin
  1754. dec(i);
  1755. if (i>0) and assigned(data^[i]) then
  1756. begin
  1757. data^[i].FIndexNext:=newp;
  1758. break;
  1759. end;
  1760. end;
  1761. end;
  1762. {****************************************************************************
  1763. tdynamicarray
  1764. ****************************************************************************}
  1765. constructor tdynamicarray.create(Ablocksize:integer);
  1766. begin
  1767. FPosn:=0;
  1768. FPosnblock:=nil;
  1769. FFirstblock:=nil;
  1770. FLastblock:=nil;
  1771. Fblocksize:=Ablocksize;
  1772. grow;
  1773. end;
  1774. destructor tdynamicarray.destroy;
  1775. var
  1776. hp : pdynamicblock;
  1777. begin
  1778. while assigned(FFirstblock) do
  1779. begin
  1780. hp:=FFirstblock;
  1781. FFirstblock:=FFirstblock^.Next;
  1782. Freemem(hp);
  1783. end;
  1784. end;
  1785. function tdynamicarray.size:integer;
  1786. begin
  1787. if assigned(FLastblock) then
  1788. size:=FLastblock^.pos+FLastblock^.used
  1789. else
  1790. size:=0;
  1791. end;
  1792. procedure tdynamicarray.reset;
  1793. var
  1794. hp : pdynamicblock;
  1795. begin
  1796. while assigned(FFirstblock) do
  1797. begin
  1798. hp:=FFirstblock;
  1799. FFirstblock:=FFirstblock^.Next;
  1800. Freemem(hp);
  1801. end;
  1802. FPosn:=0;
  1803. FPosnblock:=nil;
  1804. FFirstblock:=nil;
  1805. FLastblock:=nil;
  1806. grow;
  1807. end;
  1808. procedure tdynamicarray.grow;
  1809. var
  1810. nblock : pdynamicblock;
  1811. begin
  1812. Getmem(nblock,blocksize+dynamicblockbasesize);
  1813. if not assigned(FFirstblock) then
  1814. begin
  1815. FFirstblock:=nblock;
  1816. FPosnblock:=nblock;
  1817. nblock^.pos:=0;
  1818. end
  1819. else
  1820. begin
  1821. FLastblock^.Next:=nblock;
  1822. nblock^.pos:=FLastblock^.pos+FLastblock^.used;
  1823. end;
  1824. nblock^.used:=0;
  1825. nblock^.Next:=nil;
  1826. fillchar(nblock^.data,blocksize,0);
  1827. FLastblock:=nblock;
  1828. end;
  1829. procedure tdynamicarray.align(i:integer);
  1830. var
  1831. j : integer;
  1832. begin
  1833. j:=(FPosn mod i);
  1834. if j<>0 then
  1835. begin
  1836. j:=i-j;
  1837. if FPosnblock^.used+j>blocksize then
  1838. begin
  1839. dec(j,blocksize-FPosnblock^.used);
  1840. FPosnblock^.used:=blocksize;
  1841. grow;
  1842. FPosnblock:=FLastblock;
  1843. end;
  1844. inc(FPosnblock^.used,j);
  1845. inc(FPosn,j);
  1846. end;
  1847. end;
  1848. procedure tdynamicarray.seek(i:integer);
  1849. begin
  1850. if (i<FPosnblock^.pos) or (i>=FPosnblock^.pos+blocksize) then
  1851. begin
  1852. { set FPosnblock correct if the size is bigger then
  1853. the current block }
  1854. if FPosnblock^.pos>i then
  1855. FPosnblock:=FFirstblock;
  1856. while assigned(FPosnblock) do
  1857. begin
  1858. if FPosnblock^.pos+blocksize>i then
  1859. break;
  1860. FPosnblock:=FPosnblock^.Next;
  1861. end;
  1862. { not found ? then increase blocks }
  1863. if not assigned(FPosnblock) then
  1864. begin
  1865. repeat
  1866. { the current FLastblock is now also fully used }
  1867. FLastblock^.used:=blocksize;
  1868. grow;
  1869. FPosnblock:=FLastblock;
  1870. until FPosnblock^.pos+blocksize>=i;
  1871. end;
  1872. end;
  1873. FPosn:=i;
  1874. if FPosn mod blocksize>FPosnblock^.used then
  1875. FPosnblock^.used:=FPosn mod blocksize;
  1876. end;
  1877. procedure tdynamicarray.write(const d;len:integer);
  1878. var
  1879. p : pchar;
  1880. i,j : integer;
  1881. begin
  1882. p:=pchar(@d);
  1883. while (len>0) do
  1884. begin
  1885. i:=FPosn mod blocksize;
  1886. if i+len>=blocksize then
  1887. begin
  1888. j:=blocksize-i;
  1889. move(p^,FPosnblock^.data[i],j);
  1890. inc(p,j);
  1891. inc(FPosn,j);
  1892. dec(len,j);
  1893. FPosnblock^.used:=blocksize;
  1894. if assigned(FPosnblock^.Next) then
  1895. FPosnblock:=FPosnblock^.Next
  1896. else
  1897. begin
  1898. grow;
  1899. FPosnblock:=FLastblock;
  1900. end;
  1901. end
  1902. else
  1903. begin
  1904. move(p^,FPosnblock^.data[i],len);
  1905. inc(p,len);
  1906. inc(FPosn,len);
  1907. i:=FPosn mod blocksize;
  1908. if i>FPosnblock^.used then
  1909. FPosnblock^.used:=i;
  1910. len:=0;
  1911. end;
  1912. end;
  1913. end;
  1914. procedure tdynamicarray.writestr(const s:string);
  1915. begin
  1916. write(s[1],length(s));
  1917. end;
  1918. function tdynamicarray.read(var d;len:integer):integer;
  1919. var
  1920. p : pchar;
  1921. i,j,res : integer;
  1922. begin
  1923. res:=0;
  1924. p:=pchar(@d);
  1925. while (len>0) do
  1926. begin
  1927. i:=FPosn mod blocksize;
  1928. if i+len>=FPosnblock^.used then
  1929. begin
  1930. j:=FPosnblock^.used-i;
  1931. move(FPosnblock^.data[i],p^,j);
  1932. inc(p,j);
  1933. inc(FPosn,j);
  1934. inc(res,j);
  1935. dec(len,j);
  1936. if assigned(FPosnblock^.Next) then
  1937. FPosnblock:=FPosnblock^.Next
  1938. else
  1939. break;
  1940. end
  1941. else
  1942. begin
  1943. move(FPosnblock^.data[i],p^,len);
  1944. inc(p,len);
  1945. inc(FPosn,len);
  1946. inc(res,len);
  1947. len:=0;
  1948. end;
  1949. end;
  1950. read:=res;
  1951. end;
  1952. procedure tdynamicarray.readstream(f:TCStream;maxlen:longint);
  1953. var
  1954. i,left : integer;
  1955. begin
  1956. if maxlen=-1 then
  1957. maxlen:=maxlongint;
  1958. repeat
  1959. left:=blocksize-FPosnblock^.used;
  1960. if left>maxlen then
  1961. left:=maxlen;
  1962. i:=f.Read(FPosnblock^.data[FPosnblock^.used],left);
  1963. dec(maxlen,i);
  1964. inc(FPosnblock^.used,i);
  1965. if FPosnblock^.used=blocksize then
  1966. begin
  1967. if assigned(FPosnblock^.Next) then
  1968. FPosnblock:=FPosnblock^.Next
  1969. else
  1970. begin
  1971. grow;
  1972. FPosnblock:=FLastblock;
  1973. end;
  1974. end;
  1975. until (i<left) or (maxlen=0);
  1976. end;
  1977. procedure tdynamicarray.writestream(f:TCStream);
  1978. var
  1979. hp : pdynamicblock;
  1980. begin
  1981. hp:=FFirstblock;
  1982. while assigned(hp) do
  1983. begin
  1984. f.Write(hp^.data,hp^.used);
  1985. hp:=hp^.Next;
  1986. end;
  1987. end;
  1988. end.
  1989. {
  1990. $Log$
  1991. Revision 1.33 2004-05-24 17:30:09 peter
  1992. * allow setting of name in dictionary always. Otherwise it is never
  1993. possible to create an item with a name and rename before insert
  1994. this is used in the symtable to hide the current symbol
  1995. Revision 1.32 2004/05/23 14:31:31 peter
  1996. * count fixes for tlinkedlist
  1997. Revision 1.31 2004/04/28 18:02:54 peter
  1998. * add TList to cclasses, remove classes dependency from t_win32
  1999. Revision 1.30 2004/01/15 15:16:17 daniel
  2000. * Some minor stuff
  2001. * Managed to eliminate speed effects of string compression
  2002. Revision 1.29 2004/01/11 23:56:19 daniel
  2003. * Experiment: Compress strings to save memory
  2004. Did not save a single byte of mem; clearly the core size is boosted by
  2005. temporary memory usage...
  2006. Revision 1.28 2003/10/23 14:44:07 peter
  2007. * splitted buildderef and buildderefimpl to fix interface crc
  2008. calculation
  2009. Revision 1.27 2003/10/22 20:40:00 peter
  2010. * write derefdata in a separate ppu entry
  2011. Revision 1.26 2003/10/11 16:06:42 florian
  2012. * fixed some MMX<->SSE
  2013. * started to fix ppc, needs an overhaul
  2014. + stabs info improve for spilling, not sure if it works correctly/completly
  2015. - MMX_SUPPORT removed from Makefile.fpc
  2016. Revision 1.25 2003/09/29 20:52:50 peter
  2017. * insertbefore added
  2018. Revision 1.24 2003/09/24 13:02:10 marco
  2019. * (Peter) patch to fix snapshot
  2020. Revision 1.23 2003/06/09 12:19:34 peter
  2021. * insertlistafter added
  2022. Revision 1.22 2002/12/15 19:34:31 florian
  2023. + some front end stuff for vs_hidden added
  2024. Revision 1.21 2002/11/24 18:18:39 carl
  2025. - remove some unused defines
  2026. Revision 1.20 2002/10/05 12:43:23 carl
  2027. * fixes for Delphi 6 compilation
  2028. (warning : Some features do not work under Delphi)
  2029. Revision 1.19 2002/09/09 17:34:14 peter
  2030. * tdicationary.replace added to replace and item in a dictionary. This
  2031. is only allowed for the same name
  2032. * varsyms are inserted in symtable before the types are parsed. This
  2033. fixes the long standing "var longint : longint" bug
  2034. - consume_idlist and idstringlist removed. The loops are inserted
  2035. at the callers place and uses the symtable for duplicate id checking
  2036. Revision 1.18 2002/09/05 19:29:42 peter
  2037. * memdebug enhancements
  2038. Revision 1.17 2002/08/11 13:24:11 peter
  2039. * saving of asmsymbols in ppu supported
  2040. * asmsymbollist global is removed and moved into a new class
  2041. tasmlibrarydata that will hold the info of a .a file which
  2042. corresponds with a single module. Added librarydata to tmodule
  2043. to keep the library info stored for the module. In the future the
  2044. objectfiles will also be stored to the tasmlibrarydata class
  2045. * all getlabel/newasmsymbol and friends are moved to the new class
  2046. Revision 1.16 2002/08/09 19:08:53 carl
  2047. + fix incorrect comment in insertlistcopy
  2048. Revision 1.15 2002/07/01 18:46:21 peter
  2049. * internal linker
  2050. * reorganized aasm layer
  2051. Revision 1.14 2002/06/17 13:56:14 jonas
  2052. * tdictionary.rename() returns nil if the original object wasn't found
  2053. (reported by Sergey Korshunoff <[email protected]>)
  2054. Revision 1.13 2002/05/18 13:34:05 peter
  2055. * readded missing revisions
  2056. Revision 1.12 2002/05/16 19:46:35 carl
  2057. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  2058. + try to fix temp allocation (still in ifdef)
  2059. + generic constructor calls
  2060. + start of tassembler / tmodulebase class cleanup
  2061. Revision 1.10 2002/05/12 16:53:04 peter
  2062. * moved entry and exitcode to ncgutil and cgobj
  2063. * foreach gets extra argument for passing local data to the
  2064. iterator function
  2065. * -CR checks also class typecasts at runtime by changing them
  2066. into as
  2067. * fixed compiler to cycle with the -CR option
  2068. * fixed stabs with elf writer, finally the global variables can
  2069. be watched
  2070. * removed a lot of routines from cga unit and replaced them by
  2071. calls to cgobj
  2072. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  2073. u32bit then the other is typecasted also to u32bit without giving
  2074. a rangecheck warning/error.
  2075. * fixed pascal calling method with reversing also the high tree in
  2076. the parast, detected by tcalcst3 test
  2077. }