cobjects.pas 62 KB

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