cobjects.pas 62 KB

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