cobjects.pas 61 KB

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