cobjects.pas 63 KB

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