cobjects.pas 62 KB

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