cobjects.pas 61 KB

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