cobjects.pas 63 KB

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