cobjects.pas 61 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402
  1. {
  2. $Id$
  3. Copyright (c) 1993-98 by Florian Klaempfl
  4. This module provides some basic objects
  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. {$ifdef tp}
  19. {$E+,N+,D+,F+}
  20. {$endif}
  21. {$I-}
  22. {$R-}{ necessary for crc calculation }
  23. unit cobjects;
  24. { define OLDSPEEDVALUE}
  25. interface
  26. uses
  27. {$ifdef DELPHI4}
  28. dmisc,
  29. sysutils
  30. {$else DELPHI4}
  31. strings
  32. {$ifndef linux}
  33. ,dos
  34. {$else}
  35. ,linux
  36. {$endif}
  37. {$endif DELPHI4}
  38. ;
  39. const
  40. { the real size will be [-hasharray..hasharray] ! }
  41. {$ifdef TP}
  42. hasharraysize = 127;
  43. {$else}
  44. hasharraysize = 2047;
  45. {$endif}
  46. type
  47. pstring = ^string;
  48. {$ifdef TP}
  49. { redeclare dword only in case of emergency, some small things
  50. of the compiler won't work then correctly (FK)
  51. }
  52. dword = longint;
  53. {$endif TP}
  54. pfileposinfo = ^tfileposinfo;
  55. tfileposinfo = record
  56. line : longint;
  57. column : word;
  58. fileindex : word;
  59. end;
  60. pmemdebug = ^tmemdebug;
  61. tmemdebug = object
  62. constructor init(const s:string);
  63. destructor done;
  64. procedure show;
  65. private
  66. startmem : longint;
  67. infostr : string[40];
  68. end;
  69. plinkedlist_item = ^tlinkedlist_item;
  70. tlinkedlist_item = object
  71. next,previous : plinkedlist_item;
  72. { does nothing }
  73. constructor init;
  74. destructor done;virtual;
  75. function getcopy:plinkedlist_item;virtual;
  76. end;
  77. pstring_item = ^tstring_item;
  78. tstring_item = object(tlinkedlist_item)
  79. str : pstring;
  80. constructor init(const s : string);
  81. destructor done;virtual;
  82. end;
  83. { this implements a double linked list }
  84. plinkedlist = ^tlinkedlist;
  85. tlinkedlist = object
  86. first,last : plinkedlist_item;
  87. constructor init;
  88. destructor done;
  89. { destructors the linkedlist without cleaning the items up }
  90. destructor done_noclear;
  91. { disposes the items of the list }
  92. procedure clear;
  93. { concats a new item at the end }
  94. procedure concat(p : plinkedlist_item);
  95. { inserts a new item at the begin }
  96. procedure insert(p : plinkedlist_item);
  97. { inserts another list at the begin and make this list empty }
  98. procedure insertlist(p : plinkedlist);
  99. { concats another list at the end and make this list empty }
  100. procedure concatlist(p : plinkedlist);
  101. procedure concatlistcopy(p : plinkedlist);
  102. { removes p from the list (p isn't disposed) }
  103. { it's not tested if p is in the list ! }
  104. procedure remove(p : plinkedlist_item);
  105. { is the linkedlist empty ? }
  106. function empty:boolean;
  107. { items in the list }
  108. function count:longint;
  109. end;
  110. { some help data types }
  111. pstringqueueitem = ^tstringqueueitem;
  112. tstringqueueitem = object
  113. data : pstring;
  114. next : pstringqueueitem;
  115. end;
  116. { String Queue}
  117. PStringQueue=^TStringQueue;
  118. TStringQueue=object
  119. first,last : PStringqueueItem;
  120. constructor Init;
  121. destructor Done;
  122. function Empty:boolean;
  123. function Get:string;
  124. function Find(const s:string):PStringqueueItem;
  125. function Delete(const s:string):boolean;
  126. procedure Insert(const s:string);
  127. procedure Concat(const s:string);
  128. procedure Clear;
  129. end;
  130. { containeritem }
  131. pcontaineritem = ^tcontaineritem;
  132. tcontaineritem = object
  133. next : pcontaineritem;
  134. constructor init;
  135. destructor done;virtual;
  136. end;
  137. { container }
  138. pcontainer = ^tcontainer;
  139. tcontainer = object
  140. root,
  141. last : pcontaineritem;
  142. constructor init;
  143. destructor done;
  144. { true when the container is empty }
  145. function empty:boolean;
  146. { inserts a string }
  147. procedure insert(item:pcontaineritem);
  148. { gets a string }
  149. function get:pcontaineritem;
  150. { deletes all items }
  151. procedure clear;
  152. end;
  153. { containeritem }
  154. pstringcontaineritem = ^tstringcontaineritem;
  155. tstringcontaineritem = object(tcontaineritem)
  156. data : pstring;
  157. file_info : tfileposinfo;
  158. constructor init(const s:string);
  159. constructor Init_TokenInfo(const s:string;const pos:tfileposinfo);
  160. destructor done;virtual;
  161. end;
  162. { string container }
  163. pstringcontainer = ^tstringcontainer;
  164. tstringcontainer = object(tcontainer)
  165. doubles : boolean; { if this is set to true, doubles are allowed }
  166. constructor init;
  167. constructor init_no_double;
  168. procedure insert(const s : string);
  169. procedure insert_with_tokeninfo(const s : string;const file_info : tfileposinfo);
  170. { gets a string }
  171. function get : string;
  172. function get_with_tokeninfo(var file_info : tfileposinfo) : string;
  173. { true if string is in the container }
  174. function find(const s:string):boolean;
  175. end;
  176. { namedindexobject for use with dictionary and indexarray }
  177. Pnamedindexobject=^Tnamedindexobject;
  178. Tnamedindexobject=object
  179. indexnr : longint;
  180. _name : Pstring;
  181. next,
  182. left,right : Pnamedindexobject;
  183. speedvalue : longint;
  184. constructor init;
  185. constructor initname(const n:string);
  186. destructor done;virtual;
  187. procedure setname(const n:string);virtual;
  188. function name:string;virtual;
  189. end;
  190. Pdictionaryhasharray=^Tdictionaryhasharray;
  191. Tdictionaryhasharray=array[-hasharraysize..hasharraysize] of Pnamedindexobject;
  192. Tnamedindexcallback = procedure(p:Pnamedindexobject);
  193. Pdictionary=^Tdictionary;
  194. Tdictionary=object
  195. noclear : boolean;
  196. replace_existing : boolean;
  197. constructor init;
  198. destructor done;virtual;
  199. procedure usehash;
  200. procedure clear;
  201. function delete(const s:string):Pnamedindexobject;
  202. function empty:boolean;
  203. procedure foreach(proc2call:Tnamedindexcallback);
  204. function insert(obj:Pnamedindexobject):Pnamedindexobject;
  205. function rename(const olds,news : string):Pnamedindexobject;
  206. function search(const s:string):Pnamedindexobject;
  207. function speedsearch(const s:string;speedvalue:longint):Pnamedindexobject;
  208. private
  209. root : Pnamedindexobject;
  210. hasharray : Pdictionaryhasharray;
  211. procedure cleartree(obj:Pnamedindexobject);
  212. function insertnode(newnode:Pnamedindexobject;var currnode:Pnamedindexobject):Pnamedindexobject;
  213. procedure inserttree(currtree,currroot:Pnamedindexobject);
  214. end;
  215. pdynamicarray = ^tdynamicarray;
  216. tdynamicarray = object
  217. posn,
  218. count,
  219. limit,
  220. elemlen,
  221. growcount : longint;
  222. data : pchar;
  223. constructor init(Aelemlen,Agrow:longint);
  224. destructor done;
  225. function size:longint;
  226. function usedsize:longint;
  227. procedure grow;
  228. procedure align(i:longint);
  229. procedure seek(i:longint);
  230. procedure write(var d;len:longint);
  231. procedure read(var d;len:longint);
  232. procedure writepos(pos:longint;var d;len:longint);
  233. procedure readpos(pos:longint;var d;len:longint);
  234. end;
  235. tindexobjectarray=array[1..16000] of Pnamedindexobject;
  236. Pnamedindexobjectarray=^tindexobjectarray;
  237. pindexarray=^tindexarray;
  238. tindexarray=object
  239. first : Pnamedindexobject;
  240. count : longint;
  241. constructor init(Agrowsize:longint);
  242. destructor done;
  243. procedure clear;
  244. procedure foreach(proc2call : Tnamedindexcallback);
  245. procedure deleteindex(p:Pnamedindexobject);
  246. procedure delete(p:Pnamedindexobject);
  247. procedure insert(p:Pnamedindexobject);
  248. function search(nr:longint):Pnamedindexobject;
  249. private
  250. growsize,
  251. size : longint;
  252. data : Pnamedindexobjectarray;
  253. procedure grow(gsize:longint);
  254. end;
  255. {$ifdef BUFFEREDFILE}
  256. { this is implemented to allow buffered binary I/O }
  257. pbufferedfile = ^tbufferedfile;
  258. tbufferedfile = object
  259. f : file;
  260. buf : pchar;
  261. bufsize,buflast,bufpos : longint;
  262. { 0 closed, 1 input, 2 output }
  263. iomode : byte;
  264. { true, if the compile should change the endian of the output }
  265. change_endian : boolean;
  266. { calcules a crc for the file, }
  267. { but it's assumed, that there no seek while do_crc is true }
  268. do_crc : boolean;
  269. crc : longint;
  270. { temporary closing feature }
  271. tempclosed : boolean;
  272. tempmode : byte;
  273. temppos : longint;
  274. { inits a buffer with the size bufsize which is assigned to }
  275. { the file filename }
  276. constructor init(const filename : string;_bufsize : longint);
  277. { closes the file, if needed, and releases the memory }
  278. destructor done;virtual;
  279. { opens the file for input, other accesses are rejected }
  280. function reset:boolean;
  281. { opens the file for output, other accesses are rejected }
  282. procedure rewrite;
  283. { reads or writes the buffer from or to disk }
  284. procedure flush;
  285. { writes a string to the file }
  286. { the string is written without a length byte }
  287. procedure write_string(const s : string);
  288. { writes a zero terminated string }
  289. procedure write_pchar(p : pchar);
  290. { write specific data types, takes care of }
  291. { byte order }
  292. procedure write_byte(b : byte);
  293. procedure write_word(w : word);
  294. procedure write_long(l : longint);
  295. procedure write_double(d : double);
  296. { writes any data }
  297. procedure write_data(var data;count : longint);
  298. { reads any data }
  299. procedure read_data(var data;bytes : longint;var count : longint);
  300. { closes the file and releases the buffer }
  301. procedure close;
  302. { temporary closing }
  303. procedure tempclose;
  304. procedure tempreopen;
  305. { goto the given position }
  306. procedure seek(l : longint);
  307. { installes an user defined buffer }
  308. { and releases the old one, but be }
  309. { careful, if the old buffer contains }
  310. { data, this data is lost }
  311. procedure setbuf(p : pchar;s : longint);
  312. { reads the file time stamp of the file, }
  313. { the file must be opened }
  314. function getftime : longint;
  315. { returns filesize }
  316. function getsize : longint;
  317. { returns the path }
  318. function getpath : string;
  319. { resets the crc }
  320. procedure clear_crc;
  321. { returns the crc }
  322. function getcrc : longint;
  323. end;
  324. {$endif BUFFEREDFILE}
  325. function getspeedvalue(const s : string) : longint;
  326. { releases the string p and assignes nil to p }
  327. { if p=nil then freemem isn't called }
  328. procedure stringdispose(var p : pstring);
  329. { idem for ansistrings }
  330. procedure ansistringdispose(var p : pchar;length : longint);
  331. { allocates mem for a copy of s, copies s to this mem and returns }
  332. { a pointer to this mem }
  333. function stringdup(const s : string) : pstring;
  334. { allocates memory for s and copies s as zero terminated string
  335. to that mem and returns a pointer to that mem }
  336. function strpnew(const s : string) : pchar;
  337. { makes a char lowercase, with spanish, french and german char set }
  338. function lowercase(c : char) : char;
  339. { makes zero terminated string to a pascal string }
  340. { the data in p is modified and p is returned }
  341. function pchar2pstring(p : pchar) : pstring;
  342. { ambivalent to pchar2pstring }
  343. function pstring2pchar(p : pstring) : pchar;
  344. implementation
  345. uses
  346. comphook;
  347. {*****************************************************************************
  348. Memory debug
  349. *****************************************************************************}
  350. constructor tmemdebug.init(const s:string);
  351. begin
  352. infostr:=s;
  353. startmem:=memavail;
  354. end;
  355. procedure tmemdebug.show;
  356. var
  357. l : longint;
  358. begin
  359. write('memory [',infostr,'] ');
  360. l:=memavail;
  361. if l>startmem then
  362. writeln(l-startmem,' released')
  363. else
  364. writeln(startmem-l,' allocated');
  365. end;
  366. destructor tmemdebug.done;
  367. begin
  368. show;
  369. end;
  370. {$ifndef OLDSPEEDVALUE}
  371. {*****************************************************************************
  372. Crc 32
  373. *****************************************************************************}
  374. var
  375. {$ifdef Delphi}
  376. Crc32Tbl : array[0..255] of longword;
  377. {$else Delphi}
  378. Crc32Tbl : array[0..255] of longint;
  379. {$endif Delphi}
  380. procedure MakeCRC32Tbl;
  381. var
  382. {$ifdef Delphi}
  383. crc : longword;
  384. {$else Delphi}
  385. crc : longint;
  386. {$endif Delphi}
  387. i,n : byte;
  388. begin
  389. for i:=0 to 255 do
  390. begin
  391. crc:=i;
  392. for n:=1 to 8 do
  393. if odd(crc) then
  394. crc:=(crc shr 1) xor $edb88320
  395. else
  396. crc:=crc shr 1;
  397. Crc32Tbl[i]:=crc;
  398. end;
  399. end;
  400. {$ifopt R+}
  401. {$define Range_check_on}
  402. {$endif opt R+}
  403. {$R- needed here }
  404. {CRC 32}
  405. Function GetSpeedValue(Const s:String):longint;
  406. var
  407. i,InitCrc : longint;
  408. begin
  409. if Crc32Tbl[1]=0 then
  410. MakeCrc32Tbl;
  411. InitCrc:=$ffffffff;
  412. for i:=1to Length(s) do
  413. InitCrc:=Crc32Tbl[byte(InitCrc) xor ord(s[i])] xor (InitCrc shr 8);
  414. GetSpeedValue:=InitCrc;
  415. end;
  416. {$ifdef Range_check_on}
  417. {$R+}
  418. {$undef Range_check_on}
  419. {$endif Range_check_on}
  420. {$else}
  421. {$ifndef TP}
  422. function getspeedvalue(const s : string) : longint;
  423. var
  424. p1,p2:^byte;
  425. i : longint;
  426. begin
  427. p1:=@s;
  428. longint(p2):=longint(p1)+p1^+1;
  429. inc(longint(p1));
  430. i:=0;
  431. while p1<>p2 do
  432. begin
  433. i:=i + ord(p1^);
  434. inc(longint(p1));
  435. end;
  436. getspeedvalue:=i;
  437. end;
  438. {$else}
  439. function getspeedvalue(const s : string) : longint;
  440. type
  441. ptrrec=record
  442. ofs,seg:word;
  443. end;
  444. var
  445. l,w : longint;
  446. p1,p2 : ^byte;
  447. begin
  448. p1:=@s;
  449. ptrrec(p2).seg:=ptrrec(p1).seg;
  450. ptrrec(p2).ofs:=ptrrec(p1).ofs+p1^+1;
  451. inc(p1);
  452. l:=0;
  453. while p1<>p2 do
  454. begin
  455. l:=l + ord(p1^);
  456. inc(p1);
  457. end;
  458. getspeedvalue:=l;
  459. end;
  460. {$endif}
  461. {$endif OLDSPEEDVALUE}
  462. function pchar2pstring(p : pchar) : pstring;
  463. var
  464. w,i : longint;
  465. begin
  466. w:=strlen(p);
  467. for i:=w-1 downto 0 do
  468. p[i+1]:=p[i];
  469. p[0]:=chr(w);
  470. pchar2pstring:=pstring(p);
  471. end;
  472. function pstring2pchar(p : pstring) : pchar;
  473. var
  474. w,i : longint;
  475. begin
  476. w:=length(p^);
  477. for i:=1 to w do
  478. p^[i-1]:=p^[i];
  479. p^[w]:=#0;
  480. pstring2pchar:=pchar(p);
  481. end;
  482. function lowercase(c : char) : char;
  483. begin
  484. case c of
  485. #65..#90 : c := chr(ord (c) + 32);
  486. #154 : c:=#129; { german }
  487. #142 : c:=#132; { german }
  488. #153 : c:=#148; { german }
  489. #144 : c:=#130; { french }
  490. #128 : c:=#135; { french }
  491. #143 : c:=#134; { swedish/norge (?) }
  492. #165 : c:=#164; { spanish }
  493. #228 : c:=#229; { greek }
  494. #226 : c:=#231; { greek }
  495. #232 : c:=#227; { greek }
  496. end;
  497. lowercase := c;
  498. end;
  499. function strpnew(const s : string) : pchar;
  500. var
  501. p : pchar;
  502. begin
  503. getmem(p,length(s)+1);
  504. strpcopy(p,s);
  505. strpnew:=p;
  506. end;
  507. procedure stringdispose(var p : pstring);
  508. begin
  509. if assigned(p) then
  510. freemem(p,length(p^)+1);
  511. p:=nil;
  512. end;
  513. procedure ansistringdispose(var p : pchar;length : longint);
  514. begin
  515. if assigned(p) then
  516. freemem(p,length+1);
  517. p:=nil;
  518. end;
  519. function stringdup(const s : string) : pstring;
  520. var
  521. p : pstring;
  522. begin
  523. getmem(p,length(s)+1);
  524. p^:=s;
  525. stringdup:=p;
  526. end;
  527. {****************************************************************************
  528. TStringQueue
  529. ****************************************************************************}
  530. constructor TStringQueue.Init;
  531. begin
  532. first:=nil;
  533. end;
  534. function TStringQueue.Empty:boolean;
  535. begin
  536. Empty:=(first=nil);
  537. end;
  538. function TStringQueue.Get:string;
  539. var
  540. newnode : pstringqueueitem;
  541. begin
  542. if first=nil then
  543. begin
  544. Get:='';
  545. exit;
  546. end;
  547. Get:=first^.data^;
  548. stringdispose(first^.data);
  549. newnode:=first;
  550. first:=first^.next;
  551. dispose(newnode);
  552. end;
  553. function TStringQueue.Find(const s:string):PStringqueueItem;
  554. var
  555. p : PStringqueueItem;
  556. begin
  557. p:=first;
  558. while assigned(p) do
  559. begin
  560. if p^.data^=s then
  561. break;
  562. p:=p^.next;
  563. end;
  564. Find:=p;
  565. end;
  566. function TStringQueue.Delete(const s:string):boolean;
  567. var
  568. prev,p : PStringqueueItem;
  569. begin
  570. Delete:=false;
  571. prev:=nil;
  572. p:=first;
  573. while assigned(p) do
  574. begin
  575. if p^.data^=s then
  576. begin
  577. if assigned(prev) then
  578. prev^.next:=p^.next;
  579. dispose(p);
  580. Delete:=true;
  581. exit;
  582. end;
  583. prev:=p;
  584. p:=p^.next;
  585. end;
  586. end;
  587. procedure TStringQueue.Insert(const s:string);
  588. var
  589. newnode : pstringqueueitem;
  590. begin
  591. new(newnode);
  592. newnode^.next:=first;
  593. newnode^.data:=stringdup(s);
  594. first:=newnode;
  595. if last=nil then
  596. last:=newnode;
  597. end;
  598. procedure TStringQueue.Concat(const s:string);
  599. var
  600. newnode : pstringqueueitem;
  601. begin
  602. new(newnode);
  603. newnode^.next:=nil;
  604. newnode^.data:=stringdup(s);
  605. if first=nil then
  606. first:=newnode
  607. else
  608. last^.next:=newnode;
  609. last:=newnode;
  610. end;
  611. procedure TStringQueue.Clear;
  612. var
  613. newnode : pstringqueueitem;
  614. begin
  615. while (first<>nil) do
  616. begin
  617. newnode:=first;
  618. stringdispose(first^.data);
  619. first:=first^.next;
  620. dispose(newnode);
  621. end;
  622. end;
  623. destructor TStringQueue.Done;
  624. begin
  625. Clear;
  626. end;
  627. {****************************************************************************
  628. TContainerItem
  629. ****************************************************************************}
  630. constructor TContainerItem.Init;
  631. begin
  632. end;
  633. destructor TContainerItem.Done;
  634. begin
  635. end;
  636. {****************************************************************************
  637. TStringContainerItem
  638. ****************************************************************************}
  639. constructor TStringContainerItem.Init(const s:string);
  640. begin
  641. inherited Init;
  642. data:=stringdup(s);
  643. file_info.fileindex:=0;
  644. file_info.line:=0;
  645. file_info.column:=0;
  646. end;
  647. constructor TStringContainerItem.Init_TokenInfo(const s:string;const pos:tfileposinfo);
  648. begin
  649. inherited Init;
  650. data:=stringdup(s);
  651. file_info:=pos;
  652. end;
  653. destructor TStringContainerItem.Done;
  654. begin
  655. stringdispose(data);
  656. end;
  657. {****************************************************************************
  658. TCONTAINER
  659. ****************************************************************************}
  660. constructor tcontainer.init;
  661. begin
  662. root:=nil;
  663. last:=nil;
  664. end;
  665. destructor tcontainer.done;
  666. begin
  667. clear;
  668. end;
  669. function tcontainer.empty:boolean;
  670. begin
  671. empty:=(root=nil);
  672. end;
  673. procedure tcontainer.insert(item:pcontaineritem);
  674. begin
  675. item^.next:=nil;
  676. if root=nil then
  677. root:=item
  678. else
  679. last^.next:=item;
  680. last:=item;
  681. end;
  682. procedure tcontainer.clear;
  683. var
  684. newnode : pcontaineritem;
  685. begin
  686. newnode:=root;
  687. while assigned(newnode) do
  688. begin
  689. root:=newnode^.next;
  690. dispose(newnode,done);
  691. newnode:=root;
  692. end;
  693. last:=nil;
  694. root:=nil;
  695. end;
  696. function tcontainer.get:pcontaineritem;
  697. begin
  698. if root=nil then
  699. get:=nil
  700. else
  701. begin
  702. get:=root;
  703. root:=root^.next;
  704. end;
  705. end;
  706. {****************************************************************************
  707. TSTRINGCONTAINER
  708. ****************************************************************************}
  709. constructor tstringcontainer.init;
  710. begin
  711. inherited init;
  712. doubles:=true;
  713. end;
  714. constructor tstringcontainer.init_no_double;
  715. begin
  716. inherited init;
  717. doubles:=false;
  718. end;
  719. procedure tstringcontainer.insert(const s : string);
  720. var
  721. newnode : pstringcontaineritem;
  722. begin
  723. if (s='') or
  724. ((not doubles) and find(s)) then
  725. exit;
  726. new(newnode,init(s));
  727. inherited insert(newnode);
  728. end;
  729. procedure tstringcontainer.insert_with_tokeninfo(const s : string; const file_info : tfileposinfo);
  730. var
  731. newnode : pstringcontaineritem;
  732. begin
  733. if (not doubles) and find(s) then
  734. exit;
  735. new(newnode,init_tokeninfo(s,file_info));
  736. inherited insert(newnode);
  737. end;
  738. function tstringcontainer.get : string;
  739. var
  740. p : pstringcontaineritem;
  741. begin
  742. p:=pstringcontaineritem(inherited get);
  743. if p=nil then
  744. get:=''
  745. else
  746. begin
  747. get:=p^.data^;
  748. dispose(p,done);
  749. end;
  750. end;
  751. function tstringcontainer.get_with_tokeninfo(var file_info : tfileposinfo) : string;
  752. var
  753. p : pstringcontaineritem;
  754. begin
  755. p:=pstringcontaineritem(inherited get);
  756. if p=nil then
  757. begin
  758. get_with_tokeninfo:='';
  759. file_info.fileindex:=0;
  760. file_info.line:=0;
  761. file_info.column:=0;
  762. end
  763. else
  764. begin
  765. get_with_tokeninfo:=p^.data^;
  766. file_info:=p^.file_info;
  767. dispose(p,done);
  768. end;
  769. end;
  770. function tstringcontainer.find(const s:string):boolean;
  771. var
  772. newnode : pstringcontaineritem;
  773. begin
  774. find:=false;
  775. newnode:=pstringcontaineritem(root);
  776. while assigned(newnode) do
  777. begin
  778. if newnode^.data^=s then
  779. begin
  780. find:=true;
  781. exit;
  782. end;
  783. newnode:=pstringcontaineritem(newnode^.next);
  784. end;
  785. end;
  786. {****************************************************************************
  787. TLINKEDLIST_ITEM
  788. ****************************************************************************}
  789. constructor tlinkedlist_item.init;
  790. begin
  791. previous:=nil;
  792. next:=nil;
  793. end;
  794. destructor tlinkedlist_item.done;
  795. begin
  796. end;
  797. function tlinkedlist_item.getcopy:plinkedlist_item;
  798. var
  799. l : longint;
  800. p : plinkedlist_item;
  801. begin
  802. l:=sizeof(self);
  803. getmem(p,l);
  804. move(self,p^,l);
  805. getcopy:=p;
  806. end;
  807. {****************************************************************************
  808. TSTRING_ITEM
  809. ****************************************************************************}
  810. constructor tstring_item.init(const s : string);
  811. begin
  812. str:=stringdup(s);
  813. end;
  814. destructor tstring_item.done;
  815. begin
  816. stringdispose(str);
  817. inherited done;
  818. end;
  819. {****************************************************************************
  820. TLINKEDLIST
  821. ****************************************************************************}
  822. constructor tlinkedlist.init;
  823. begin
  824. first:=nil;
  825. last:=nil;
  826. end;
  827. destructor tlinkedlist.done;
  828. begin
  829. clear;
  830. end;
  831. destructor tlinkedlist.done_noclear;
  832. begin
  833. end;
  834. procedure tlinkedlist.clear;
  835. var
  836. newnode : plinkedlist_item;
  837. begin
  838. newnode:=first;
  839. while assigned(newnode) do
  840. begin
  841. first:=newnode^.next;
  842. dispose(newnode,done);
  843. newnode:=first;
  844. end;
  845. end;
  846. procedure tlinkedlist.insertlist(p : plinkedlist);
  847. begin
  848. { empty list ? }
  849. if not(assigned(p^.first)) then
  850. exit;
  851. p^.last^.next:=first;
  852. { we have a double linked list }
  853. if assigned(first) then
  854. first^.previous:=p^.last;
  855. first:=p^.first;
  856. if not(assigned(last)) then
  857. last:=p^.last;
  858. { p becomes empty }
  859. p^.first:=nil;
  860. p^.last:=nil;
  861. end;
  862. procedure tlinkedlist.concat(p : plinkedlist_item);
  863. begin
  864. if not(assigned(first)) then
  865. begin
  866. first:=p;
  867. p^.previous:=nil;
  868. p^.next:=nil;
  869. end
  870. else
  871. begin
  872. last^.next:=p;
  873. p^.previous:=last;
  874. p^.next:=nil;
  875. end;
  876. last:=p;
  877. end;
  878. procedure tlinkedlist.insert(p : plinkedlist_item);
  879. begin
  880. if not(assigned(first)) then
  881. begin
  882. last:=p;
  883. p^.previous:=nil;
  884. p^.next:=nil;
  885. end
  886. else
  887. begin
  888. first^.previous:=p;
  889. p^.previous:=nil;
  890. p^.next:=first;
  891. end;
  892. first:=p;
  893. end;
  894. procedure tlinkedlist.remove(p : plinkedlist_item);
  895. begin
  896. if not(assigned(p)) then
  897. exit;
  898. if (first=p) and (last=p) then
  899. begin
  900. first:=nil;
  901. last:=nil;
  902. end
  903. else if first=p then
  904. begin
  905. first:=p^.next;
  906. if assigned(first) then
  907. first^.previous:=nil;
  908. end
  909. else if last=p then
  910. begin
  911. last:=last^.previous;
  912. if assigned(last) then
  913. last^.next:=nil;
  914. end
  915. else
  916. begin
  917. p^.previous^.next:=p^.next;
  918. p^.next^.previous:=p^.previous;
  919. end;
  920. p^.next:=nil;
  921. p^.previous:=nil;
  922. end;
  923. procedure tlinkedlist.concatlist(p : plinkedlist);
  924. begin
  925. if not(assigned(p^.first)) then
  926. exit;
  927. if not(assigned(first)) then
  928. first:=p^.first
  929. else
  930. begin
  931. last^.next:=p^.first;
  932. p^.first^.previous:=last;
  933. end;
  934. last:=p^.last;
  935. { make p empty }
  936. p^.last:=nil;
  937. p^.first:=nil;
  938. end;
  939. procedure tlinkedlist.concatlistcopy(p : plinkedlist);
  940. var
  941. newnode,newnode2 : plinkedlist_item;
  942. begin
  943. newnode:=p^.first;
  944. while assigned(newnode) do
  945. begin
  946. newnode2:=newnode^.getcopy;
  947. if assigned(newnode2) then
  948. begin
  949. if not(assigned(first)) then
  950. begin
  951. first:=newnode2;
  952. newnode2^.previous:=nil;
  953. newnode2^.next:=nil;
  954. end
  955. else
  956. begin
  957. last^.next:=newnode2;
  958. newnode2^.previous:=last;
  959. newnode2^.next:=nil;
  960. end;
  961. last:=newnode2;
  962. end;
  963. newnode:=newnode^.next;
  964. end;
  965. end;
  966. function tlinkedlist.empty:boolean;
  967. begin
  968. empty:=(first=nil);
  969. end;
  970. function tlinkedlist.count:longint;
  971. var
  972. i : longint;
  973. hp : plinkedlist_item;
  974. begin
  975. hp:=first;
  976. i:=0;
  977. while assigned(hp) do
  978. begin
  979. inc(i);
  980. hp:=hp^.next;
  981. end;
  982. count:=i;
  983. end;
  984. {****************************************************************************
  985. Tnamedindexobject
  986. ****************************************************************************}
  987. constructor Tnamedindexobject.init;
  988. begin
  989. { index }
  990. indexnr:=-1;
  991. next:=nil;
  992. { dictionary }
  993. left:=nil;
  994. right:=nil;
  995. _name:=nil;
  996. speedvalue:=-1;
  997. end;
  998. constructor Tnamedindexobject.initname(const n:string);
  999. begin
  1000. { index }
  1001. indexnr:=-1;
  1002. next:=nil;
  1003. { dictionary }
  1004. left:=nil;
  1005. right:=nil;
  1006. speedvalue:=-1;
  1007. _name:=stringdup(n);
  1008. end;
  1009. destructor Tnamedindexobject.done;
  1010. begin
  1011. stringdispose(_name);
  1012. end;
  1013. procedure Tnamedindexobject.setname(const n:string);
  1014. begin
  1015. if speedvalue=-1 then
  1016. begin
  1017. if assigned(_name) then
  1018. stringdispose(_name);
  1019. _name:=stringdup(n);
  1020. end;
  1021. end;
  1022. function Tnamedindexobject.name:string;
  1023. begin
  1024. if assigned(_name) then
  1025. name:=_name^
  1026. else
  1027. name:='';
  1028. end;
  1029. {****************************************************************************
  1030. TDICTIONARY
  1031. ****************************************************************************}
  1032. constructor Tdictionary.init;
  1033. begin
  1034. root:=nil;
  1035. hasharray:=nil;
  1036. noclear:=false;
  1037. replace_existing:=false;
  1038. end;
  1039. procedure Tdictionary.usehash;
  1040. begin
  1041. if not(assigned(root)) and
  1042. not(assigned(hasharray)) then
  1043. begin
  1044. new(hasharray);
  1045. fillchar(hasharray^,sizeof(hasharray^),0);
  1046. end;
  1047. end;
  1048. destructor Tdictionary.done;
  1049. begin
  1050. if not noclear then
  1051. clear;
  1052. if assigned(hasharray) then
  1053. dispose(hasharray);
  1054. end;
  1055. procedure Tdictionary.cleartree(obj:Pnamedindexobject);
  1056. begin
  1057. if assigned(obj^.left) then
  1058. cleartree(obj^.left);
  1059. if assigned(obj^.right) then
  1060. cleartree(obj^.right);
  1061. dispose(obj,done);
  1062. obj:=nil;
  1063. end;
  1064. procedure Tdictionary.clear;
  1065. var
  1066. w : longint;
  1067. begin
  1068. if assigned(root) then
  1069. cleartree(root);
  1070. if assigned(hasharray) then
  1071. for w:=-hasharraysize to hasharraysize do
  1072. if assigned(hasharray^[w]) then
  1073. cleartree(hasharray^[w]);
  1074. end;
  1075. function Tdictionary.delete(const s:string):Pnamedindexobject;
  1076. var p,speedvalue:longint;
  1077. n:Pnamedindexobject;
  1078. procedure insert_right_bottom(var root,Atree:Pnamedindexobject);
  1079. begin
  1080. while root^.right<>nil do
  1081. root:=root^.right;
  1082. root^.right:=Atree;
  1083. end;
  1084. function delete_from_tree(root:Pnamedindexobject):Pnamedindexobject;
  1085. type leftright=(left,right);
  1086. var lr:leftright;
  1087. oldroot:Pnamedindexobject;
  1088. begin
  1089. oldroot:=nil;
  1090. while (root<>nil) and (root^.speedvalue<>speedvalue) do
  1091. begin
  1092. oldroot:=root;
  1093. if speedvalue<root^.speedvalue then
  1094. begin
  1095. root:=root^.right;
  1096. lr:=right;
  1097. end
  1098. else
  1099. begin
  1100. root:=root^.left;
  1101. lr:=left;
  1102. end;
  1103. end;
  1104. while (root<>nil) and (root^._name^<>s) do
  1105. begin
  1106. oldroot:=root;
  1107. if s<root^._name^ then
  1108. begin
  1109. root:=root^.right;
  1110. lr:=right;
  1111. end
  1112. else
  1113. begin
  1114. root:=root^.left;
  1115. lr:=left;
  1116. end;
  1117. end;
  1118. if (oldroot=nil) or (root=nil) then
  1119. do_internalerror(218); {Internalerror is not available...}
  1120. if root^.left<>nil then
  1121. begin
  1122. {Now the node pointing to root must point to the left
  1123. subtree of root. The right subtree of root must be
  1124. connected to the right bottom of the left subtree.}
  1125. if lr=left then
  1126. oldroot^.left:=root^.left
  1127. else
  1128. oldroot^.right:=root^.left;
  1129. if root^.right<>nil then
  1130. insert_right_bottom(root^.left,root^.right);
  1131. end
  1132. else
  1133. {There is no left subtree. So we can just replace the node to
  1134. delete with the right subtree.}
  1135. if lr=left then
  1136. oldroot^.left:=root^.right
  1137. else
  1138. oldroot^.right:=root^.right;
  1139. delete_from_tree:=root;
  1140. end;
  1141. begin
  1142. speedvalue:=getspeedvalue(s);
  1143. n:=root;
  1144. if assigned(hasharray) then
  1145. begin
  1146. {First, check if the node to delete directly located under
  1147. the hasharray.}
  1148. p:=speedvalue mod hasharraysize;
  1149. n:=hasharray^[p];
  1150. if (n<>nil) and (n^.speedvalue=speedvalue) and
  1151. (n^._name^=s) then
  1152. begin
  1153. {The node to delete is directly located under the
  1154. hasharray. Make the hasharray point to the left
  1155. subtree of the node and place the right subtree on
  1156. the right-bottom of the left subtree.}
  1157. if n^.left<>nil then
  1158. begin
  1159. hasharray^[p]:=n^.left;
  1160. if n^.right<>nil then
  1161. insert_right_bottom(n^.left,n^.right);
  1162. end
  1163. else
  1164. hasharray^[p]:=n^.right;
  1165. delete:=n;
  1166. exit;
  1167. end;
  1168. end
  1169. else
  1170. begin
  1171. {First check if the node to delete is the root.}
  1172. if (root<>nil) and (n^.speedvalue=speedvalue)
  1173. and (n^._name^=s) then
  1174. begin
  1175. if n^.left<>nil then
  1176. begin
  1177. root:=n^.left;
  1178. if n^.right<>nil then
  1179. insert_right_bottom(n^.left,n^.right);
  1180. end
  1181. else
  1182. root:=n^.right;
  1183. delete:=n;
  1184. exit;
  1185. end;
  1186. end;
  1187. delete:=delete_from_tree(n);
  1188. end;
  1189. function Tdictionary.empty:boolean;
  1190. var
  1191. w : longint;
  1192. begin
  1193. if assigned(hasharray) then
  1194. begin
  1195. empty:=false;
  1196. for w:=-hasharraysize to hasharraysize do
  1197. if assigned(hasharray^[w]) then
  1198. exit;
  1199. empty:=true;
  1200. end
  1201. else
  1202. empty:=(root=nil);
  1203. end;
  1204. procedure Tdictionary.foreach(proc2call:Tnamedindexcallback);
  1205. procedure a(p:Pnamedindexobject);
  1206. begin
  1207. proc2call(p);
  1208. if assigned(p^.left) then
  1209. a(p^.left);
  1210. if assigned(p^.right) then
  1211. a(p^.right);
  1212. end;
  1213. var
  1214. i : longint;
  1215. begin
  1216. if assigned(hasharray) then
  1217. begin
  1218. for i:=-hasharraysize to hasharraysize do
  1219. if assigned(hasharray^[i]) then
  1220. a(hasharray^[i]);
  1221. end
  1222. else
  1223. if assigned(root) then
  1224. a(root);
  1225. end;
  1226. function Tdictionary.insert(obj:Pnamedindexobject):Pnamedindexobject;
  1227. begin
  1228. obj^.speedvalue:=getspeedvalue(obj^._name^);
  1229. if assigned(hasharray) then
  1230. insert:=insertnode(obj,hasharray^[obj^.speedvalue mod hasharraysize])
  1231. else
  1232. insert:=insertnode(obj,root);
  1233. end;
  1234. function tdictionary.insertnode(newnode:Pnamedindexobject;var currnode:Pnamedindexobject):Pnamedindexobject;
  1235. var
  1236. s1,s2:^string;
  1237. begin
  1238. if currnode=nil then
  1239. begin
  1240. currnode:=newnode;
  1241. insertnode:=currnode;
  1242. end
  1243. { first check speedvalue, to allow a fast insert }
  1244. else
  1245. if currnode^.speedvalue>newnode^.speedvalue then
  1246. insertnode:=insertnode(newnode,currnode^.right)
  1247. else
  1248. if currnode^.speedvalue<newnode^.speedvalue then
  1249. insertnode:=insertnode(newnode,currnode^.left)
  1250. else
  1251. begin
  1252. new(s1);
  1253. new(s2);
  1254. s1^:=currnode^._name^;
  1255. s2^:=newnode^._name^;
  1256. if s1^>s2^ then
  1257. begin
  1258. dispose(s2);
  1259. dispose(s1);
  1260. insertnode:=insertnode(newnode,currnode^.right);
  1261. end
  1262. else
  1263. if s1^<s2^ then
  1264. begin
  1265. dispose(s2);
  1266. dispose(s1);
  1267. insertnode:=insertnode(newnode,currnode^.left);
  1268. end
  1269. else
  1270. begin
  1271. dispose(s2);
  1272. dispose(s1);
  1273. if replace_existing and
  1274. assigned(currnode) then
  1275. begin
  1276. newnode^.left:=currnode^.left;
  1277. newnode^.right:=currnode^.right;
  1278. currnode:=newnode;
  1279. insertnode:=newnode;
  1280. end
  1281. else
  1282. insertnode:=currnode;
  1283. end;
  1284. end;
  1285. end;
  1286. procedure tdictionary.inserttree(currtree,currroot:Pnamedindexobject);
  1287. begin
  1288. if assigned(currtree) then
  1289. begin
  1290. inserttree(currtree^.left,currroot);
  1291. inserttree(currtree^.right,currroot);
  1292. currtree^.right:=nil;
  1293. currtree^.left:=nil;
  1294. insertnode(currtree,currroot);
  1295. end;
  1296. end;
  1297. function tdictionary.rename(const olds,news : string):Pnamedindexobject;
  1298. var
  1299. spdval : longint;
  1300. lasthp,
  1301. hp,hp2,hp3 : Pnamedindexobject;
  1302. begin
  1303. spdval:=getspeedvalue(olds);
  1304. if assigned(hasharray) then
  1305. hp:=hasharray^[spdval mod hasharraysize]
  1306. else
  1307. hp:=root;
  1308. lasthp:=nil;
  1309. while assigned(hp) do
  1310. begin
  1311. if spdval>hp^.speedvalue then
  1312. begin
  1313. lasthp:=hp;
  1314. hp:=hp^.left
  1315. end
  1316. else
  1317. if spdval<hp^.speedvalue then
  1318. begin
  1319. lasthp:=hp;
  1320. hp:=hp^.right
  1321. end
  1322. else
  1323. begin
  1324. if (hp^.name=olds) then
  1325. begin
  1326. { get in hp2 the replacer for the root or hasharr }
  1327. hp2:=hp^.left;
  1328. hp3:=hp^.right;
  1329. if not assigned(hp2) then
  1330. begin
  1331. hp2:=hp^.right;
  1332. hp3:=hp^.left;
  1333. end;
  1334. { remove entry from the tree }
  1335. if assigned(lasthp) then
  1336. begin
  1337. if lasthp^.left=hp then
  1338. lasthp^.left:=hp2
  1339. else
  1340. lasthp^.right:=hp2;
  1341. end
  1342. else
  1343. begin
  1344. if assigned(hasharray) then
  1345. hasharray^[spdval mod hasharraysize]:=hp2
  1346. else
  1347. root:=hp2;
  1348. end;
  1349. { reinsert the hp3 in the tree from hp2 }
  1350. inserttree(hp3,hp2);
  1351. { reset node with new values }
  1352. stringdispose(hp^._name);
  1353. hp^._name:=stringdup(news);
  1354. hp^.speedvalue:=getspeedvalue(news);
  1355. hp^.left:=nil;
  1356. hp^.right:=nil;
  1357. { reinsert }
  1358. if assigned(hasharray) then
  1359. rename:=insertnode(hp,hasharray^[hp^.speedvalue mod hasharraysize])
  1360. else
  1361. rename:=insertnode(hp,root);
  1362. exit;
  1363. end
  1364. else
  1365. if olds>hp^.name then
  1366. begin
  1367. lasthp:=hp;
  1368. hp:=hp^.left
  1369. end
  1370. else
  1371. begin
  1372. lasthp:=hp;
  1373. hp:=hp^.right;
  1374. end;
  1375. end;
  1376. end;
  1377. end;
  1378. function Tdictionary.search(const s:string):Pnamedindexobject;
  1379. begin
  1380. search:=speedsearch(s,getspeedvalue(s));
  1381. end;
  1382. function Tdictionary.speedsearch(const s:string;speedvalue:longint):Pnamedindexobject;
  1383. var
  1384. newnode:Pnamedindexobject;
  1385. begin
  1386. if assigned(hasharray) then
  1387. newnode:=hasharray^[speedvalue mod hasharraysize]
  1388. else
  1389. newnode:=root;
  1390. while assigned(newnode) do
  1391. begin
  1392. if speedvalue>newnode^.speedvalue then
  1393. newnode:=newnode^.left
  1394. else
  1395. if speedvalue<newnode^.speedvalue then
  1396. newnode:=newnode^.right
  1397. else
  1398. begin
  1399. if (newnode^._name^=s) then
  1400. begin
  1401. speedsearch:=newnode;
  1402. exit;
  1403. end
  1404. else
  1405. if s>newnode^._name^ then
  1406. newnode:=newnode^.left
  1407. else
  1408. newnode:=newnode^.right;
  1409. end;
  1410. end;
  1411. speedsearch:=nil;
  1412. end;
  1413. {****************************************************************************
  1414. tdynamicarray
  1415. ****************************************************************************}
  1416. constructor tdynamicarray.init(Aelemlen,Agrow:longint);
  1417. begin
  1418. posn:=0;
  1419. count:=0;
  1420. limit:=0;
  1421. data:=nil;
  1422. elemlen:=Aelemlen;
  1423. growcount:=Agrow;
  1424. grow;
  1425. end;
  1426. function tdynamicarray.size:longint;
  1427. begin
  1428. size:=limit*elemlen;
  1429. end;
  1430. function tdynamicarray.usedsize:longint;
  1431. begin
  1432. usedsize:=count*elemlen;
  1433. end;
  1434. procedure tdynamicarray.grow;
  1435. var
  1436. osize : longint;
  1437. odata : pchar;
  1438. begin
  1439. osize:=size;
  1440. odata:=data;
  1441. inc(limit,growcount);
  1442. getmem(data,size);
  1443. if assigned(odata) then
  1444. begin
  1445. move(odata^,data^,osize);
  1446. freemem(odata,osize);
  1447. end;
  1448. fillchar(data[osize],growcount*elemlen,0);
  1449. end;
  1450. procedure tdynamicarray.align(i:longint);
  1451. var
  1452. j : longint;
  1453. begin
  1454. j:=(posn*elemlen mod i);
  1455. if j<>0 then
  1456. begin
  1457. j:=i-j;
  1458. while limit<(posn+j) do
  1459. grow;
  1460. inc(posn,j);
  1461. if (posn>count) then
  1462. count:=posn;
  1463. end;
  1464. end;
  1465. procedure tdynamicarray.seek(i:longint);
  1466. begin
  1467. while limit<i do
  1468. grow;
  1469. posn:=i;
  1470. if (posn>count) then
  1471. count:=posn;
  1472. end;
  1473. procedure tdynamicarray.write(var d;len:longint);
  1474. begin
  1475. while limit<(posn+len) do
  1476. grow;
  1477. move(d,data[posn*elemlen],len*elemlen);
  1478. inc(posn,len);
  1479. if (posn>count) then
  1480. count:=posn;
  1481. end;
  1482. procedure tdynamicarray.read(var d;len:longint);
  1483. begin
  1484. move(data[posn*elemlen],d,len*elemlen);
  1485. inc(posn,len);
  1486. if (posn>count) then
  1487. count:=posn;
  1488. end;
  1489. procedure tdynamicarray.writepos(pos:longint;var d;len:longint);
  1490. begin
  1491. while limit<(pos+len) do
  1492. grow;
  1493. move(d,data[pos*elemlen],len*elemlen);
  1494. posn:=pos+len;
  1495. if (posn>count) then
  1496. count:=posn;
  1497. end;
  1498. procedure tdynamicarray.readpos(pos:longint;var d;len:longint);
  1499. begin
  1500. while limit<(pos+len) do
  1501. grow;
  1502. move(data[pos*elemlen],d,len*elemlen);
  1503. posn:=pos+len;
  1504. if (posn>count) then
  1505. count:=posn;
  1506. end;
  1507. destructor tdynamicarray.done;
  1508. begin
  1509. if assigned(data) then
  1510. freemem(data,size);
  1511. end;
  1512. {****************************************************************************
  1513. tindexarray
  1514. ****************************************************************************}
  1515. constructor tindexarray.init(Agrowsize:longint);
  1516. begin
  1517. growsize:=Agrowsize;
  1518. size:=0;
  1519. count:=0;
  1520. data:=nil;
  1521. first:=nil;
  1522. end;
  1523. destructor tindexarray.done;
  1524. begin
  1525. if assigned(data) then
  1526. begin
  1527. clear;
  1528. freemem(data,size*4);
  1529. data:=nil;
  1530. end;
  1531. end;
  1532. function tindexarray.search(nr:longint):Pnamedindexobject;
  1533. begin
  1534. if nr<=count then
  1535. search:=data^[nr]
  1536. else
  1537. search:=nil;
  1538. end;
  1539. procedure tindexarray.clear;
  1540. var
  1541. i : longint;
  1542. begin
  1543. for i:=1 to count do
  1544. if assigned(data^[i]) then
  1545. begin
  1546. dispose(data^[i],done);
  1547. data^[i]:=nil;
  1548. end;
  1549. count:=0;
  1550. first:=nil;
  1551. end;
  1552. procedure tindexarray.foreach(proc2call : Tnamedindexcallback);
  1553. var
  1554. i : longint;
  1555. begin
  1556. for i:=1 to count do
  1557. if assigned(data^[i]) then
  1558. proc2call(data^[i]);
  1559. end;
  1560. procedure tindexarray.grow(gsize:longint);
  1561. var
  1562. osize : longint;
  1563. odata : Pnamedindexobjectarray;
  1564. begin
  1565. osize:=size;
  1566. odata:=data;
  1567. inc(size,gsize);
  1568. getmem(data,size*4);
  1569. if assigned(odata) then
  1570. begin
  1571. move(odata^,data^,osize*4);
  1572. freemem(odata,osize*4);
  1573. end;
  1574. fillchar(data^[osize+1],gsize*4,0);
  1575. end;
  1576. procedure tindexarray.deleteindex(p:Pnamedindexobject);
  1577. var
  1578. i : longint;
  1579. begin
  1580. i:=p^.indexnr;
  1581. { update counter }
  1582. if i=count then
  1583. dec(count);
  1584. { update linked list }
  1585. while (i>0) do
  1586. begin
  1587. dec(i);
  1588. if (i>0) and assigned(data^[i]) then
  1589. begin
  1590. data^[i]^.next:=data^[p^.indexnr]^.next;
  1591. break;
  1592. end;
  1593. end;
  1594. if i=0 then
  1595. first:=p^.next;
  1596. data^[p^.indexnr]:=nil;
  1597. { clear entry }
  1598. p^.indexnr:=-1;
  1599. p^.next:=nil;
  1600. end;
  1601. procedure tindexarray.delete(p:Pnamedindexobject);
  1602. begin
  1603. deleteindex(p);
  1604. dispose(p,done);
  1605. p:=nil;
  1606. end;
  1607. procedure tindexarray.insert(p:Pnamedindexobject);
  1608. var
  1609. i : longint;
  1610. begin
  1611. if p^.indexnr=-1 then
  1612. begin
  1613. inc(count);
  1614. p^.indexnr:=count;
  1615. end;
  1616. if p^.indexnr>count then
  1617. count:=p^.indexnr;
  1618. if count>size then
  1619. grow(((count div growsize)+1)*growsize);
  1620. data^[p^.indexnr]:=p;
  1621. { update linked list backward }
  1622. i:=p^.indexnr;
  1623. while (i>0) do
  1624. begin
  1625. dec(i);
  1626. if (i>0) and assigned(data^[i]) then
  1627. begin
  1628. data^[i]^.next:=p;
  1629. break;
  1630. end;
  1631. end;
  1632. if i=0 then
  1633. first:=p;
  1634. { update linked list forward }
  1635. i:=p^.indexnr;
  1636. while (i<=count) do
  1637. begin
  1638. inc(i);
  1639. if (i<=count) and assigned(data^[i]) then
  1640. begin
  1641. p^.next:=data^[i];
  1642. exit;
  1643. end;
  1644. end;
  1645. if i>count then
  1646. p^.next:=nil;
  1647. end;
  1648. {$ifdef BUFFEREDFILE}
  1649. {****************************************************************************
  1650. TBUFFEREDFILE
  1651. ****************************************************************************}
  1652. Const
  1653. crcseed = $ffffffff;
  1654. crctable : array[0..255] of longint = (
  1655. $00000000,$77073096,$ee0e612c,$990951ba,$076dc419,$706af48f,
  1656. $e963a535,$9e6495a3,$0edb8832,$79dcb8a4,$e0d5e91e,$97d2d988,
  1657. $09b64c2b,$7eb17cbd,$e7b82d07,$90bf1d91,$1db71064,$6ab020f2,
  1658. $f3b97148,$84be41de,$1adad47d,$6ddde4eb,$f4d4b551,$83d385c7,
  1659. $136c9856,$646ba8c0,$fd62f97a,$8a65c9ec,$14015c4f,$63066cd9,
  1660. $fa0f3d63,$8d080df5,$3b6e20c8,$4c69105e,$d56041e4,$a2677172,
  1661. $3c03e4d1,$4b04d447,$d20d85fd,$a50ab56b,$35b5a8fa,$42b2986c,
  1662. $dbbbc9d6,$acbcf940,$32d86ce3,$45df5c75,$dcd60dcf,$abd13d59,
  1663. $26d930ac,$51de003a,$c8d75180,$bfd06116,$21b4f4b5,$56b3c423,
  1664. $cfba9599,$b8bda50f,$2802b89e,$5f058808,$c60cd9b2,$b10be924,
  1665. $2f6f7c87,$58684c11,$c1611dab,$b6662d3d,$76dc4190,$01db7106,
  1666. $98d220bc,$efd5102a,$71b18589,$06b6b51f,$9fbfe4a5,$e8b8d433,
  1667. $7807c9a2,$0f00f934,$9609a88e,$e10e9818,$7f6a0dbb,$086d3d2d,
  1668. $91646c97,$e6635c01,$6b6b51f4,$1c6c6162,$856530d8,$f262004e,
  1669. $6c0695ed,$1b01a57b,$8208f4c1,$f50fc457,$65b0d9c6,$12b7e950,
  1670. $8bbeb8ea,$fcb9887c,$62dd1ddf,$15da2d49,$8cd37cf3,$fbd44c65,
  1671. $4db26158,$3ab551ce,$a3bc0074,$d4bb30e2,$4adfa541,$3dd895d7,
  1672. $a4d1c46d,$d3d6f4fb,$4369e96a,$346ed9fc,$ad678846,$da60b8d0,
  1673. $44042d73,$33031de5,$aa0a4c5f,$dd0d7cc9,$5005713c,$270241aa,
  1674. $be0b1010,$c90c2086,$5768b525,$206f85b3,$b966d409,$ce61e49f,
  1675. $5edef90e,$29d9c998,$b0d09822,$c7d7a8b4,$59b33d17,$2eb40d81,
  1676. $b7bd5c3b,$c0ba6cad,$edb88320,$9abfb3b6,$03b6e20c,$74b1d29a,
  1677. $ead54739,$9dd277af,$04db2615,$73dc1683,$e3630b12,$94643b84,
  1678. $0d6d6a3e,$7a6a5aa8,$e40ecf0b,$9309ff9d,$0a00ae27,$7d079eb1,
  1679. $f00f9344,$8708a3d2,$1e01f268,$6906c2fe,$f762575d,$806567cb,
  1680. $196c3671,$6e6b06e7,$fed41b76,$89d32be0,$10da7a5a,$67dd4acc,
  1681. $f9b9df6f,$8ebeeff9,$17b7be43,$60b08ed5,$d6d6a3e8,$a1d1937e,
  1682. $38d8c2c4,$4fdff252,$d1bb67f1,$a6bc5767,$3fb506dd,$48b2364b,
  1683. $d80d2bda,$af0a1b4c,$36034af6,$41047a60,$df60efc3,$a867df55,
  1684. $316e8eef,$4669be79,$cb61b38c,$bc66831a,$256fd2a0,$5268e236,
  1685. $cc0c7795,$bb0b4703,$220216b9,$5505262f,$c5ba3bbe,$b2bd0b28,
  1686. $2bb45a92,$5cb36a04,$c2d7ffa7,$b5d0cf31,$2cd99e8b,$5bdeae1d,
  1687. $9b64c2b0,$ec63f226,$756aa39c,$026d930a,$9c0906a9,$eb0e363f,
  1688. $72076785,$05005713,$95bf4a82,$e2b87a14,$7bb12bae,$0cb61b38,
  1689. $92d28e9b,$e5d5be0d,$7cdcefb7,$0bdbdf21,$86d3d2d4,$f1d4e242,
  1690. $68ddb3f8,$1fda836e,$81be16cd,$f6b9265b,$6fb077e1,$18b74777,
  1691. $88085ae6,$ff0f6a70,$66063bca,$11010b5c,$8f659eff,$f862ae69,
  1692. $616bffd3,$166ccf45,$a00ae278,$d70dd2ee,$4e048354,$3903b3c2,
  1693. $a7672661,$d06016f7,$4969474d,$3e6e77db,$aed16a4a,$d9d65adc,
  1694. $40df0b66,$37d83bf0,$a9bcae53,$debb9ec5,$47b2cf7f,$30b5ffe9,
  1695. $bdbdf21c,$cabac28a,$53b39330,$24b4a3a6,$bad03605,$cdd70693,
  1696. $54de5729,$23d967bf,$b3667a2e,$c4614ab8,$5d681b02,$2a6f2b94,
  1697. $b40bbe37,$c30c8ea1,$5a05df1b,$2d02ef8d);
  1698. constructor tbufferedfile.init(const filename : string;_bufsize : longint);
  1699. begin
  1700. assign(f,filename);
  1701. bufsize:=_bufsize;
  1702. bufpos:=0;
  1703. buflast:=0;
  1704. do_crc:=false;
  1705. iomode:=0;
  1706. tempclosed:=false;
  1707. change_endian:=false;
  1708. clear_crc;
  1709. end;
  1710. destructor tbufferedfile.done;
  1711. begin
  1712. close;
  1713. end;
  1714. procedure tbufferedfile.clear_crc;
  1715. begin
  1716. crc:=crcseed;
  1717. end;
  1718. procedure tbufferedfile.setbuf(p : pchar;s : longint);
  1719. begin
  1720. flush;
  1721. freemem(buf,bufsize);
  1722. bufsize:=s;
  1723. buf:=p;
  1724. end;
  1725. function tbufferedfile.reset:boolean;
  1726. var
  1727. ofm : byte;
  1728. begin
  1729. ofm:=filemode;
  1730. iomode:=1;
  1731. getmem(buf,bufsize);
  1732. filemode:=0;
  1733. {$I-}
  1734. system.reset(f,1);
  1735. {$I+}
  1736. reset:=(ioresult=0);
  1737. filemode:=ofm;
  1738. end;
  1739. procedure tbufferedfile.rewrite;
  1740. begin
  1741. iomode:=2;
  1742. getmem(buf,bufsize);
  1743. system.rewrite(f,1);
  1744. end;
  1745. procedure tbufferedfile.flush;
  1746. var
  1747. {$ifdef FPC}
  1748. count : longint;
  1749. {$else}
  1750. count : integer;
  1751. {$endif}
  1752. begin
  1753. if iomode=2 then
  1754. begin
  1755. if bufpos=0 then
  1756. exit;
  1757. blockwrite(f,buf^,bufpos)
  1758. end
  1759. else if iomode=1 then
  1760. if buflast=bufpos then
  1761. begin
  1762. blockread(f,buf^,bufsize,count);
  1763. buflast:=count;
  1764. end;
  1765. bufpos:=0;
  1766. end;
  1767. function tbufferedfile.getftime : longint;
  1768. var
  1769. l : longint;
  1770. {$ifdef linux}
  1771. Info : Stat;
  1772. {$endif}
  1773. begin
  1774. {$ifndef linux}
  1775. { this only works if the file is open !! }
  1776. dos.getftime(f,l);
  1777. {$else}
  1778. Fstat(f,Info);
  1779. l:=info.mtime;
  1780. {$endif}
  1781. getftime:=l;
  1782. end;
  1783. function tbufferedfile.getsize : longint;
  1784. begin
  1785. getsize:=filesize(f);
  1786. end;
  1787. procedure tbufferedfile.seek(l : longint);
  1788. begin
  1789. if iomode=2 then
  1790. begin
  1791. flush;
  1792. system.seek(f,l);
  1793. end
  1794. else if iomode=1 then
  1795. begin
  1796. { forces a reload }
  1797. bufpos:=buflast;
  1798. system.seek(f,l);
  1799. flush;
  1800. end;
  1801. end;
  1802. type
  1803. {$ifdef tp}
  1804. bytearray1 = array [1..65535] of byte;
  1805. {$else}
  1806. bytearray1 = array [1..10000000] of byte;
  1807. {$endif}
  1808. procedure tbufferedfile.read_data(var data;bytes : longint;var count : longint);
  1809. var
  1810. p : pchar;
  1811. c,i : longint;
  1812. begin
  1813. p:=pchar(@data);
  1814. count:=0;
  1815. while bytes-count>0 do
  1816. begin
  1817. if bytes-count>buflast-bufpos then
  1818. begin
  1819. move((buf+bufpos)^,(p+count)^,buflast-bufpos);
  1820. inc(count,buflast-bufpos);
  1821. bufpos:=buflast;
  1822. flush;
  1823. { can't we read anything ? }
  1824. if bufpos=buflast then
  1825. break;
  1826. end
  1827. else
  1828. begin
  1829. move((buf+bufpos)^,(p+count)^,bytes-count);
  1830. inc(bufpos,bytes-count);
  1831. count:=bytes;
  1832. break;
  1833. end;
  1834. end;
  1835. if do_crc then
  1836. begin
  1837. c:=crc;
  1838. for i:=1 to bytes do
  1839. c:=(c shr 8) xor crctable[byte(c) xor (bytearray1(data)[i])];
  1840. crc:=c;
  1841. end;
  1842. end;
  1843. procedure tbufferedfile.write_data(var data;count : longint);
  1844. var
  1845. c,i : longint;
  1846. begin
  1847. if bufpos+count>bufsize then
  1848. flush;
  1849. move(data,(buf+bufpos)^,count);
  1850. inc(bufpos,count);
  1851. if do_crc then
  1852. begin
  1853. c:=crc;
  1854. for i:=1 to count do
  1855. c:=(c shr 8) xor crctable[byte(c) xor (bytearray1(data)[i])];
  1856. crc:=c;
  1857. end;
  1858. end;
  1859. function tbufferedfile.getcrc : longint;
  1860. begin
  1861. getcrc:=crc xor crcseed;
  1862. end;
  1863. procedure tbufferedfile.write_string(const s : string);
  1864. begin
  1865. if bufpos+length(s)>bufsize then
  1866. flush;
  1867. { why is there not CRC here ??? }
  1868. move(s[1],(buf+bufpos)^,length(s));
  1869. inc(bufpos,length(s));
  1870. { should be
  1871. write_data(s[1],length(s)); }
  1872. end;
  1873. procedure tbufferedfile.write_pchar(p : pchar);
  1874. var
  1875. l : longint;
  1876. begin
  1877. l:=strlen(p);
  1878. if l>=bufsize then
  1879. do_internalerror(222);
  1880. { why is there not CRC here ???}
  1881. if bufpos+l>bufsize then
  1882. flush;
  1883. move(p^,(buf+bufpos)^,l);
  1884. inc(bufpos,l);
  1885. { should be
  1886. write_data(p^,l); }
  1887. end;
  1888. procedure tbufferedfile.write_byte(b : byte);
  1889. begin
  1890. write_data(b,sizeof(byte));
  1891. end;
  1892. procedure tbufferedfile.write_long(l : longint);
  1893. var
  1894. w1,w2 : word;
  1895. begin
  1896. if change_endian then
  1897. begin
  1898. w1:=l and $ffff;
  1899. w2:=l shr 16;
  1900. l:=swap(w2)+(longint(swap(w1)) shl 16);
  1901. end;
  1902. write_data(l,sizeof(longint));
  1903. end;
  1904. procedure tbufferedfile.write_word(w : word);
  1905. begin
  1906. if change_endian then
  1907. begin
  1908. w:=swap(w);
  1909. end;
  1910. write_data(w,sizeof(word));
  1911. end;
  1912. procedure tbufferedfile.write_double(d : double);
  1913. begin
  1914. write_data(d,sizeof(double));
  1915. end;
  1916. function tbufferedfile.getpath : string;
  1917. begin
  1918. {$ifdef dummy}
  1919. getpath:=strpas(filerec(f).name);
  1920. {$endif}
  1921. getpath:='';
  1922. end;
  1923. procedure tbufferedfile.close;
  1924. begin
  1925. if iomode<>0 then
  1926. begin
  1927. flush;
  1928. system.close(f);
  1929. freemem(buf,bufsize);
  1930. buf:=nil;
  1931. iomode:=0;
  1932. end;
  1933. end;
  1934. procedure tbufferedfile.tempclose;
  1935. begin
  1936. if iomode<>0 then
  1937. begin
  1938. temppos:=system.filepos(f);
  1939. tempmode:=iomode;
  1940. tempclosed:=true;
  1941. system.close(f);
  1942. iomode:=0;
  1943. end
  1944. else
  1945. tempclosed:=false;
  1946. end;
  1947. procedure tbufferedfile.tempreopen;
  1948. var
  1949. ofm : byte;
  1950. begin
  1951. if tempclosed then
  1952. begin
  1953. case tempmode of
  1954. 1 : begin
  1955. ofm:=filemode;
  1956. iomode:=1;
  1957. filemode:=0;
  1958. system.reset(f,1);
  1959. filemode:=ofm;
  1960. end;
  1961. 2 : begin
  1962. iomode:=2;
  1963. system.rewrite(f,1);
  1964. end;
  1965. end;
  1966. system.seek(f,temppos);
  1967. tempclosed:=false;
  1968. end;
  1969. end;
  1970. {$endif BUFFEREDFILE}
  1971. end.
  1972. {
  1973. $Log$
  1974. Revision 1.45 1999-11-12 11:03:49 peter
  1975. * searchpaths changed to stringqueue object
  1976. Revision 1.44 1999/11/06 14:34:20 peter
  1977. * truncated log to 20 revs
  1978. Revision 1.43 1999/10/26 12:30:41 peter
  1979. * const parameter is now checked
  1980. * better and generic check if a node can be used for assigning
  1981. * export fixes
  1982. * procvar equal works now (it never had worked at least from 0.99.8)
  1983. * defcoll changed to linkedlist with pparaitem so it can easily be
  1984. walked both directions
  1985. Revision 1.42 1999/09/07 15:08:51 pierre
  1986. * runerror => do_internalerror
  1987. Revision 1.41 1999/08/24 13:13:57 peter
  1988. * MEMDEBUG to see the sizes of asmlist,asmsymbols,symtables
  1989. Revision 1.40 1999/08/12 23:19:05 pierre
  1990. * added inherited init call to tstringcontainer.init_no_double for Peter
  1991. Revision 1.39 1999/08/05 14:58:07 florian
  1992. * some fixes for the floating point registers
  1993. * more things for the new code generator
  1994. Revision 1.38 1999/07/18 10:19:46 florian
  1995. * made it compilable with Dlephi 4 again
  1996. + fixed problem with large stack allocations on win32
  1997. Revision 1.37 1999/07/03 00:29:45 peter
  1998. * new link writing to the ppu, one .ppu is needed for all link types,
  1999. static (.o) is now always created also when smartlinking is used
  2000. Revision 1.36 1999/06/23 11:13:20 peter
  2001. * fixed linebreak
  2002. Revision 1.35 1999/06/23 11:07:23 daniel
  2003. * Tdictionary.delete
  2004. Revision 1.33.2.1 1999/06/15 10:12:22 peter
  2005. * fixed inserttree which didn't reset left,right
  2006. Revision 1.33 1999/05/31 23:33:21 peter
  2007. * fixed tdictionary rename which didn't reset left,right when
  2008. reinserting
  2009. Revision 1.32 1999/05/27 19:44:23 peter
  2010. * removed oldasm
  2011. * plabel -> pasmlabel
  2012. * -a switches to source writing automaticly
  2013. * assembler readers OOPed
  2014. * asmsymbol automaticly external
  2015. * jumptables and other label fixes for asm readers
  2016. Revision 1.31 1999/05/21 13:54:59 peter
  2017. * NEWLAB for label as symbol
  2018. Revision 1.30 1999/05/21 10:38:59 peter
  2019. * fixed deleteindex which didn't reset indexnr and set first wrong
  2020. Revision 1.29 1999/05/08 19:47:27 peter
  2021. * indexarray.delete resets pointer after dispose
  2022. Revision 1.28 1999/05/05 10:05:48 florian
  2023. * a delphi compiled compiler recompiles ppc
  2024. Revision 1.27 1999/05/05 09:19:03 florian
  2025. * more fixes to get it with delphi running
  2026. Revision 1.26 1999/04/21 09:43:31 peter
  2027. * storenumber works
  2028. * fixed some typos in double_checksum
  2029. + incompatible types type1 and type2 message (with storenumber)
  2030. Revision 1.25 1999/04/15 10:01:44 peter
  2031. * small update for storenumber
  2032. Revision 1.24 1999/04/14 09:14:47 peter
  2033. * first things to store the symbol/def number in the ppu
  2034. }