cobjects.pas 60 KB

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