cobjects.pas 62 KB

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