cobjects.pas 62 KB

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