cobjects.pas 63 KB

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