cclasses.pas 62 KB

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