cobjects.pas 61 KB

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