cobjects.pas 61 KB

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