cobjects.pas 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217
  1. {
  2. $Id$
  3. Copyright (c) 1993-98 by Florian Klaempfl
  4. This module provides some basic objects
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. {$ifdef tp}
  19. {$E+,N+,D+,F+}
  20. {$endif}
  21. {$I-}
  22. {$R-}{ necessary for crc calculation }
  23. unit cobjects;
  24. interface
  25. uses
  26. strings
  27. {$ifndef linux}
  28. ,dos
  29. {$else}
  30. ,linux
  31. {$endif}
  32. ;
  33. type
  34. pstring = ^string;
  35. pfileposinfo = ^tfileposinfo;
  36. tfileposinfo = record
  37. line : longint;
  38. column : word;
  39. fileindex : word;
  40. end;
  41. { some help data types }
  42. pstringitem = ^tstringitem;
  43. tstringitem = record
  44. data : pstring;
  45. next : pstringitem;
  46. fileinfo : tfileposinfo; { pointer to tinputfile }
  47. end;
  48. plinkedlist_item = ^tlinkedlist_item;
  49. tlinkedlist_item = object
  50. next,previous : plinkedlist_item;
  51. { does nothing }
  52. constructor init;
  53. destructor done;virtual;
  54. end;
  55. pstring_item = ^tstring_item;
  56. tstring_item = object(tlinkedlist_item)
  57. str : pstring;
  58. constructor init(const s : string);
  59. destructor done;virtual;
  60. end;
  61. { this implements a double linked list }
  62. plinkedlist = ^tlinkedlist;
  63. tlinkedlist = object
  64. first,last : plinkedlist_item;
  65. constructor init;
  66. destructor done;
  67. { disposes the items of the list }
  68. procedure clear;
  69. { concats a new item at the end }
  70. procedure concat(p : plinkedlist_item);
  71. { inserts a new item at the begin }
  72. procedure insert(p : plinkedlist_item);
  73. { inserts another list at the begin and make this list empty }
  74. procedure insertlist(p : plinkedlist);
  75. { concats another list at the end and make this list empty }
  76. procedure concatlist(p : plinkedlist);
  77. { removes p from the list (p isn't disposed) }
  78. { it's not tested if p is in the list ! }
  79. procedure remove(p : plinkedlist_item);
  80. { is the linkedlist empty ? }
  81. function empty:boolean;
  82. end;
  83. { String Queue}
  84. PStringQueue=^TStringQueue;
  85. TStringQueue=object
  86. first,last : PStringItem;
  87. constructor Init;
  88. destructor Done;
  89. function Empty:boolean;
  90. function Get:string;
  91. procedure Insert(const s:string);
  92. procedure Concat(const s:string);
  93. procedure Clear;
  94. end;
  95. { string container }
  96. pstringcontainer = ^tstringcontainer;
  97. tstringcontainer = object
  98. root,
  99. last : pstringitem;
  100. doubles : boolean; { if this is set to true, doubles are allowed }
  101. constructor init;
  102. constructor init_no_double;
  103. destructor done;
  104. { true when the container is empty }
  105. function empty:boolean;
  106. { inserts a string }
  107. procedure insert(const s : string);
  108. procedure insert_with_tokeninfo(const s : string;const file_info : tfileposinfo);
  109. { gets a string }
  110. function get : string;
  111. function get_with_tokeninfo(var file_info : tfileposinfo) : string;
  112. { true if string is in the container }
  113. function find(const s:string):boolean;
  114. { deletes all strings }
  115. procedure clear;
  116. end;
  117. {$ifdef BUFFEREDFILE}
  118. { this is implemented to allow buffered binary I/O }
  119. pbufferedfile = ^tbufferedfile;
  120. tbufferedfile = object
  121. f : file;
  122. buf : pchar;
  123. bufsize,buflast,bufpos : longint;
  124. { 0 closed, 1 input, 2 output }
  125. iomode : byte;
  126. { true, if the compile should change the endian of the output }
  127. change_endian : boolean;
  128. { calcules a crc for the file, }
  129. { but it's assumed, that there no seek while do_crc is true }
  130. do_crc : boolean;
  131. crc : longint;
  132. { temporary closing feature }
  133. tempclosed : boolean;
  134. tempmode : byte;
  135. temppos : longint;
  136. { inits a buffer with the size bufsize which is assigned to }
  137. { the file filename }
  138. constructor init(const filename : string;_bufsize : longint);
  139. { closes the file, if needed, and releases the memory }
  140. destructor done;virtual;
  141. { opens the file for input, other accesses are rejected }
  142. function reset:boolean;
  143. { opens the file for output, other accesses are rejected }
  144. procedure rewrite;
  145. { reads or writes the buffer from or to disk }
  146. procedure flush;
  147. { writes a string to the file }
  148. { the string is written without a length byte }
  149. procedure write_string(const s : string);
  150. { writes a zero terminated string }
  151. procedure write_pchar(p : pchar);
  152. { write specific data types, takes care of }
  153. { byte order }
  154. procedure write_byte(b : byte);
  155. procedure write_word(w : word);
  156. procedure write_long(l : longint);
  157. procedure write_double(d : double);
  158. { writes any data }
  159. procedure write_data(var data;count : longint);
  160. { reads any data }
  161. procedure read_data(var data;bytes : longint;var count : longint);
  162. { closes the file and releases the buffer }
  163. procedure close;
  164. { temporary closing }
  165. procedure tempclose;
  166. procedure tempreopen;
  167. { goto the given position }
  168. procedure seek(l : longint);
  169. { installes an user defined buffer }
  170. { and releases the old one, but be }
  171. { careful, if the old buffer contains }
  172. { data, this data is lost }
  173. procedure setbuf(p : pchar;s : longint);
  174. { reads the file time stamp of the file, }
  175. { the file must be opened }
  176. function getftime : longint;
  177. { returns filesize }
  178. function getsize : longint;
  179. { returns the path }
  180. function getpath : string;
  181. { resets the crc }
  182. procedure clear_crc;
  183. { returns the crc }
  184. function getcrc : longint;
  185. end;
  186. {$endif BUFFEREDFILE}
  187. { releases the string p and assignes nil to p }
  188. { if p=nil then freemem isn't called }
  189. procedure stringdispose(var p : pstring);
  190. { idem for ansistrings }
  191. procedure ansistringdispose(var p : pchar;length : longint);
  192. { allocates mem for a copy of s, copies s to this mem and returns }
  193. { a pointer to this mem }
  194. function stringdup(const s : string) : pstring;
  195. { allocates memory for s and copies s as zero terminated string
  196. to that mem and returns a pointer to that mem }
  197. function strpnew(const s : string) : pchar;
  198. { makes a char lowercase, with spanish, french and german char set }
  199. function lowercase(c : char) : char;
  200. { makes zero terminated string to a pascal string }
  201. { the data in p is modified and p is returned }
  202. function pchar2pstring(p : pchar) : pstring;
  203. { ambivalent to pchar2pstring }
  204. function pstring2pchar(p : pstring) : pchar;
  205. implementation
  206. function pchar2pstring(p : pchar) : pstring;
  207. var
  208. w,i : longint;
  209. begin
  210. w:=strlen(p);
  211. for i:=w-1 downto 0 do
  212. p[i+1]:=p[i];
  213. p[0]:=chr(w);
  214. pchar2pstring:=pstring(p);
  215. end;
  216. function pstring2pchar(p : pstring) : pchar;
  217. var
  218. w,i : longint;
  219. begin
  220. w:=length(p^);
  221. for i:=1 to w do
  222. p^[i-1]:=p^[i];
  223. p^[w]:=#0;
  224. pstring2pchar:=pchar(p);
  225. end;
  226. function lowercase(c : char) : char;
  227. begin
  228. case c of
  229. #65..#90 : c := chr(ord (c) + 32);
  230. #154 : c:=#129; { german }
  231. #142 : c:=#132; { german }
  232. #153 : c:=#148; { german }
  233. #144 : c:=#130; { french }
  234. #128 : c:=#135; { french }
  235. #143 : c:=#134; { swedish/norge (?) }
  236. #165 : c:=#164; { spanish }
  237. #228 : c:=#229; { greek }
  238. #226 : c:=#231; { greek }
  239. #232 : c:=#227; { greek }
  240. end;
  241. lowercase := c;
  242. end;
  243. function strpnew(const s : string) : pchar;
  244. var
  245. p : pchar;
  246. begin
  247. getmem(p,length(s)+1);
  248. strpcopy(p,s);
  249. strpnew:=p;
  250. end;
  251. procedure stringdispose(var p : pstring);
  252. begin
  253. if assigned(p) then
  254. freemem(p,length(p^)+1);
  255. p:=nil;
  256. end;
  257. procedure ansistringdispose(var p : pchar;length : longint);
  258. begin
  259. if assigned(p) then
  260. freemem(p,length+1);
  261. p:=nil;
  262. end;
  263. function stringdup(const s : string) : pstring;
  264. var
  265. p : pstring;
  266. begin
  267. getmem(p,length(s)+1);
  268. p^:=s;
  269. stringdup:=p;
  270. end;
  271. {****************************************************************************
  272. TStringQueue
  273. ****************************************************************************}
  274. constructor TStringQueue.Init;
  275. begin
  276. first:=nil;
  277. end;
  278. function TStringQueue.Empty:boolean;
  279. begin
  280. Empty:=(first=nil);
  281. end;
  282. function TStringQueue.Get:string;
  283. var
  284. hp : pstringitem;
  285. begin
  286. if first=nil then
  287. begin
  288. Get:='';
  289. exit;
  290. end;
  291. Get:=first^.data^;
  292. stringdispose(first^.data);
  293. hp:=first;
  294. first:=first^.next;
  295. dispose(hp);
  296. end;
  297. procedure TStringQueue.Insert(const s:string);
  298. var
  299. hp : pstringitem;
  300. begin
  301. new(hp);
  302. hp^.next:=first;
  303. hp^.data:=stringdup(s);
  304. first:=hp;
  305. if last=nil then
  306. last:=hp;
  307. end;
  308. procedure TStringQueue.Concat(const s:string);
  309. var
  310. hp : pstringitem;
  311. begin
  312. new(hp);
  313. hp^.next:=nil;
  314. hp^.data:=stringdup(s);
  315. if first=nil then
  316. first:=hp
  317. else
  318. last^.next:=hp;
  319. last:=hp;
  320. end;
  321. procedure TStringQueue.Clear;
  322. var
  323. hp : pstringitem;
  324. begin
  325. while (first<>nil) do
  326. begin
  327. hp:=first;
  328. stringdispose(first^.data);
  329. first:=first^.next;
  330. dispose(hp);
  331. end;
  332. end;
  333. destructor TStringQueue.Done;
  334. begin
  335. Clear;
  336. end;
  337. {****************************************************************************
  338. TSTRINGCONTAINER
  339. ****************************************************************************}
  340. constructor tstringcontainer.init;
  341. begin
  342. root:=nil;
  343. last:=nil;
  344. doubles:=true;
  345. end;
  346. constructor tstringcontainer.init_no_double;
  347. begin
  348. root:=nil;
  349. last:=nil;
  350. doubles:=false;
  351. end;
  352. destructor tstringcontainer.done;
  353. begin
  354. clear;
  355. end;
  356. function tstringcontainer.empty:boolean;
  357. begin
  358. empty:=(root=nil);
  359. end;
  360. procedure tstringcontainer.insert(const s : string);
  361. var
  362. hp : pstringitem;
  363. begin
  364. if not(doubles) then
  365. begin
  366. hp:=root;
  367. while assigned(hp) do
  368. begin
  369. if hp^.data^=s then exit;
  370. hp:=hp^.next;
  371. end;
  372. end;
  373. new(hp);
  374. hp^.next:=nil;
  375. hp^.data:=stringdup(s);
  376. if root=nil then root:=hp
  377. else last^.next:=hp;
  378. last:=hp;
  379. end;
  380. procedure tstringcontainer.insert_with_tokeninfo(const s : string; const file_info : tfileposinfo);
  381. var
  382. hp : pstringitem;
  383. begin
  384. if not(doubles) then
  385. begin
  386. hp:=root;
  387. while assigned(hp) do
  388. begin
  389. if hp^.data^=s then exit;
  390. hp:=hp^.next;
  391. end;
  392. end;
  393. new(hp);
  394. hp^.next:=nil;
  395. hp^.data:=stringdup(s);
  396. hp^.fileinfo:=file_info;
  397. if root=nil then root:=hp
  398. else last^.next:=hp;
  399. last:=hp;
  400. end;
  401. procedure tstringcontainer.clear;
  402. var
  403. hp : pstringitem;
  404. begin
  405. hp:=root;
  406. while assigned(hp) do
  407. begin
  408. stringdispose(hp^.data);
  409. root:=hp^.next;
  410. dispose(hp);
  411. hp:=root;
  412. end;
  413. last:=nil;
  414. root:=nil;
  415. end;
  416. function tstringcontainer.get : string;
  417. var
  418. hp : pstringitem;
  419. begin
  420. if root=nil then
  421. get:=''
  422. else
  423. begin
  424. get:=root^.data^;
  425. hp:=root;
  426. root:=root^.next;
  427. stringdispose(hp^.data);
  428. dispose(hp);
  429. end;
  430. end;
  431. function tstringcontainer.get_with_tokeninfo(var file_info : tfileposinfo) : string;
  432. var
  433. hp : pstringitem;
  434. begin
  435. if root=nil then
  436. begin
  437. get_with_tokeninfo:='';
  438. file_info.fileindex:=0;
  439. file_info.line:=0;
  440. file_info.column:=0;
  441. end
  442. else
  443. begin
  444. get_with_tokeninfo:=root^.data^;
  445. hp:=root;
  446. root:=root^.next;
  447. stringdispose(hp^.data);
  448. file_info:=hp^.fileinfo;
  449. dispose(hp);
  450. end;
  451. end;
  452. function tstringcontainer.find(const s:string):boolean;
  453. var
  454. hp : pstringitem;
  455. begin
  456. find:=false;
  457. hp:=root;
  458. while assigned(hp) do
  459. begin
  460. if hp^.data^=s then
  461. begin
  462. find:=true;
  463. exit;
  464. end;
  465. hp:=hp^.next;
  466. end;
  467. end;
  468. {****************************************************************************
  469. TLINKEDLIST_ITEM
  470. ****************************************************************************}
  471. constructor tlinkedlist_item.init;
  472. begin
  473. previous:=nil;
  474. next:=nil;
  475. end;
  476. destructor tlinkedlist_item.done;
  477. begin
  478. end;
  479. {****************************************************************************
  480. TSTRING_ITEM
  481. ****************************************************************************}
  482. constructor tstring_item.init(const s : string);
  483. begin
  484. str:=stringdup(s);
  485. end;
  486. destructor tstring_item.done;
  487. begin
  488. stringdispose(str);
  489. inherited done;
  490. end;
  491. {****************************************************************************
  492. TLINKEDLIST
  493. ****************************************************************************}
  494. constructor tlinkedlist.init;
  495. begin
  496. first:=nil;
  497. last:=nil;
  498. end;
  499. destructor tlinkedlist.done;
  500. begin
  501. clear;
  502. end;
  503. procedure tlinkedlist.clear;
  504. var
  505. hp : plinkedlist_item;
  506. begin
  507. hp:=first;
  508. while assigned(hp) do
  509. begin
  510. first:=hp^.next;
  511. dispose(hp,done);
  512. hp:=first;
  513. end;
  514. end;
  515. procedure tlinkedlist.insertlist(p : plinkedlist);
  516. begin
  517. { empty list ? }
  518. if not(assigned(p^.first)) then
  519. exit;
  520. p^.last^.next:=first;
  521. { we have a double linked list }
  522. if assigned(first) then
  523. first^.previous:=p^.last;
  524. first:=p^.first;
  525. if not(assigned(last)) then
  526. last:=p^.last;
  527. { p becomes empty }
  528. p^.first:=nil;
  529. p^.last:=nil;
  530. end;
  531. procedure tlinkedlist.concat(p : plinkedlist_item);
  532. begin
  533. p^.previous:=nil;
  534. p^.next:=nil;
  535. if not(assigned(first)) then
  536. first:=p
  537. else
  538. begin
  539. last^.next:=p;
  540. p^.previous:=last;
  541. end;
  542. last:=p;
  543. end;
  544. procedure tlinkedlist.insert(p : plinkedlist_item);
  545. begin
  546. p^.previous:=nil;
  547. p^.next:=nil;
  548. if not(assigned(first)) then
  549. last:=p
  550. else
  551. begin
  552. first^.previous:=p;
  553. p^.next:=first;
  554. first:=p;
  555. end;
  556. first:=p;
  557. end;
  558. procedure tlinkedlist.remove(p : plinkedlist_item);
  559. begin
  560. if not(assigned(p)) then
  561. exit;
  562. if (first=p) and (last=p) then
  563. begin
  564. first:=nil;
  565. last:=nil;
  566. end
  567. else if first=p then
  568. begin
  569. first:=p^.next;
  570. if assigned(first) then
  571. first^.previous:=nil;
  572. end
  573. else if last=p then
  574. begin
  575. last:=last^.previous;
  576. if assigned(last) then
  577. last^.next:=nil;
  578. end
  579. else
  580. begin
  581. p^.previous^.next:=p^.next;
  582. p^.next^.previous:=p^.previous;
  583. end;
  584. p^.next:=nil;
  585. p^.previous:=nil;
  586. end;
  587. procedure tlinkedlist.concatlist(p : plinkedlist);
  588. begin
  589. if not(assigned(p^.first)) then
  590. exit;
  591. if not(assigned(first)) then
  592. first:=p^.first
  593. else
  594. begin
  595. last^.next:=p^.first;
  596. p^.first^.previous:=last;
  597. end;
  598. last:=p^.last;
  599. { make p empty }
  600. p^.last:=nil;
  601. p^.first:=nil;
  602. end;
  603. function tlinkedlist.empty:boolean;
  604. begin
  605. empty:=(first=nil);
  606. end;
  607. {$ifdef BUFFEREDFILE}
  608. {****************************************************************************
  609. TBUFFEREDFILE
  610. ****************************************************************************}
  611. Const
  612. crcseed = $ffffffff;
  613. crctable : array[0..255] of longint = (
  614. $00000000,$77073096,$ee0e612c,$990951ba,$076dc419,$706af48f,
  615. $e963a535,$9e6495a3,$0edb8832,$79dcb8a4,$e0d5e91e,$97d2d988,
  616. $09b64c2b,$7eb17cbd,$e7b82d07,$90bf1d91,$1db71064,$6ab020f2,
  617. $f3b97148,$84be41de,$1adad47d,$6ddde4eb,$f4d4b551,$83d385c7,
  618. $136c9856,$646ba8c0,$fd62f97a,$8a65c9ec,$14015c4f,$63066cd9,
  619. $fa0f3d63,$8d080df5,$3b6e20c8,$4c69105e,$d56041e4,$a2677172,
  620. $3c03e4d1,$4b04d447,$d20d85fd,$a50ab56b,$35b5a8fa,$42b2986c,
  621. $dbbbc9d6,$acbcf940,$32d86ce3,$45df5c75,$dcd60dcf,$abd13d59,
  622. $26d930ac,$51de003a,$c8d75180,$bfd06116,$21b4f4b5,$56b3c423,
  623. $cfba9599,$b8bda50f,$2802b89e,$5f058808,$c60cd9b2,$b10be924,
  624. $2f6f7c87,$58684c11,$c1611dab,$b6662d3d,$76dc4190,$01db7106,
  625. $98d220bc,$efd5102a,$71b18589,$06b6b51f,$9fbfe4a5,$e8b8d433,
  626. $7807c9a2,$0f00f934,$9609a88e,$e10e9818,$7f6a0dbb,$086d3d2d,
  627. $91646c97,$e6635c01,$6b6b51f4,$1c6c6162,$856530d8,$f262004e,
  628. $6c0695ed,$1b01a57b,$8208f4c1,$f50fc457,$65b0d9c6,$12b7e950,
  629. $8bbeb8ea,$fcb9887c,$62dd1ddf,$15da2d49,$8cd37cf3,$fbd44c65,
  630. $4db26158,$3ab551ce,$a3bc0074,$d4bb30e2,$4adfa541,$3dd895d7,
  631. $a4d1c46d,$d3d6f4fb,$4369e96a,$346ed9fc,$ad678846,$da60b8d0,
  632. $44042d73,$33031de5,$aa0a4c5f,$dd0d7cc9,$5005713c,$270241aa,
  633. $be0b1010,$c90c2086,$5768b525,$206f85b3,$b966d409,$ce61e49f,
  634. $5edef90e,$29d9c998,$b0d09822,$c7d7a8b4,$59b33d17,$2eb40d81,
  635. $b7bd5c3b,$c0ba6cad,$edb88320,$9abfb3b6,$03b6e20c,$74b1d29a,
  636. $ead54739,$9dd277af,$04db2615,$73dc1683,$e3630b12,$94643b84,
  637. $0d6d6a3e,$7a6a5aa8,$e40ecf0b,$9309ff9d,$0a00ae27,$7d079eb1,
  638. $f00f9344,$8708a3d2,$1e01f268,$6906c2fe,$f762575d,$806567cb,
  639. $196c3671,$6e6b06e7,$fed41b76,$89d32be0,$10da7a5a,$67dd4acc,
  640. $f9b9df6f,$8ebeeff9,$17b7be43,$60b08ed5,$d6d6a3e8,$a1d1937e,
  641. $38d8c2c4,$4fdff252,$d1bb67f1,$a6bc5767,$3fb506dd,$48b2364b,
  642. $d80d2bda,$af0a1b4c,$36034af6,$41047a60,$df60efc3,$a867df55,
  643. $316e8eef,$4669be79,$cb61b38c,$bc66831a,$256fd2a0,$5268e236,
  644. $cc0c7795,$bb0b4703,$220216b9,$5505262f,$c5ba3bbe,$b2bd0b28,
  645. $2bb45a92,$5cb36a04,$c2d7ffa7,$b5d0cf31,$2cd99e8b,$5bdeae1d,
  646. $9b64c2b0,$ec63f226,$756aa39c,$026d930a,$9c0906a9,$eb0e363f,
  647. $72076785,$05005713,$95bf4a82,$e2b87a14,$7bb12bae,$0cb61b38,
  648. $92d28e9b,$e5d5be0d,$7cdcefb7,$0bdbdf21,$86d3d2d4,$f1d4e242,
  649. $68ddb3f8,$1fda836e,$81be16cd,$f6b9265b,$6fb077e1,$18b74777,
  650. $88085ae6,$ff0f6a70,$66063bca,$11010b5c,$8f659eff,$f862ae69,
  651. $616bffd3,$166ccf45,$a00ae278,$d70dd2ee,$4e048354,$3903b3c2,
  652. $a7672661,$d06016f7,$4969474d,$3e6e77db,$aed16a4a,$d9d65adc,
  653. $40df0b66,$37d83bf0,$a9bcae53,$debb9ec5,$47b2cf7f,$30b5ffe9,
  654. $bdbdf21c,$cabac28a,$53b39330,$24b4a3a6,$bad03605,$cdd70693,
  655. $54de5729,$23d967bf,$b3667a2e,$c4614ab8,$5d681b02,$2a6f2b94,
  656. $b40bbe37,$c30c8ea1,$5a05df1b,$2d02ef8d);
  657. constructor tbufferedfile.init(const filename : string;_bufsize : longint);
  658. begin
  659. assign(f,filename);
  660. bufsize:=_bufsize;
  661. bufpos:=0;
  662. buflast:=0;
  663. do_crc:=false;
  664. iomode:=0;
  665. tempclosed:=false;
  666. change_endian:=false;
  667. clear_crc;
  668. end;
  669. destructor tbufferedfile.done;
  670. begin
  671. close;
  672. end;
  673. procedure tbufferedfile.clear_crc;
  674. begin
  675. crc:=crcseed;
  676. end;
  677. procedure tbufferedfile.setbuf(p : pchar;s : longint);
  678. begin
  679. flush;
  680. freemem(buf,bufsize);
  681. bufsize:=s;
  682. buf:=p;
  683. end;
  684. function tbufferedfile.reset:boolean;
  685. var
  686. ofm : byte;
  687. begin
  688. ofm:=filemode;
  689. iomode:=1;
  690. getmem(buf,bufsize);
  691. filemode:=0;
  692. {$I-}
  693. system.reset(f,1);
  694. {$I+}
  695. reset:=(ioresult=0);
  696. filemode:=ofm;
  697. end;
  698. procedure tbufferedfile.rewrite;
  699. begin
  700. iomode:=2;
  701. getmem(buf,bufsize);
  702. system.rewrite(f,1);
  703. end;
  704. procedure tbufferedfile.flush;
  705. var
  706. {$ifdef FPC}
  707. count : longint;
  708. {$else}
  709. count : integer;
  710. {$endif}
  711. begin
  712. if iomode=2 then
  713. begin
  714. if bufpos=0 then
  715. exit;
  716. blockwrite(f,buf^,bufpos)
  717. end
  718. else if iomode=1 then
  719. if buflast=bufpos then
  720. begin
  721. blockread(f,buf^,bufsize,count);
  722. buflast:=count;
  723. end;
  724. bufpos:=0;
  725. end;
  726. function tbufferedfile.getftime : longint;
  727. var
  728. l : longint;
  729. {$ifdef linux}
  730. Info : Stat;
  731. {$endif}
  732. begin
  733. {$ifndef linux}
  734. { this only works if the file is open !! }
  735. dos.getftime(f,l);
  736. {$else}
  737. Fstat(f,Info);
  738. l:=info.mtime;
  739. {$endif}
  740. getftime:=l;
  741. end;
  742. function tbufferedfile.getsize : longint;
  743. begin
  744. getsize:=filesize(f);
  745. end;
  746. procedure tbufferedfile.seek(l : longint);
  747. begin
  748. if iomode=2 then
  749. begin
  750. flush;
  751. system.seek(f,l);
  752. end
  753. else if iomode=1 then
  754. begin
  755. { forces a reload }
  756. bufpos:=buflast;
  757. system.seek(f,l);
  758. flush;
  759. end;
  760. end;
  761. type
  762. {$ifdef tp}
  763. bytearray1 = array [1..65535] of byte;
  764. {$else}
  765. bytearray1 = array [1..10000000] of byte;
  766. {$endif}
  767. procedure tbufferedfile.read_data(var data;bytes : longint;var count : longint);
  768. var
  769. p : pchar;
  770. c,i : longint;
  771. begin
  772. p:=pchar(@data);
  773. count:=0;
  774. while bytes-count>0 do
  775. begin
  776. if bytes-count>buflast-bufpos then
  777. begin
  778. move((buf+bufpos)^,(p+count)^,buflast-bufpos);
  779. inc(count,buflast-bufpos);
  780. bufpos:=buflast;
  781. flush;
  782. { can't we read anything ? }
  783. if bufpos=buflast then
  784. break;
  785. end
  786. else
  787. begin
  788. move((buf+bufpos)^,(p+count)^,bytes-count);
  789. inc(bufpos,bytes-count);
  790. count:=bytes;
  791. break;
  792. end;
  793. end;
  794. if do_crc then
  795. begin
  796. c:=crc;
  797. for i:=1 to bytes do
  798. c:=(c shr 8) xor crctable[byte(c) xor (bytearray1(data)[i])];
  799. crc:=c;
  800. end;
  801. end;
  802. procedure tbufferedfile.write_data(var data;count : longint);
  803. var
  804. c,i : longint;
  805. begin
  806. if bufpos+count>bufsize then
  807. flush;
  808. move(data,(buf+bufpos)^,count);
  809. inc(bufpos,count);
  810. if do_crc then
  811. begin
  812. c:=crc;
  813. for i:=1 to count do
  814. c:=(c shr 8) xor crctable[byte(c) xor (bytearray1(data)[i])];
  815. crc:=c;
  816. end;
  817. end;
  818. function tbufferedfile.getcrc : longint;
  819. begin
  820. getcrc:=crc xor crcseed;
  821. end;
  822. procedure tbufferedfile.write_string(const s : string);
  823. begin
  824. if bufpos+length(s)>bufsize then
  825. flush;
  826. { why is there not CRC here ??? }
  827. move(s[1],(buf+bufpos)^,length(s));
  828. inc(bufpos,length(s));
  829. { should be
  830. write_data(s[1],length(s)); }
  831. end;
  832. procedure tbufferedfile.write_pchar(p : pchar);
  833. var
  834. l : longint;
  835. begin
  836. l:=strlen(p);
  837. if l>=bufsize then
  838. runerror(222);
  839. { why is there not CRC here ???}
  840. if bufpos+l>bufsize then
  841. flush;
  842. move(p^,(buf+bufpos)^,l);
  843. inc(bufpos,l);
  844. { should be
  845. write_data(p^,l); }
  846. end;
  847. procedure tbufferedfile.write_byte(b : byte);
  848. begin
  849. write_data(b,sizeof(byte));
  850. end;
  851. procedure tbufferedfile.write_long(l : longint);
  852. var
  853. w1,w2 : word;
  854. begin
  855. if change_endian then
  856. begin
  857. w1:=l and $ffff;
  858. w2:=l shr 16;
  859. l:=swap(w2)+(longint(swap(w1)) shl 16);
  860. write_data(l,sizeof(longint))
  861. end
  862. else
  863. write_data(l,sizeof(longint))
  864. end;
  865. procedure tbufferedfile.write_word(w : word);
  866. begin
  867. if change_endian then
  868. begin
  869. w:=swap(w);
  870. write_data(w,sizeof(word))
  871. end
  872. else
  873. write_data(w,sizeof(word));
  874. end;
  875. procedure tbufferedfile.write_double(d : double);
  876. begin
  877. write_data(d,sizeof(double));
  878. end;
  879. function tbufferedfile.getpath : string;
  880. begin
  881. {$ifdef dummy}
  882. getpath:=strpas(filerec(f).name);
  883. {$endif}
  884. getpath:='';
  885. end;
  886. procedure tbufferedfile.close;
  887. begin
  888. if iomode<>0 then
  889. begin
  890. flush;
  891. system.close(f);
  892. freemem(buf,bufsize);
  893. buf:=nil;
  894. iomode:=0;
  895. end;
  896. end;
  897. procedure tbufferedfile.tempclose;
  898. begin
  899. if iomode<>0 then
  900. begin
  901. temppos:=system.filepos(f);
  902. tempmode:=iomode;
  903. tempclosed:=true;
  904. system.close(f);
  905. iomode:=0;
  906. end
  907. else
  908. tempclosed:=false;
  909. end;
  910. procedure tbufferedfile.tempreopen;
  911. var
  912. ofm : byte;
  913. begin
  914. if tempclosed then
  915. begin
  916. case tempmode of
  917. 1 : begin
  918. ofm:=filemode;
  919. iomode:=1;
  920. filemode:=0;
  921. system.reset(f,1);
  922. filemode:=ofm;
  923. end;
  924. 2 : begin
  925. iomode:=2;
  926. system.rewrite(f,1);
  927. end;
  928. end;
  929. system.seek(f,temppos);
  930. tempclosed:=false;
  931. end;
  932. end;
  933. {$endif BUFFEREDFILE}
  934. end.
  935. {
  936. $Log$
  937. Revision 1.16 1998-11-04 10:11:37 peter
  938. * ansistring fixes
  939. Revision 1.15 1998/10/19 18:04:40 peter
  940. + tstringcontainer.init_no_doubles
  941. Revision 1.14 1998/09/18 16:03:37 florian
  942. * some changes to compile with Delphi
  943. Revision 1.13 1998/08/12 19:28:16 peter
  944. * better libc support
  945. Revision 1.12 1998/07/14 14:46:47 peter
  946. * released NEWINPUT
  947. Revision 1.11 1998/07/07 11:19:54 peter
  948. + NEWINPUT for a better inputfile and scanner object
  949. Revision 1.10 1998/07/01 15:26:59 peter
  950. * better bufferfile.reset error handling
  951. Revision 1.9 1998/06/03 23:40:37 peter
  952. + unlimited file support, release tempclose
  953. Revision 1.8 1998/05/20 09:42:33 pierre
  954. + UseTokenInfo now default
  955. * unit in interface uses and implementation uses gives error now
  956. * only one error for unknown symbol (uses lastsymknown boolean)
  957. the problem came from the label code !
  958. + first inlined procedures and function work
  959. (warning there might be allowed cases were the result is still wrong !!)
  960. * UseBrower updated gives a global list of all position of all used symbols
  961. with switch -gb
  962. Revision 1.7 1998/05/06 18:36:53 peter
  963. * tai_section extended with code,data,bss sections and enumerated type
  964. * ident 'compiled by FPC' moved to pmodules
  965. * small fix for smartlink
  966. Revision 1.6 1998/05/06 08:38:37 pierre
  967. * better position info with UseTokenInfo
  968. UseTokenInfo greatly simplified
  969. + added check for changed tree after first time firstpass
  970. (if we could remove all the cases were it happen
  971. we could skip all firstpass if firstpasscount > 1)
  972. Only with ExtDebug
  973. Revision 1.5 1998/04/30 15:59:40 pierre
  974. * GDB works again better :
  975. correct type info in one pass
  976. + UseTokenInfo for better source position
  977. * fixed one remaining bug in scanner for line counts
  978. * several little fixes
  979. Revision 1.4 1998/04/29 10:33:50 pierre
  980. + added some code for ansistring (not complete nor working yet)
  981. * corrected operator overloading
  982. * corrected nasm output
  983. + started inline procedures
  984. + added starstarn : use ** for exponentiation (^ gave problems)
  985. + started UseTokenInfo cond to get accurate positions
  986. Revision 1.3 1998/04/27 23:10:28 peter
  987. + new scanner
  988. * $makelib -> if smartlink
  989. * small filename fixes pmodule.setfilename
  990. * moved import from files.pas -> import.pas
  991. Revision 1.2 1998/04/07 11:09:04 peter
  992. + filemode is set correct in tbufferedfile.reset
  993. }