cobjects.pas 61 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414
  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. last:=nil;
  534. end;
  535. function TStringQueue.Empty:boolean;
  536. begin
  537. Empty:=(first=nil);
  538. end;
  539. function TStringQueue.Get:string;
  540. var
  541. newnode : pstringqueueitem;
  542. begin
  543. if first=nil then
  544. begin
  545. Get:='';
  546. exit;
  547. end;
  548. Get:=first^.data^;
  549. stringdispose(first^.data);
  550. newnode:=first;
  551. first:=first^.next;
  552. dispose(newnode);
  553. end;
  554. function TStringQueue.Find(const s:string):PStringqueueItem;
  555. var
  556. p : PStringqueueItem;
  557. begin
  558. p:=first;
  559. while assigned(p) do
  560. begin
  561. if p^.data^=s then
  562. break;
  563. p:=p^.next;
  564. end;
  565. Find:=p;
  566. end;
  567. function TStringQueue.Delete(const s:string):boolean;
  568. var
  569. prev,p : PStringqueueItem;
  570. begin
  571. Delete:=false;
  572. prev:=nil;
  573. p:=first;
  574. while assigned(p) do
  575. begin
  576. if p^.data^=s then
  577. begin
  578. if p=last then
  579. last:=prev;
  580. if assigned(prev) then
  581. prev^.next:=p^.next
  582. else
  583. first:=p^.next;
  584. dispose(p);
  585. Delete:=true;
  586. exit;
  587. end;
  588. prev:=p;
  589. p:=p^.next;
  590. end;
  591. end;
  592. procedure TStringQueue.Insert(const s:string);
  593. var
  594. newnode : pstringqueueitem;
  595. begin
  596. new(newnode);
  597. newnode^.next:=first;
  598. newnode^.data:=stringdup(s);
  599. first:=newnode;
  600. if last=nil then
  601. last:=newnode;
  602. end;
  603. procedure TStringQueue.Concat(const s:string);
  604. var
  605. newnode : pstringqueueitem;
  606. begin
  607. new(newnode);
  608. newnode^.next:=nil;
  609. newnode^.data:=stringdup(s);
  610. if first=nil then
  611. first:=newnode
  612. else
  613. last^.next:=newnode;
  614. last:=newnode;
  615. end;
  616. procedure TStringQueue.Clear;
  617. var
  618. newnode : pstringqueueitem;
  619. begin
  620. while (first<>nil) do
  621. begin
  622. newnode:=first;
  623. stringdispose(first^.data);
  624. first:=first^.next;
  625. dispose(newnode);
  626. end;
  627. last:=nil;
  628. end;
  629. destructor TStringQueue.Done;
  630. begin
  631. Clear;
  632. end;
  633. {****************************************************************************
  634. TContainerItem
  635. ****************************************************************************}
  636. constructor TContainerItem.Init;
  637. begin
  638. end;
  639. destructor TContainerItem.Done;
  640. begin
  641. end;
  642. {****************************************************************************
  643. TStringContainerItem
  644. ****************************************************************************}
  645. constructor TStringContainerItem.Init(const s:string);
  646. begin
  647. inherited Init;
  648. data:=stringdup(s);
  649. file_info.fileindex:=0;
  650. file_info.line:=0;
  651. file_info.column:=0;
  652. end;
  653. constructor TStringContainerItem.Init_TokenInfo(const s:string;const pos:tfileposinfo);
  654. begin
  655. inherited Init;
  656. data:=stringdup(s);
  657. file_info:=pos;
  658. end;
  659. destructor TStringContainerItem.Done;
  660. begin
  661. stringdispose(data);
  662. end;
  663. {****************************************************************************
  664. TCONTAINER
  665. ****************************************************************************}
  666. constructor tcontainer.init;
  667. begin
  668. root:=nil;
  669. last:=nil;
  670. end;
  671. destructor tcontainer.done;
  672. begin
  673. clear;
  674. end;
  675. function tcontainer.empty:boolean;
  676. begin
  677. empty:=(root=nil);
  678. end;
  679. procedure tcontainer.insert(item:pcontaineritem);
  680. begin
  681. item^.next:=nil;
  682. if root=nil then
  683. root:=item
  684. else
  685. last^.next:=item;
  686. last:=item;
  687. end;
  688. procedure tcontainer.clear;
  689. var
  690. newnode : pcontaineritem;
  691. begin
  692. newnode:=root;
  693. while assigned(newnode) do
  694. begin
  695. root:=newnode^.next;
  696. dispose(newnode,done);
  697. newnode:=root;
  698. end;
  699. last:=nil;
  700. root:=nil;
  701. end;
  702. function tcontainer.get:pcontaineritem;
  703. begin
  704. if root=nil then
  705. get:=nil
  706. else
  707. begin
  708. get:=root;
  709. root:=root^.next;
  710. end;
  711. end;
  712. {****************************************************************************
  713. TSTRINGCONTAINER
  714. ****************************************************************************}
  715. constructor tstringcontainer.init;
  716. begin
  717. inherited init;
  718. doubles:=true;
  719. end;
  720. constructor tstringcontainer.init_no_double;
  721. begin
  722. inherited init;
  723. doubles:=false;
  724. end;
  725. procedure tstringcontainer.insert(const s : string);
  726. var
  727. newnode : pstringcontaineritem;
  728. begin
  729. if (s='') or
  730. ((not doubles) and find(s)) then
  731. exit;
  732. new(newnode,init(s));
  733. inherited insert(newnode);
  734. end;
  735. procedure tstringcontainer.insert_with_tokeninfo(const s : string; const file_info : tfileposinfo);
  736. var
  737. newnode : pstringcontaineritem;
  738. begin
  739. if (not doubles) and find(s) then
  740. exit;
  741. new(newnode,init_tokeninfo(s,file_info));
  742. inherited insert(newnode);
  743. end;
  744. function tstringcontainer.get : string;
  745. var
  746. p : pstringcontaineritem;
  747. begin
  748. p:=pstringcontaineritem(inherited get);
  749. if p=nil then
  750. get:=''
  751. else
  752. begin
  753. get:=p^.data^;
  754. dispose(p,done);
  755. end;
  756. end;
  757. function tstringcontainer.get_with_tokeninfo(var file_info : tfileposinfo) : string;
  758. var
  759. p : pstringcontaineritem;
  760. begin
  761. p:=pstringcontaineritem(inherited get);
  762. if p=nil then
  763. begin
  764. get_with_tokeninfo:='';
  765. file_info.fileindex:=0;
  766. file_info.line:=0;
  767. file_info.column:=0;
  768. end
  769. else
  770. begin
  771. get_with_tokeninfo:=p^.data^;
  772. file_info:=p^.file_info;
  773. dispose(p,done);
  774. end;
  775. end;
  776. function tstringcontainer.find(const s:string):boolean;
  777. var
  778. newnode : pstringcontaineritem;
  779. begin
  780. find:=false;
  781. newnode:=pstringcontaineritem(root);
  782. while assigned(newnode) do
  783. begin
  784. if newnode^.data^=s then
  785. begin
  786. find:=true;
  787. exit;
  788. end;
  789. newnode:=pstringcontaineritem(newnode^.next);
  790. end;
  791. end;
  792. {****************************************************************************
  793. TLINKEDLIST_ITEM
  794. ****************************************************************************}
  795. constructor tlinkedlist_item.init;
  796. begin
  797. previous:=nil;
  798. next:=nil;
  799. end;
  800. destructor tlinkedlist_item.done;
  801. begin
  802. end;
  803. function tlinkedlist_item.getcopy:plinkedlist_item;
  804. var
  805. l : longint;
  806. p : plinkedlist_item;
  807. begin
  808. l:=sizeof(self);
  809. getmem(p,l);
  810. move(self,p^,l);
  811. getcopy:=p;
  812. end;
  813. {****************************************************************************
  814. TSTRING_ITEM
  815. ****************************************************************************}
  816. constructor tstring_item.init(const s : string);
  817. begin
  818. str:=stringdup(s);
  819. end;
  820. destructor tstring_item.done;
  821. begin
  822. stringdispose(str);
  823. inherited done;
  824. end;
  825. {****************************************************************************
  826. TLINKEDLIST
  827. ****************************************************************************}
  828. constructor tlinkedlist.init;
  829. begin
  830. first:=nil;
  831. last:=nil;
  832. end;
  833. destructor tlinkedlist.done;
  834. begin
  835. clear;
  836. end;
  837. destructor tlinkedlist.done_noclear;
  838. begin
  839. end;
  840. procedure tlinkedlist.clear;
  841. var
  842. newnode : plinkedlist_item;
  843. begin
  844. newnode:=first;
  845. while assigned(newnode) do
  846. begin
  847. first:=newnode^.next;
  848. dispose(newnode,done);
  849. newnode:=first;
  850. end;
  851. end;
  852. procedure tlinkedlist.insertlist(p : plinkedlist);
  853. begin
  854. { empty list ? }
  855. if not(assigned(p^.first)) then
  856. exit;
  857. p^.last^.next:=first;
  858. { we have a double linked list }
  859. if assigned(first) then
  860. first^.previous:=p^.last;
  861. first:=p^.first;
  862. if not(assigned(last)) then
  863. last:=p^.last;
  864. { p becomes empty }
  865. p^.first:=nil;
  866. p^.last:=nil;
  867. end;
  868. procedure tlinkedlist.concat(p : plinkedlist_item);
  869. begin
  870. if not(assigned(first)) then
  871. begin
  872. first:=p;
  873. p^.previous:=nil;
  874. p^.next:=nil;
  875. end
  876. else
  877. begin
  878. last^.next:=p;
  879. p^.previous:=last;
  880. p^.next:=nil;
  881. end;
  882. last:=p;
  883. end;
  884. procedure tlinkedlist.insert(p : plinkedlist_item);
  885. begin
  886. if not(assigned(first)) then
  887. begin
  888. last:=p;
  889. p^.previous:=nil;
  890. p^.next:=nil;
  891. end
  892. else
  893. begin
  894. first^.previous:=p;
  895. p^.previous:=nil;
  896. p^.next:=first;
  897. end;
  898. first:=p;
  899. end;
  900. procedure tlinkedlist.remove(p : plinkedlist_item);
  901. begin
  902. if not(assigned(p)) then
  903. exit;
  904. if (first=p) and (last=p) then
  905. begin
  906. first:=nil;
  907. last:=nil;
  908. end
  909. else if first=p then
  910. begin
  911. first:=p^.next;
  912. if assigned(first) then
  913. first^.previous:=nil;
  914. end
  915. else if last=p then
  916. begin
  917. last:=last^.previous;
  918. if assigned(last) then
  919. last^.next:=nil;
  920. end
  921. else
  922. begin
  923. p^.previous^.next:=p^.next;
  924. p^.next^.previous:=p^.previous;
  925. end;
  926. p^.next:=nil;
  927. p^.previous:=nil;
  928. end;
  929. procedure tlinkedlist.concatlist(p : plinkedlist);
  930. begin
  931. if not(assigned(p^.first)) then
  932. exit;
  933. if not(assigned(first)) then
  934. first:=p^.first
  935. else
  936. begin
  937. last^.next:=p^.first;
  938. p^.first^.previous:=last;
  939. end;
  940. last:=p^.last;
  941. { make p empty }
  942. p^.last:=nil;
  943. p^.first:=nil;
  944. end;
  945. procedure tlinkedlist.concatlistcopy(p : plinkedlist);
  946. var
  947. newnode,newnode2 : plinkedlist_item;
  948. begin
  949. newnode:=p^.first;
  950. while assigned(newnode) do
  951. begin
  952. newnode2:=newnode^.getcopy;
  953. if assigned(newnode2) then
  954. begin
  955. if not(assigned(first)) then
  956. begin
  957. first:=newnode2;
  958. newnode2^.previous:=nil;
  959. newnode2^.next:=nil;
  960. end
  961. else
  962. begin
  963. last^.next:=newnode2;
  964. newnode2^.previous:=last;
  965. newnode2^.next:=nil;
  966. end;
  967. last:=newnode2;
  968. end;
  969. newnode:=newnode^.next;
  970. end;
  971. end;
  972. function tlinkedlist.empty:boolean;
  973. begin
  974. empty:=(first=nil);
  975. end;
  976. function tlinkedlist.count:longint;
  977. var
  978. i : longint;
  979. hp : plinkedlist_item;
  980. begin
  981. hp:=first;
  982. i:=0;
  983. while assigned(hp) do
  984. begin
  985. inc(i);
  986. hp:=hp^.next;
  987. end;
  988. count:=i;
  989. end;
  990. {****************************************************************************
  991. Tnamedindexobject
  992. ****************************************************************************}
  993. constructor Tnamedindexobject.init;
  994. begin
  995. { index }
  996. indexnr:=-1;
  997. next:=nil;
  998. { dictionary }
  999. left:=nil;
  1000. right:=nil;
  1001. _name:=nil;
  1002. speedvalue:=-1;
  1003. end;
  1004. constructor Tnamedindexobject.initname(const n:string);
  1005. begin
  1006. { index }
  1007. indexnr:=-1;
  1008. next:=nil;
  1009. { dictionary }
  1010. left:=nil;
  1011. right:=nil;
  1012. speedvalue:=-1;
  1013. _name:=stringdup(n);
  1014. end;
  1015. destructor Tnamedindexobject.done;
  1016. begin
  1017. stringdispose(_name);
  1018. end;
  1019. procedure Tnamedindexobject.setname(const n:string);
  1020. begin
  1021. if speedvalue=-1 then
  1022. begin
  1023. if assigned(_name) then
  1024. stringdispose(_name);
  1025. _name:=stringdup(n);
  1026. end;
  1027. end;
  1028. function Tnamedindexobject.name:string;
  1029. begin
  1030. if assigned(_name) then
  1031. name:=_name^
  1032. else
  1033. name:='';
  1034. end;
  1035. {****************************************************************************
  1036. TDICTIONARY
  1037. ****************************************************************************}
  1038. constructor Tdictionary.init;
  1039. begin
  1040. root:=nil;
  1041. hasharray:=nil;
  1042. noclear:=false;
  1043. replace_existing:=false;
  1044. end;
  1045. procedure Tdictionary.usehash;
  1046. begin
  1047. if not(assigned(root)) and
  1048. not(assigned(hasharray)) then
  1049. begin
  1050. new(hasharray);
  1051. fillchar(hasharray^,sizeof(hasharray^),0);
  1052. end;
  1053. end;
  1054. destructor Tdictionary.done;
  1055. begin
  1056. if not noclear then
  1057. clear;
  1058. if assigned(hasharray) then
  1059. dispose(hasharray);
  1060. end;
  1061. procedure Tdictionary.cleartree(obj:Pnamedindexobject);
  1062. begin
  1063. if assigned(obj^.left) then
  1064. cleartree(obj^.left);
  1065. if assigned(obj^.right) then
  1066. cleartree(obj^.right);
  1067. dispose(obj,done);
  1068. obj:=nil;
  1069. end;
  1070. procedure Tdictionary.clear;
  1071. var
  1072. w : longint;
  1073. begin
  1074. if assigned(root) then
  1075. cleartree(root);
  1076. if assigned(hasharray) then
  1077. for w:=-hasharraysize to hasharraysize do
  1078. if assigned(hasharray^[w]) then
  1079. cleartree(hasharray^[w]);
  1080. end;
  1081. function Tdictionary.delete(const s:string):Pnamedindexobject;
  1082. var p,speedvalue:longint;
  1083. n:Pnamedindexobject;
  1084. procedure insert_right_bottom(var root,Atree:Pnamedindexobject);
  1085. begin
  1086. while root^.right<>nil do
  1087. root:=root^.right;
  1088. root^.right:=Atree;
  1089. end;
  1090. function delete_from_tree(root:Pnamedindexobject):Pnamedindexobject;
  1091. type leftright=(left,right);
  1092. var lr:leftright;
  1093. oldroot:Pnamedindexobject;
  1094. begin
  1095. oldroot:=nil;
  1096. while (root<>nil) and (root^.speedvalue<>speedvalue) do
  1097. begin
  1098. oldroot:=root;
  1099. if speedvalue<root^.speedvalue then
  1100. begin
  1101. root:=root^.right;
  1102. lr:=right;
  1103. end
  1104. else
  1105. begin
  1106. root:=root^.left;
  1107. lr:=left;
  1108. end;
  1109. end;
  1110. while (root<>nil) and (root^._name^<>s) do
  1111. begin
  1112. oldroot:=root;
  1113. if s<root^._name^ then
  1114. begin
  1115. root:=root^.right;
  1116. lr:=right;
  1117. end
  1118. else
  1119. begin
  1120. root:=root^.left;
  1121. lr:=left;
  1122. end;
  1123. end;
  1124. if (oldroot=nil) or (root=nil) then
  1125. do_internalerror(218); {Internalerror is not available...}
  1126. if root^.left<>nil then
  1127. begin
  1128. {Now the node pointing to root must point to the left
  1129. subtree of root. The right subtree of root must be
  1130. connected to the right bottom of the left subtree.}
  1131. if lr=left then
  1132. oldroot^.left:=root^.left
  1133. else
  1134. oldroot^.right:=root^.left;
  1135. if root^.right<>nil then
  1136. insert_right_bottom(root^.left,root^.right);
  1137. end
  1138. else
  1139. {There is no left subtree. So we can just replace the node to
  1140. delete with the right subtree.}
  1141. if lr=left then
  1142. oldroot^.left:=root^.right
  1143. else
  1144. oldroot^.right:=root^.right;
  1145. delete_from_tree:=root;
  1146. end;
  1147. begin
  1148. speedvalue:=getspeedvalue(s);
  1149. n:=root;
  1150. if assigned(hasharray) then
  1151. begin
  1152. {First, check if the node to delete directly located under
  1153. the hasharray.}
  1154. p:=speedvalue mod hasharraysize;
  1155. n:=hasharray^[p];
  1156. if (n<>nil) and (n^.speedvalue=speedvalue) and
  1157. (n^._name^=s) then
  1158. begin
  1159. {The node to delete is directly located under the
  1160. hasharray. Make the hasharray point to the left
  1161. subtree of the node and place the right subtree on
  1162. the right-bottom of the left subtree.}
  1163. if n^.left<>nil then
  1164. begin
  1165. hasharray^[p]:=n^.left;
  1166. if n^.right<>nil then
  1167. insert_right_bottom(n^.left,n^.right);
  1168. end
  1169. else
  1170. hasharray^[p]:=n^.right;
  1171. delete:=n;
  1172. exit;
  1173. end;
  1174. end
  1175. else
  1176. begin
  1177. {First check if the node to delete is the root.}
  1178. if (root<>nil) and (n^.speedvalue=speedvalue)
  1179. and (n^._name^=s) then
  1180. begin
  1181. if n^.left<>nil then
  1182. begin
  1183. root:=n^.left;
  1184. if n^.right<>nil then
  1185. insert_right_bottom(n^.left,n^.right);
  1186. end
  1187. else
  1188. root:=n^.right;
  1189. delete:=n;
  1190. exit;
  1191. end;
  1192. end;
  1193. delete:=delete_from_tree(n);
  1194. end;
  1195. function Tdictionary.empty:boolean;
  1196. var
  1197. w : longint;
  1198. begin
  1199. if assigned(hasharray) then
  1200. begin
  1201. empty:=false;
  1202. for w:=-hasharraysize to hasharraysize do
  1203. if assigned(hasharray^[w]) then
  1204. exit;
  1205. empty:=true;
  1206. end
  1207. else
  1208. empty:=(root=nil);
  1209. end;
  1210. procedure Tdictionary.foreach(proc2call:Tnamedindexcallback);
  1211. procedure a(p:Pnamedindexobject);
  1212. begin
  1213. proc2call(p);
  1214. if assigned(p^.left) then
  1215. a(p^.left);
  1216. if assigned(p^.right) then
  1217. a(p^.right);
  1218. end;
  1219. var
  1220. i : longint;
  1221. begin
  1222. if assigned(hasharray) then
  1223. begin
  1224. for i:=-hasharraysize to hasharraysize do
  1225. if assigned(hasharray^[i]) then
  1226. a(hasharray^[i]);
  1227. end
  1228. else
  1229. if assigned(root) then
  1230. a(root);
  1231. end;
  1232. function Tdictionary.insert(obj:Pnamedindexobject):Pnamedindexobject;
  1233. begin
  1234. obj^.speedvalue:=getspeedvalue(obj^._name^);
  1235. if assigned(hasharray) then
  1236. insert:=insertnode(obj,hasharray^[obj^.speedvalue mod hasharraysize])
  1237. else
  1238. insert:=insertnode(obj,root);
  1239. end;
  1240. function tdictionary.insertnode(newnode:Pnamedindexobject;var currnode:Pnamedindexobject):Pnamedindexobject;
  1241. var
  1242. s1,s2:^string;
  1243. begin
  1244. if currnode=nil then
  1245. begin
  1246. currnode:=newnode;
  1247. insertnode:=currnode;
  1248. end
  1249. { first check speedvalue, to allow a fast insert }
  1250. else
  1251. if currnode^.speedvalue>newnode^.speedvalue then
  1252. insertnode:=insertnode(newnode,currnode^.right)
  1253. else
  1254. if currnode^.speedvalue<newnode^.speedvalue then
  1255. insertnode:=insertnode(newnode,currnode^.left)
  1256. else
  1257. begin
  1258. new(s1);
  1259. new(s2);
  1260. s1^:=currnode^._name^;
  1261. s2^:=newnode^._name^;
  1262. if s1^>s2^ then
  1263. begin
  1264. dispose(s2);
  1265. dispose(s1);
  1266. insertnode:=insertnode(newnode,currnode^.right);
  1267. end
  1268. else
  1269. if s1^<s2^ then
  1270. begin
  1271. dispose(s2);
  1272. dispose(s1);
  1273. insertnode:=insertnode(newnode,currnode^.left);
  1274. end
  1275. else
  1276. begin
  1277. dispose(s2);
  1278. dispose(s1);
  1279. if replace_existing and
  1280. assigned(currnode) then
  1281. begin
  1282. newnode^.left:=currnode^.left;
  1283. newnode^.right:=currnode^.right;
  1284. currnode:=newnode;
  1285. insertnode:=newnode;
  1286. end
  1287. else
  1288. insertnode:=currnode;
  1289. end;
  1290. end;
  1291. end;
  1292. procedure tdictionary.inserttree(currtree,currroot:Pnamedindexobject);
  1293. begin
  1294. if assigned(currtree) then
  1295. begin
  1296. inserttree(currtree^.left,currroot);
  1297. inserttree(currtree^.right,currroot);
  1298. currtree^.right:=nil;
  1299. currtree^.left:=nil;
  1300. insertnode(currtree,currroot);
  1301. end;
  1302. end;
  1303. function tdictionary.rename(const olds,news : string):Pnamedindexobject;
  1304. var
  1305. spdval : longint;
  1306. lasthp,
  1307. hp,hp2,hp3 : Pnamedindexobject;
  1308. begin
  1309. spdval:=getspeedvalue(olds);
  1310. if assigned(hasharray) then
  1311. hp:=hasharray^[spdval mod hasharraysize]
  1312. else
  1313. hp:=root;
  1314. lasthp:=nil;
  1315. while assigned(hp) do
  1316. begin
  1317. if spdval>hp^.speedvalue then
  1318. begin
  1319. lasthp:=hp;
  1320. hp:=hp^.left
  1321. end
  1322. else
  1323. if spdval<hp^.speedvalue then
  1324. begin
  1325. lasthp:=hp;
  1326. hp:=hp^.right
  1327. end
  1328. else
  1329. begin
  1330. if (hp^.name=olds) then
  1331. begin
  1332. { get in hp2 the replacer for the root or hasharr }
  1333. hp2:=hp^.left;
  1334. hp3:=hp^.right;
  1335. if not assigned(hp2) then
  1336. begin
  1337. hp2:=hp^.right;
  1338. hp3:=hp^.left;
  1339. end;
  1340. { remove entry from the tree }
  1341. if assigned(lasthp) then
  1342. begin
  1343. if lasthp^.left=hp then
  1344. lasthp^.left:=hp2
  1345. else
  1346. lasthp^.right:=hp2;
  1347. end
  1348. else
  1349. begin
  1350. if assigned(hasharray) then
  1351. hasharray^[spdval mod hasharraysize]:=hp2
  1352. else
  1353. root:=hp2;
  1354. end;
  1355. { reinsert the hp3 in the tree from hp2 }
  1356. inserttree(hp3,hp2);
  1357. { reset node with new values }
  1358. stringdispose(hp^._name);
  1359. hp^._name:=stringdup(news);
  1360. hp^.speedvalue:=getspeedvalue(news);
  1361. hp^.left:=nil;
  1362. hp^.right:=nil;
  1363. { reinsert }
  1364. if assigned(hasharray) then
  1365. rename:=insertnode(hp,hasharray^[hp^.speedvalue mod hasharraysize])
  1366. else
  1367. rename:=insertnode(hp,root);
  1368. exit;
  1369. end
  1370. else
  1371. if olds>hp^.name then
  1372. begin
  1373. lasthp:=hp;
  1374. hp:=hp^.left
  1375. end
  1376. else
  1377. begin
  1378. lasthp:=hp;
  1379. hp:=hp^.right;
  1380. end;
  1381. end;
  1382. end;
  1383. end;
  1384. function Tdictionary.search(const s:string):Pnamedindexobject;
  1385. begin
  1386. search:=speedsearch(s,getspeedvalue(s));
  1387. end;
  1388. function Tdictionary.speedsearch(const s:string;speedvalue:longint):Pnamedindexobject;
  1389. var
  1390. newnode:Pnamedindexobject;
  1391. begin
  1392. if assigned(hasharray) then
  1393. newnode:=hasharray^[speedvalue mod hasharraysize]
  1394. else
  1395. newnode:=root;
  1396. while assigned(newnode) do
  1397. begin
  1398. if speedvalue>newnode^.speedvalue then
  1399. newnode:=newnode^.left
  1400. else
  1401. if speedvalue<newnode^.speedvalue then
  1402. newnode:=newnode^.right
  1403. else
  1404. begin
  1405. if (newnode^._name^=s) then
  1406. begin
  1407. speedsearch:=newnode;
  1408. exit;
  1409. end
  1410. else
  1411. if s>newnode^._name^ then
  1412. newnode:=newnode^.left
  1413. else
  1414. newnode:=newnode^.right;
  1415. end;
  1416. end;
  1417. speedsearch:=nil;
  1418. end;
  1419. {****************************************************************************
  1420. tdynamicarray
  1421. ****************************************************************************}
  1422. constructor tdynamicarray.init(Aelemlen,Agrow:longint);
  1423. begin
  1424. posn:=0;
  1425. count:=0;
  1426. limit:=0;
  1427. data:=nil;
  1428. elemlen:=Aelemlen;
  1429. growcount:=Agrow;
  1430. grow;
  1431. end;
  1432. function tdynamicarray.size:longint;
  1433. begin
  1434. size:=limit*elemlen;
  1435. end;
  1436. function tdynamicarray.usedsize:longint;
  1437. begin
  1438. usedsize:=count*elemlen;
  1439. end;
  1440. procedure tdynamicarray.grow;
  1441. var
  1442. osize : longint;
  1443. odata : pchar;
  1444. begin
  1445. osize:=size;
  1446. odata:=data;
  1447. inc(limit,growcount);
  1448. getmem(data,size);
  1449. if assigned(odata) then
  1450. begin
  1451. move(odata^,data^,osize);
  1452. freemem(odata,osize);
  1453. end;
  1454. fillchar(data[osize],growcount*elemlen,0);
  1455. end;
  1456. procedure tdynamicarray.align(i:longint);
  1457. var
  1458. j : longint;
  1459. begin
  1460. j:=(posn*elemlen mod i);
  1461. if j<>0 then
  1462. begin
  1463. j:=i-j;
  1464. while limit<(posn+j) do
  1465. grow;
  1466. inc(posn,j);
  1467. if (posn>count) then
  1468. count:=posn;
  1469. end;
  1470. end;
  1471. procedure tdynamicarray.seek(i:longint);
  1472. begin
  1473. while limit<i do
  1474. grow;
  1475. posn:=i;
  1476. if (posn>count) then
  1477. count:=posn;
  1478. end;
  1479. procedure tdynamicarray.write(var d;len:longint);
  1480. begin
  1481. while limit<(posn+len) do
  1482. grow;
  1483. move(d,data[posn*elemlen],len*elemlen);
  1484. inc(posn,len);
  1485. if (posn>count) then
  1486. count:=posn;
  1487. end;
  1488. procedure tdynamicarray.read(var d;len:longint);
  1489. begin
  1490. move(data[posn*elemlen],d,len*elemlen);
  1491. inc(posn,len);
  1492. if (posn>count) then
  1493. count:=posn;
  1494. end;
  1495. procedure tdynamicarray.writepos(pos:longint;var d;len:longint);
  1496. begin
  1497. while limit<(pos+len) do
  1498. grow;
  1499. move(d,data[pos*elemlen],len*elemlen);
  1500. posn:=pos+len;
  1501. if (posn>count) then
  1502. count:=posn;
  1503. end;
  1504. procedure tdynamicarray.readpos(pos:longint;var d;len:longint);
  1505. begin
  1506. while limit<(pos+len) do
  1507. grow;
  1508. move(data[pos*elemlen],d,len*elemlen);
  1509. posn:=pos+len;
  1510. if (posn>count) then
  1511. count:=posn;
  1512. end;
  1513. destructor tdynamicarray.done;
  1514. begin
  1515. if assigned(data) then
  1516. freemem(data,size);
  1517. end;
  1518. {****************************************************************************
  1519. tindexarray
  1520. ****************************************************************************}
  1521. constructor tindexarray.init(Agrowsize:longint);
  1522. begin
  1523. growsize:=Agrowsize;
  1524. size:=0;
  1525. count:=0;
  1526. data:=nil;
  1527. first:=nil;
  1528. end;
  1529. destructor tindexarray.done;
  1530. begin
  1531. if assigned(data) then
  1532. begin
  1533. clear;
  1534. freemem(data,size*4);
  1535. data:=nil;
  1536. end;
  1537. end;
  1538. function tindexarray.search(nr:longint):Pnamedindexobject;
  1539. begin
  1540. if nr<=count then
  1541. search:=data^[nr]
  1542. else
  1543. search:=nil;
  1544. end;
  1545. procedure tindexarray.clear;
  1546. var
  1547. i : longint;
  1548. begin
  1549. for i:=1 to count do
  1550. if assigned(data^[i]) then
  1551. begin
  1552. dispose(data^[i],done);
  1553. data^[i]:=nil;
  1554. end;
  1555. count:=0;
  1556. first:=nil;
  1557. end;
  1558. procedure tindexarray.foreach(proc2call : Tnamedindexcallback);
  1559. var
  1560. i : longint;
  1561. begin
  1562. for i:=1 to count do
  1563. if assigned(data^[i]) then
  1564. proc2call(data^[i]);
  1565. end;
  1566. procedure tindexarray.grow(gsize:longint);
  1567. var
  1568. osize : longint;
  1569. odata : Pnamedindexobjectarray;
  1570. begin
  1571. osize:=size;
  1572. odata:=data;
  1573. inc(size,gsize);
  1574. getmem(data,size*4);
  1575. if assigned(odata) then
  1576. begin
  1577. move(odata^,data^,osize*4);
  1578. freemem(odata,osize*4);
  1579. end;
  1580. fillchar(data^[osize+1],gsize*4,0);
  1581. end;
  1582. procedure tindexarray.deleteindex(p:Pnamedindexobject);
  1583. var
  1584. i : longint;
  1585. begin
  1586. i:=p^.indexnr;
  1587. { update counter }
  1588. if i=count then
  1589. dec(count);
  1590. { update linked list }
  1591. while (i>0) do
  1592. begin
  1593. dec(i);
  1594. if (i>0) and assigned(data^[i]) then
  1595. begin
  1596. data^[i]^.next:=data^[p^.indexnr]^.next;
  1597. break;
  1598. end;
  1599. end;
  1600. if i=0 then
  1601. first:=p^.next;
  1602. data^[p^.indexnr]:=nil;
  1603. { clear entry }
  1604. p^.indexnr:=-1;
  1605. p^.next:=nil;
  1606. end;
  1607. procedure tindexarray.delete(p:Pnamedindexobject);
  1608. begin
  1609. deleteindex(p);
  1610. dispose(p,done);
  1611. p:=nil;
  1612. end;
  1613. procedure tindexarray.insert(p:Pnamedindexobject);
  1614. var
  1615. i : longint;
  1616. begin
  1617. if p^.indexnr=-1 then
  1618. begin
  1619. inc(count);
  1620. p^.indexnr:=count;
  1621. end;
  1622. if p^.indexnr>count then
  1623. count:=p^.indexnr;
  1624. if count>size then
  1625. grow(((count div growsize)+1)*growsize);
  1626. data^[p^.indexnr]:=p;
  1627. { update linked list backward }
  1628. i:=p^.indexnr;
  1629. while (i>0) do
  1630. begin
  1631. dec(i);
  1632. if (i>0) and assigned(data^[i]) then
  1633. begin
  1634. data^[i]^.next:=p;
  1635. break;
  1636. end;
  1637. end;
  1638. if i=0 then
  1639. first:=p;
  1640. { update linked list forward }
  1641. i:=p^.indexnr;
  1642. while (i<=count) do
  1643. begin
  1644. inc(i);
  1645. if (i<=count) and assigned(data^[i]) then
  1646. begin
  1647. p^.next:=data^[i];
  1648. exit;
  1649. end;
  1650. end;
  1651. if i>count then
  1652. p^.next:=nil;
  1653. end;
  1654. {$ifdef BUFFEREDFILE}
  1655. {****************************************************************************
  1656. TBUFFEREDFILE
  1657. ****************************************************************************}
  1658. Const
  1659. crcseed = $ffffffff;
  1660. crctable : array[0..255] of longint = (
  1661. $00000000,$77073096,$ee0e612c,$990951ba,$076dc419,$706af48f,
  1662. $e963a535,$9e6495a3,$0edb8832,$79dcb8a4,$e0d5e91e,$97d2d988,
  1663. $09b64c2b,$7eb17cbd,$e7b82d07,$90bf1d91,$1db71064,$6ab020f2,
  1664. $f3b97148,$84be41de,$1adad47d,$6ddde4eb,$f4d4b551,$83d385c7,
  1665. $136c9856,$646ba8c0,$fd62f97a,$8a65c9ec,$14015c4f,$63066cd9,
  1666. $fa0f3d63,$8d080df5,$3b6e20c8,$4c69105e,$d56041e4,$a2677172,
  1667. $3c03e4d1,$4b04d447,$d20d85fd,$a50ab56b,$35b5a8fa,$42b2986c,
  1668. $dbbbc9d6,$acbcf940,$32d86ce3,$45df5c75,$dcd60dcf,$abd13d59,
  1669. $26d930ac,$51de003a,$c8d75180,$bfd06116,$21b4f4b5,$56b3c423,
  1670. $cfba9599,$b8bda50f,$2802b89e,$5f058808,$c60cd9b2,$b10be924,
  1671. $2f6f7c87,$58684c11,$c1611dab,$b6662d3d,$76dc4190,$01db7106,
  1672. $98d220bc,$efd5102a,$71b18589,$06b6b51f,$9fbfe4a5,$e8b8d433,
  1673. $7807c9a2,$0f00f934,$9609a88e,$e10e9818,$7f6a0dbb,$086d3d2d,
  1674. $91646c97,$e6635c01,$6b6b51f4,$1c6c6162,$856530d8,$f262004e,
  1675. $6c0695ed,$1b01a57b,$8208f4c1,$f50fc457,$65b0d9c6,$12b7e950,
  1676. $8bbeb8ea,$fcb9887c,$62dd1ddf,$15da2d49,$8cd37cf3,$fbd44c65,
  1677. $4db26158,$3ab551ce,$a3bc0074,$d4bb30e2,$4adfa541,$3dd895d7,
  1678. $a4d1c46d,$d3d6f4fb,$4369e96a,$346ed9fc,$ad678846,$da60b8d0,
  1679. $44042d73,$33031de5,$aa0a4c5f,$dd0d7cc9,$5005713c,$270241aa,
  1680. $be0b1010,$c90c2086,$5768b525,$206f85b3,$b966d409,$ce61e49f,
  1681. $5edef90e,$29d9c998,$b0d09822,$c7d7a8b4,$59b33d17,$2eb40d81,
  1682. $b7bd5c3b,$c0ba6cad,$edb88320,$9abfb3b6,$03b6e20c,$74b1d29a,
  1683. $ead54739,$9dd277af,$04db2615,$73dc1683,$e3630b12,$94643b84,
  1684. $0d6d6a3e,$7a6a5aa8,$e40ecf0b,$9309ff9d,$0a00ae27,$7d079eb1,
  1685. $f00f9344,$8708a3d2,$1e01f268,$6906c2fe,$f762575d,$806567cb,
  1686. $196c3671,$6e6b06e7,$fed41b76,$89d32be0,$10da7a5a,$67dd4acc,
  1687. $f9b9df6f,$8ebeeff9,$17b7be43,$60b08ed5,$d6d6a3e8,$a1d1937e,
  1688. $38d8c2c4,$4fdff252,$d1bb67f1,$a6bc5767,$3fb506dd,$48b2364b,
  1689. $d80d2bda,$af0a1b4c,$36034af6,$41047a60,$df60efc3,$a867df55,
  1690. $316e8eef,$4669be79,$cb61b38c,$bc66831a,$256fd2a0,$5268e236,
  1691. $cc0c7795,$bb0b4703,$220216b9,$5505262f,$c5ba3bbe,$b2bd0b28,
  1692. $2bb45a92,$5cb36a04,$c2d7ffa7,$b5d0cf31,$2cd99e8b,$5bdeae1d,
  1693. $9b64c2b0,$ec63f226,$756aa39c,$026d930a,$9c0906a9,$eb0e363f,
  1694. $72076785,$05005713,$95bf4a82,$e2b87a14,$7bb12bae,$0cb61b38,
  1695. $92d28e9b,$e5d5be0d,$7cdcefb7,$0bdbdf21,$86d3d2d4,$f1d4e242,
  1696. $68ddb3f8,$1fda836e,$81be16cd,$f6b9265b,$6fb077e1,$18b74777,
  1697. $88085ae6,$ff0f6a70,$66063bca,$11010b5c,$8f659eff,$f862ae69,
  1698. $616bffd3,$166ccf45,$a00ae278,$d70dd2ee,$4e048354,$3903b3c2,
  1699. $a7672661,$d06016f7,$4969474d,$3e6e77db,$aed16a4a,$d9d65adc,
  1700. $40df0b66,$37d83bf0,$a9bcae53,$debb9ec5,$47b2cf7f,$30b5ffe9,
  1701. $bdbdf21c,$cabac28a,$53b39330,$24b4a3a6,$bad03605,$cdd70693,
  1702. $54de5729,$23d967bf,$b3667a2e,$c4614ab8,$5d681b02,$2a6f2b94,
  1703. $b40bbe37,$c30c8ea1,$5a05df1b,$2d02ef8d);
  1704. constructor tbufferedfile.init(const filename : string;_bufsize : longint);
  1705. begin
  1706. assign(f,filename);
  1707. bufsize:=_bufsize;
  1708. bufpos:=0;
  1709. buflast:=0;
  1710. do_crc:=false;
  1711. iomode:=0;
  1712. tempclosed:=false;
  1713. change_endian:=false;
  1714. clear_crc;
  1715. end;
  1716. destructor tbufferedfile.done;
  1717. begin
  1718. close;
  1719. end;
  1720. procedure tbufferedfile.clear_crc;
  1721. begin
  1722. crc:=crcseed;
  1723. end;
  1724. procedure tbufferedfile.setbuf(p : pchar;s : longint);
  1725. begin
  1726. flush;
  1727. freemem(buf,bufsize);
  1728. bufsize:=s;
  1729. buf:=p;
  1730. end;
  1731. function tbufferedfile.reset:boolean;
  1732. var
  1733. ofm : byte;
  1734. begin
  1735. ofm:=filemode;
  1736. iomode:=1;
  1737. getmem(buf,bufsize);
  1738. filemode:=0;
  1739. {$I-}
  1740. system.reset(f,1);
  1741. {$I+}
  1742. reset:=(ioresult=0);
  1743. filemode:=ofm;
  1744. end;
  1745. procedure tbufferedfile.rewrite;
  1746. begin
  1747. iomode:=2;
  1748. getmem(buf,bufsize);
  1749. system.rewrite(f,1);
  1750. end;
  1751. procedure tbufferedfile.flush;
  1752. var
  1753. {$ifdef FPC}
  1754. count : longint;
  1755. {$else}
  1756. count : integer;
  1757. {$endif}
  1758. begin
  1759. if iomode=2 then
  1760. begin
  1761. if bufpos=0 then
  1762. exit;
  1763. blockwrite(f,buf^,bufpos)
  1764. end
  1765. else if iomode=1 then
  1766. if buflast=bufpos then
  1767. begin
  1768. blockread(f,buf^,bufsize,count);
  1769. buflast:=count;
  1770. end;
  1771. bufpos:=0;
  1772. end;
  1773. function tbufferedfile.getftime : longint;
  1774. var
  1775. l : longint;
  1776. {$ifdef linux}
  1777. Info : Stat;
  1778. {$endif}
  1779. begin
  1780. {$ifndef linux}
  1781. { this only works if the file is open !! }
  1782. dos.getftime(f,l);
  1783. {$else}
  1784. Fstat(f,Info);
  1785. l:=info.mtime;
  1786. {$endif}
  1787. getftime:=l;
  1788. end;
  1789. function tbufferedfile.getsize : longint;
  1790. begin
  1791. getsize:=filesize(f);
  1792. end;
  1793. procedure tbufferedfile.seek(l : longint);
  1794. begin
  1795. if iomode=2 then
  1796. begin
  1797. flush;
  1798. system.seek(f,l);
  1799. end
  1800. else if iomode=1 then
  1801. begin
  1802. { forces a reload }
  1803. bufpos:=buflast;
  1804. system.seek(f,l);
  1805. flush;
  1806. end;
  1807. end;
  1808. type
  1809. {$ifdef tp}
  1810. bytearray1 = array [1..65535] of byte;
  1811. {$else}
  1812. bytearray1 = array [1..10000000] of byte;
  1813. {$endif}
  1814. procedure tbufferedfile.read_data(var data;bytes : longint;var count : longint);
  1815. var
  1816. p : pchar;
  1817. c,i : longint;
  1818. begin
  1819. p:=pchar(@data);
  1820. count:=0;
  1821. while bytes-count>0 do
  1822. begin
  1823. if bytes-count>buflast-bufpos then
  1824. begin
  1825. move((buf+bufpos)^,(p+count)^,buflast-bufpos);
  1826. inc(count,buflast-bufpos);
  1827. bufpos:=buflast;
  1828. flush;
  1829. { can't we read anything ? }
  1830. if bufpos=buflast then
  1831. break;
  1832. end
  1833. else
  1834. begin
  1835. move((buf+bufpos)^,(p+count)^,bytes-count);
  1836. inc(bufpos,bytes-count);
  1837. count:=bytes;
  1838. break;
  1839. end;
  1840. end;
  1841. if do_crc then
  1842. begin
  1843. c:=crc;
  1844. for i:=1 to bytes do
  1845. c:=(c shr 8) xor crctable[byte(c) xor (bytearray1(data)[i])];
  1846. crc:=c;
  1847. end;
  1848. end;
  1849. procedure tbufferedfile.write_data(var data;count : longint);
  1850. var
  1851. c,i : longint;
  1852. begin
  1853. if bufpos+count>bufsize then
  1854. flush;
  1855. move(data,(buf+bufpos)^,count);
  1856. inc(bufpos,count);
  1857. if do_crc then
  1858. begin
  1859. c:=crc;
  1860. for i:=1 to count do
  1861. c:=(c shr 8) xor crctable[byte(c) xor (bytearray1(data)[i])];
  1862. crc:=c;
  1863. end;
  1864. end;
  1865. function tbufferedfile.getcrc : longint;
  1866. begin
  1867. getcrc:=crc xor crcseed;
  1868. end;
  1869. procedure tbufferedfile.write_string(const s : string);
  1870. begin
  1871. if bufpos+length(s)>bufsize then
  1872. flush;
  1873. { why is there not CRC here ??? }
  1874. move(s[1],(buf+bufpos)^,length(s));
  1875. inc(bufpos,length(s));
  1876. { should be
  1877. write_data(s[1],length(s)); }
  1878. end;
  1879. procedure tbufferedfile.write_pchar(p : pchar);
  1880. var
  1881. l : longint;
  1882. begin
  1883. l:=strlen(p);
  1884. if l>=bufsize then
  1885. do_internalerror(222);
  1886. { why is there not CRC here ???}
  1887. if bufpos+l>bufsize then
  1888. flush;
  1889. move(p^,(buf+bufpos)^,l);
  1890. inc(bufpos,l);
  1891. { should be
  1892. write_data(p^,l); }
  1893. end;
  1894. procedure tbufferedfile.write_byte(b : byte);
  1895. begin
  1896. write_data(b,sizeof(byte));
  1897. end;
  1898. procedure tbufferedfile.write_long(l : longint);
  1899. var
  1900. w1,w2 : word;
  1901. begin
  1902. if change_endian then
  1903. begin
  1904. w1:=l and $ffff;
  1905. w2:=l shr 16;
  1906. l:=swap(w2)+(longint(swap(w1)) shl 16);
  1907. end;
  1908. write_data(l,sizeof(longint));
  1909. end;
  1910. procedure tbufferedfile.write_word(w : word);
  1911. begin
  1912. if change_endian then
  1913. begin
  1914. w:=swap(w);
  1915. end;
  1916. write_data(w,sizeof(word));
  1917. end;
  1918. procedure tbufferedfile.write_double(d : double);
  1919. begin
  1920. write_data(d,sizeof(double));
  1921. end;
  1922. function tbufferedfile.getpath : string;
  1923. begin
  1924. {$ifdef dummy}
  1925. getpath:=strpas(filerec(f).name);
  1926. {$endif}
  1927. getpath:='';
  1928. end;
  1929. procedure tbufferedfile.close;
  1930. begin
  1931. if iomode<>0 then
  1932. begin
  1933. flush;
  1934. system.close(f);
  1935. freemem(buf,bufsize);
  1936. buf:=nil;
  1937. iomode:=0;
  1938. end;
  1939. end;
  1940. procedure tbufferedfile.tempclose;
  1941. begin
  1942. if iomode<>0 then
  1943. begin
  1944. temppos:=system.filepos(f);
  1945. tempmode:=iomode;
  1946. tempclosed:=true;
  1947. system.close(f);
  1948. iomode:=0;
  1949. end
  1950. else
  1951. tempclosed:=false;
  1952. end;
  1953. procedure tbufferedfile.tempreopen;
  1954. var
  1955. ofm : byte;
  1956. begin
  1957. if tempclosed then
  1958. begin
  1959. case tempmode of
  1960. 1 : begin
  1961. ofm:=filemode;
  1962. iomode:=1;
  1963. filemode:=0;
  1964. system.reset(f,1);
  1965. filemode:=ofm;
  1966. end;
  1967. 2 : begin
  1968. iomode:=2;
  1969. system.rewrite(f,1);
  1970. end;
  1971. end;
  1972. system.seek(f,temppos);
  1973. tempclosed:=false;
  1974. end;
  1975. end;
  1976. {$endif BUFFEREDFILE}
  1977. end.
  1978. {
  1979. $Log$
  1980. Revision 1.47 1999-11-15 14:59:55 pierre
  1981. * last was not handled correctly in TStringQueue
  1982. Revision 1.46 1999/11/14 15:56:36 peter
  1983. * fixed stringqueue.delete
  1984. Revision 1.45 1999/11/12 11:03:49 peter
  1985. * searchpaths changed to stringqueue object
  1986. Revision 1.44 1999/11/06 14:34:20 peter
  1987. * truncated log to 20 revs
  1988. Revision 1.43 1999/10/26 12:30:41 peter
  1989. * const parameter is now checked
  1990. * better and generic check if a node can be used for assigning
  1991. * export fixes
  1992. * procvar equal works now (it never had worked at least from 0.99.8)
  1993. * defcoll changed to linkedlist with pparaitem so it can easily be
  1994. walked both directions
  1995. Revision 1.42 1999/09/07 15:08:51 pierre
  1996. * runerror => do_internalerror
  1997. Revision 1.41 1999/08/24 13:13:57 peter
  1998. * MEMDEBUG to see the sizes of asmlist,asmsymbols,symtables
  1999. Revision 1.40 1999/08/12 23:19:05 pierre
  2000. * added inherited init call to tstringcontainer.init_no_double for Peter
  2001. Revision 1.39 1999/08/05 14:58:07 florian
  2002. * some fixes for the floating point registers
  2003. * more things for the new code generator
  2004. Revision 1.38 1999/07/18 10:19:46 florian
  2005. * made it compilable with Dlephi 4 again
  2006. + fixed problem with large stack allocations on win32
  2007. Revision 1.37 1999/07/03 00:29:45 peter
  2008. * new link writing to the ppu, one .ppu is needed for all link types,
  2009. static (.o) is now always created also when smartlinking is used
  2010. Revision 1.36 1999/06/23 11:13:20 peter
  2011. * fixed linebreak
  2012. Revision 1.35 1999/06/23 11:07:23 daniel
  2013. * Tdictionary.delete
  2014. Revision 1.33.2.1 1999/06/15 10:12:22 peter
  2015. * fixed inserttree which didn't reset left,right
  2016. Revision 1.33 1999/05/31 23:33:21 peter
  2017. * fixed tdictionary rename which didn't reset left,right when
  2018. reinserting
  2019. Revision 1.32 1999/05/27 19:44:23 peter
  2020. * removed oldasm
  2021. * plabel -> pasmlabel
  2022. * -a switches to source writing automaticly
  2023. * assembler readers OOPed
  2024. * asmsymbol automaticly external
  2025. * jumptables and other label fixes for asm readers
  2026. Revision 1.31 1999/05/21 13:54:59 peter
  2027. * NEWLAB for label as symbol
  2028. Revision 1.30 1999/05/21 10:38:59 peter
  2029. * fixed deleteindex which didn't reset indexnr and set first wrong
  2030. Revision 1.29 1999/05/08 19:47:27 peter
  2031. * indexarray.delete resets pointer after dispose
  2032. Revision 1.28 1999/05/05 10:05:48 florian
  2033. * a delphi compiled compiler recompiles ppc
  2034. Revision 1.27 1999/05/05 09:19:03 florian
  2035. * more fixes to get it with delphi running
  2036. Revision 1.26 1999/04/21 09:43:31 peter
  2037. * storenumber works
  2038. * fixed some typos in double_checksum
  2039. + incompatible types type1 and type2 message (with storenumber)
  2040. Revision 1.25 1999/04/15 10:01:44 peter
  2041. * small update for storenumber
  2042. Revision 1.24 1999/04/14 09:14:47 peter
  2043. * first things to store the symbol/def number in the ppu
  2044. }