text.inc 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Run time library.
  4. Copyright (c) 1993,97 by the Free Pascal development team
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {
  12. Possible Defines:
  13. EOF_CTRLZ Is Ctrl-Z (#26) a EOF mark for textfiles
  14. SHORT_LINEBREAK Use short Linebreaks #10 instead of #10#13
  15. SHORT_LINEBREAK is defined in the Linux system unit (syslinux.pp)
  16. }
  17. {****************************************************************************
  18. subroutines For TextFile handling
  19. ****************************************************************************}
  20. Procedure FileCloseFunc(Var t:TextRec);
  21. Begin
  22. Do_Close(t.Handle);
  23. t.Handle:=UnusedHandle;
  24. End;
  25. Procedure FileReadFunc(var t:TextRec);
  26. Begin
  27. t.BufEnd:=Do_Read(t.Handle,Longint(t.Bufptr),t.BufSize);
  28. t.BufPos:=0;
  29. End;
  30. Procedure FileWriteFunc(var t:TextRec);
  31. Begin
  32. Do_Write(t.Handle,Longint(t.Bufptr),t.BufPos);
  33. t.BufPos:=0;
  34. End;
  35. Procedure FileOpenFunc(var t:TextRec);
  36. var
  37. Flags : Longint;
  38. Begin
  39. Case t.mode Of
  40. fmInput : Flags:=$1000;
  41. fmOutput : Flags:=$1101;
  42. fmAppend : Flags:=$1011;
  43. else
  44. HandleError(102);
  45. End;
  46. Do_Open(t,PChar(@t.Name),Flags);
  47. t.CloseFunc:=@FileCloseFunc;
  48. t.FlushFunc:=nil;
  49. if t.Mode=fmInput then
  50. t.InOutFunc:=@FileReadFunc
  51. else
  52. begin
  53. t.InOutFunc:=@FileWriteFunc;
  54. { Only install flushing if its a NOT a file }
  55. if Do_Isdevice(t.Handle) then
  56. t.FlushFunc:=@FileWriteFunc;
  57. end;
  58. End;
  59. Procedure assign(var t:Text;const s:String);
  60. Begin
  61. FillChar(t,SizEof(TextRec),0);
  62. { only set things that are not zero }
  63. TextRec(t).Handle:=UnusedHandle;
  64. TextRec(t).mode:=fmClosed;
  65. TextRec(t).BufSize:=TextRecBufSize;
  66. TextRec(t).Bufptr:=@TextRec(t).Buffer;
  67. TextRec(t).OpenFunc:=@FileOpenFunc;
  68. Move(s[1],TextRec(t).Name,Length(s));
  69. End;
  70. Procedure assign(var t:Text;p:pchar);
  71. begin
  72. Assign(t,StrPas(p));
  73. end;
  74. Procedure assign(var t:Text;c:char);
  75. begin
  76. Assign(t,string(c));
  77. end;
  78. Procedure Close(var t : Text);[IOCheck];
  79. Begin
  80. if InOutRes<>0 then
  81. Exit;
  82. If (TextRec(t).mode<>fmClosed) Then
  83. Begin
  84. { Write pending buffer }
  85. If Textrec(t).Mode=fmoutput then
  86. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  87. TextRec(t).mode:=fmClosed;
  88. { Only close functions not connected to stdout.}
  89. If ((TextRec(t).Handle<>StdInputHandle) and
  90. (TextRec(t).Handle<>StdOutputHandle) and
  91. (TextRec(t).Handle<>StdErrorHandle)) Then
  92. FileFunc(TextRec(t).CloseFunc)(TextRec(t));
  93. { Reset buffer for safety }
  94. TextRec(t).BufPos:=0;
  95. TextRec(t).BufEnd:=0;
  96. End;
  97. End;
  98. Procedure OpenText(var t : Text;mode,defHdl:Longint);
  99. Begin
  100. Case TextRec(t).mode Of {This gives the fastest code}
  101. fmInput,fmOutput,fmInOut : Close(t);
  102. fmClosed : ;
  103. else
  104. Begin
  105. InOutRes:=102;
  106. exit;
  107. End;
  108. End;
  109. TextRec(t).mode:=mode;
  110. TextRec(t).bufpos:=0;
  111. TextRec(t).bufend:=0;
  112. FileFunc(TextRec(t).OpenFunc)(TextRec(t))
  113. End;
  114. Procedure Rewrite(var t : Text);[IOCheck];
  115. Begin
  116. If InOutRes<>0 then
  117. exit;
  118. OpenText(t,fmOutput,1);
  119. End;
  120. Procedure Reset(var t : Text);[IOCheck];
  121. Begin
  122. If InOutRes<>0 then
  123. exit;
  124. OpenText(t,fmInput,0);
  125. End;
  126. Procedure Append(var t : Text);[IOCheck];
  127. Begin
  128. If InOutRes<>0 then
  129. exit;
  130. OpenText(t,fmAppend,1);
  131. End;
  132. Procedure Flush(var t : Text);[IOCheck];
  133. Begin
  134. If InOutRes<>0 then
  135. exit;
  136. If TextRec(t).mode<>fmOutput Then
  137. begin
  138. InOutres:=105;
  139. exit;
  140. end;
  141. { Not the flushfunc but the inoutfunc should be used, becuase that
  142. writes the data, flushfunc doesn't need to be assigned }
  143. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  144. End;
  145. Procedure Erase(var t:Text);[IOCheck];
  146. Begin
  147. If InOutRes <> 0 then
  148. exit;
  149. If TextRec(t).mode=fmClosed Then
  150. Do_Erase(PChar(@TextRec(t).Name));
  151. End;
  152. Procedure Rename(var t : text;p:pchar);[IOCheck];
  153. Begin
  154. If InOutRes <> 0 then
  155. exit;
  156. If TextRec(t).mode=fmClosed Then
  157. Begin
  158. Do_Rename(PChar(@TextRec(t).Name),p);
  159. Move(p^,TextRec(t).Name,StrLen(p)+1);
  160. End;
  161. End;
  162. Procedure Rename(var t : Text;const s : string);[IOCheck];
  163. var
  164. p : array[0..255] Of Char;
  165. Begin
  166. If InOutRes <> 0 then
  167. exit;
  168. Move(s[1],p,Length(s));
  169. p[Length(s)]:=#0;
  170. Rename(t,Pchar(@p));
  171. End;
  172. Procedure Rename(var t : Text;c : char);[IOCheck];
  173. var
  174. p : array[0..1] Of Char;
  175. Begin
  176. If InOutRes <> 0 then
  177. exit;
  178. p[0]:=c;
  179. p[1]:=#0;
  180. Rename(t,Pchar(@p));
  181. End;
  182. Function Eof(Var t: Text): Boolean;[IOCheck];
  183. Begin
  184. If (InOutRes<>0) then
  185. exit(true);
  186. if (TextRec(t).mode<>fmInput) Then
  187. begin
  188. InOutRes:=104;
  189. exit(true);
  190. end;
  191. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  192. begin
  193. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  194. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  195. exit(true);
  196. end;
  197. {$ifdef EOF_CTRLZ}
  198. Eof:=(TextRec(t).Bufptr^[TextRec(t).BufPos]=#26);
  199. {$else}
  200. Eof:=false;
  201. {$endif EOL_CTRLZ}
  202. end;
  203. Function Eof:Boolean;
  204. Begin
  205. Eof:=Eof(Input);
  206. End;
  207. Function SeekEof (Var t : Text) : Boolean;
  208. Begin
  209. If (InOutRes<>0) then
  210. exit(true);
  211. if (TextRec(t).mode<>fmInput) Then
  212. begin
  213. InOutRes:=104;
  214. exit(true);
  215. end;
  216. repeat
  217. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  218. begin
  219. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  220. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  221. exit(true);
  222. end;
  223. case TextRec(t).Bufptr^[TextRec(t).BufPos] of
  224. #26 : exit(true);
  225. #10,#13,
  226. #9,' ' : ;
  227. else
  228. exit(false);
  229. end;
  230. inc(TextRec(t).BufPos);
  231. until false;
  232. End;
  233. Function SeekEof : Boolean;
  234. Begin
  235. SeekEof:=SeekEof(Input);
  236. End;
  237. Function Eoln(var t:Text) : Boolean;
  238. Begin
  239. If (InOutRes<>0) then
  240. exit(true);
  241. if (TextRec(t).mode<>fmInput) Then
  242. begin
  243. InOutRes:=104;
  244. exit(true);
  245. end;
  246. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  247. begin
  248. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  249. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  250. exit(true);
  251. end;
  252. Eoln:=(TextRec(t).Bufptr^[TextRec(t).BufPos] in [#10,#13]);
  253. End;
  254. Function Eoln : Boolean;
  255. Begin
  256. Eoln:=Eoln(Input);
  257. End;
  258. Function SeekEoln (Var t : Text) : Boolean;
  259. Begin
  260. If (InOutRes<>0) then
  261. exit(true);
  262. if (TextRec(t).mode<>fmInput) Then
  263. begin
  264. InOutRes:=104;
  265. exit(true);
  266. end;
  267. repeat
  268. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  269. begin
  270. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  271. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  272. exit(true);
  273. end;
  274. case TextRec(t).Bufptr^[TextRec(t).BufPos] of
  275. #26,
  276. #10,#13 : exit(true);
  277. #9,' ' : ;
  278. else
  279. exit(false);
  280. end;
  281. inc(TextRec(t).BufPos);
  282. until false;
  283. End;
  284. Function SeekEoln : Boolean;
  285. Begin
  286. SeekEoln:=SeekEoln(Input);
  287. End;
  288. Procedure SetTextBuf(Var F : Text; Var Buf);[INTERNPROC: In_settextbuf_file_x];
  289. Procedure SetTextBuf(Var F : Text; Var Buf; Size : Word);
  290. Begin
  291. TextRec(f).BufPtr:=@Buf;
  292. TextRec(f).BufSize:=Size;
  293. TextRec(f).BufPos:=0;
  294. TextRec(f).BufEnd:=0;
  295. End;
  296. {*****************************************************************************
  297. Write(Ln)
  298. *****************************************************************************}
  299. Procedure WriteBuffer(var f:TextRec;var b;len:longint);
  300. var
  301. p : pchar;
  302. left,
  303. idx : longint;
  304. begin
  305. p:=pchar(@b);
  306. idx:=0;
  307. left:=f.BufSize-f.BufPos;
  308. while len>left do
  309. begin
  310. move(p[idx],f.Bufptr^[f.BufPos],left);
  311. dec(len,left);
  312. inc(idx,left);
  313. inc(f.BufPos,left);
  314. FileFunc(f.InOutFunc)(f);
  315. left:=f.BufSize-f.BufPos;
  316. end;
  317. move(p[idx],f.Bufptr^[f.BufPos],len);
  318. inc(f.BufPos,len);
  319. end;
  320. Procedure WriteBlanks(var f:TextRec;len:longint);
  321. var
  322. left : longint;
  323. begin
  324. left:=f.BufSize-f.BufPos;
  325. while len>left do
  326. begin
  327. FillChar(f.Bufptr^[f.BufPos],left,' ');
  328. dec(len,left);
  329. inc(f.BufPos,left);
  330. FileFunc(f.InOutFunc)(f);
  331. left:=f.BufSize-f.BufPos;
  332. end;
  333. FillChar(f.Bufptr^[f.BufPos],len,' ');
  334. inc(f.BufPos,len);
  335. end;
  336. Procedure Write_End(var f:TextRec);[Public,Alias:{$ifdef FPCNAMES}'FPC_'+{$endif}'WRITE_END'];
  337. begin
  338. if f.FlushFunc<>nil then
  339. FileFunc(f.FlushFunc)(f);
  340. end;
  341. Procedure Writeln_End(var f:TextRec);[Public,Alias:{$ifdef FPCNAMES}'FPC_'+{$endif}'WRITELN_END'];
  342. const
  343. {$IFDEF SHORT_LINEBREAK}
  344. eollen=1;
  345. eol : array[0..0] of char=(#10);
  346. {$ELSE SHORT_LINEBREAK}
  347. eollen=2;
  348. eol : array[0..1] of char=(#13,#10);
  349. {$ENDIF SHORT_LINEBREAK}
  350. begin
  351. If InOutRes <> 0 then exit;
  352. { Write EOL }
  353. WriteBuffer(f,eol,eollen);
  354. { Flush }
  355. if f.FlushFunc<>nil then
  356. FileFunc(f.FlushFunc)(f);
  357. end;
  358. Procedure Write_Str(Len : Longint;var f : TextRec;const s : String);[Public,Alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'WRITE_TEXT_STRING'];
  359. Begin
  360. If (InOutRes<>0) then
  361. exit;
  362. if (f.mode<>fmOutput) Then
  363. begin
  364. InOutRes:=105;
  365. exit;
  366. end;
  367. If Len>Length(s) Then
  368. WriteBlanks(f,Len-Length(s));
  369. WriteBuffer(f,s[1],Length(s));
  370. End;
  371. Type
  372. array00 = array[0..0] Of Char;
  373. Procedure Write_Array(Len : Longint;var f : TextRec;const p : array00);[Public,Alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'WRITE_TEXT_PCHAR_AS_ARRAY'];
  374. var
  375. ArrayLen : longint;
  376. Begin
  377. If (InOutRes<>0) then
  378. exit;
  379. if (f.mode<>fmOutput) Then
  380. begin
  381. InOutRes:=105;
  382. exit;
  383. end;
  384. ArrayLen:=StrLen(p);
  385. If Len>ArrayLen Then
  386. WriteBlanks(f,Len-ArrayLen);
  387. WriteBuffer(f,p,ArrayLen);
  388. End;
  389. Procedure Write_PChar(Len : Longint;var f : TextRec;p : PChar);[Public,Alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'WRITE_TEXT_PCHAR_AS_POINTER'];
  390. var
  391. PCharLen : longint;
  392. Begin
  393. If (p=nil) or (InOutRes<>0) then
  394. exit;
  395. if (f.mode<>fmOutput) Then
  396. begin
  397. InOutRes:=105;
  398. exit;
  399. end;
  400. PCharLen:=StrLen(p);
  401. If Len>PCharLen Then
  402. WriteBlanks(f,Len-PCharLen);
  403. WriteBuffer(f,p^,PCharLen);
  404. End;
  405. Procedure Write_Text_AnsiString (Len : Longint; Var T : TextRec; S : Pointer);[Public, alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'WRITE_TEXT_ANSISTRING'];
  406. {
  407. Writes a AnsiString to the Text file T
  408. }
  409. begin
  410. If S=Nil then
  411. exit;
  412. Write_pchar (Len,t,PChar(S));
  413. end;
  414. Procedure Write_LongInt(Len : Longint;var t : TextRec;l : Longint);[Public,Alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'WRITE_TEXT_LONGINT'];
  415. var
  416. s : String;
  417. Begin
  418. If (InOutRes<>0) then
  419. exit;
  420. Str(l,s);
  421. Write_Str(Len,t,s);
  422. End;
  423. Procedure Write_Real(fixkomma,Len : Longint;var t : TextRec;r : real);[Public,Alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'WRITE_TEXT_REAL'];
  424. var
  425. s : String;
  426. Begin
  427. If (InOutRes<>0) then
  428. exit;
  429. {$ifdef i386}
  430. Str_real(Len,fixkomma,r,rt_s64real,s);
  431. {$else}
  432. Str_real(Len,fixkomma,r,rt_s32real,s);
  433. {$endif}
  434. Write_Str(Len,t,s);
  435. End;
  436. Procedure Write_Cardinal(Len : Longint;var t : TextRec;l : cardinal);[Public,Alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'WRITE_TEXT_CARDINAL'];
  437. var
  438. s : String;
  439. Begin
  440. If (InOutRes<>0) then
  441. exit;
  442. Str(L,s);
  443. Write_Str(Len,t,s);
  444. End;
  445. {$ifdef SUPPORT_SINGLE}
  446. Procedure Write_Single(fixkomma,Len : Longint;var t : TextRec;r : single);[Public,Alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'WRITE_TEXT_SINGLE'];
  447. var
  448. s : String;
  449. Begin
  450. If (InOutRes<>0) then
  451. exit;
  452. Str_real(Len,fixkomma,r,rt_s32real,s);
  453. Write_Str(Len,t,s);
  454. End;
  455. {$endif SUPPORT_SINGLE}
  456. {$ifdef SUPPORT_EXTENDED}
  457. Procedure Write_Extended(fixkomma,Len : Longint;var t : TextRec;r : extended);[Public,Alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'WRITE_TEXT_EXTENDED'];
  458. var
  459. s : String;
  460. Begin
  461. If (InOutRes<>0) then
  462. exit;
  463. Str_real(Len,fixkomma,r,rt_s80real,s);
  464. Write_Str(Len,t,s);
  465. End;
  466. {$endif SUPPORT_EXTENDED}
  467. {$ifdef SUPPORT_COMP}
  468. Procedure Write_Comp(fixkomma,Len : Longint;var t : TextRec;r : comp);[Public,Alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'WRITE_TEXT_COMP'];
  469. var
  470. s : String;
  471. Begin
  472. If (InOutRes<>0) then
  473. exit;
  474. Str_real(Len,fixkomma,r,rt_s64bit,s);
  475. Write_Str(Len,t,s);
  476. End;
  477. {$endif SUPPORT_COMP}
  478. {$ifdef SUPPORT_FIXED}
  479. Procedure Write_Fixed(fixkomma,Len : Longint;var t : TextRec;r : fixed);[Public,Alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'WRITE_TEXT_FIXED'];
  480. var
  481. s : String;
  482. Begin
  483. If (InOutRes<>0) then
  484. exit;
  485. Str_real(Len,fixkomma,r,rt_f32bit,s);
  486. Write_Str(Len,t,s);
  487. End;
  488. {$endif SUPPORT_FIXED}
  489. Procedure Write_Boolean(Len : Longint;var t : TextRec;b : Boolean);[Public,Alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'WRITE_TEXT_BOOLEAN'];
  490. Begin
  491. If (InOutRes<>0) then
  492. exit;
  493. { Can't use array[boolean] because b can be >0 ! }
  494. if b then
  495. Write_Str(Len,t,'TRUE')
  496. else
  497. Write_Str(Len,t,'FALSE');
  498. End;
  499. Procedure Write_Char(Len : Longint;var t : TextRec;c : Char);[Public,Alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'WRITE_TEXT_CHAR'];
  500. Begin
  501. If (InOutRes<>0) then
  502. exit;
  503. if (TextRec(t).mode<>fmOutput) Then
  504. begin
  505. InOutRes:=105;
  506. exit;
  507. end;
  508. If Len>1 Then
  509. WriteBlanks(t,Len-1);
  510. If t.BufPos+1>=t.BufSize Then
  511. FileFunc(t.InOutFunc)(t);
  512. t.Bufptr^[t.BufPos]:=c;
  513. Inc(t.BufPos);
  514. End;
  515. {*****************************************************************************
  516. Read(Ln)
  517. *****************************************************************************}
  518. Function NextChar(var f:TextRec;var s:string):Boolean;
  519. begin
  520. if f.BufPos<f.BufEnd then
  521. begin
  522. s:=s+f.BufPtr^[f.BufPos];
  523. Inc(f.BufPos);
  524. If f.BufPos>=f.BufEnd Then
  525. FileFunc(f.InOutFunc)(f);
  526. NextChar:=true;
  527. end
  528. else
  529. NextChar:=false;
  530. end;
  531. Function IgnoreSpaces(var f:TextRec):Boolean;
  532. {
  533. Removes all leading spaces,tab,eols from the input buffer, returns true if
  534. the buffer is empty
  535. }
  536. var
  537. s : string;
  538. begin
  539. s:='';
  540. IgnoreSpaces:=false;
  541. while f.Bufptr^[f.BufPos] in [#9,#10,#13,' '] do
  542. if not NextChar(f,s) then
  543. exit;
  544. IgnoreSpaces:=true;
  545. end;
  546. Function ReadSign(var f:TextRec;var s:string):Boolean;
  547. {
  548. Read + and - sign, return true if buffer is empty
  549. }
  550. begin
  551. ReadSign:=(not (f.Bufptr^[f.BufPos] in ['-','+'])) or NextChar(f,s);
  552. end;
  553. Function ReadBase(var f:TextRec;var s:string;var Base:longint):boolean;
  554. {
  555. Read the base $ For 16 and % For 2, if buffer is empty return true
  556. }
  557. begin
  558. case f.BufPtr^[f.BufPos] of
  559. '$' : Base:=16;
  560. '%' : Base:=2;
  561. else
  562. Base:=10;
  563. end;
  564. ReadBase:=(Base=10) or NextChar(f,s);
  565. end;
  566. Function ReadNumeric(var f:TextRec;var s:string;base:longint):Boolean;
  567. {
  568. Read numeric input, if buffer is empty then return True
  569. }
  570. var
  571. c : char;
  572. begin
  573. ReadNumeric:=false;
  574. c:=f.BufPtr^[f.BufPos];
  575. while ((base>=10) and (c in ['0'..'9'])) or
  576. ((base=16) and (c in ['A'..'F','a'..'f'])) or
  577. ((base=2) and (c in ['0'..'1'])) do
  578. begin
  579. if not NextChar(f,s) then
  580. exit;
  581. c:=f.BufPtr^[f.BufPos];
  582. end;
  583. ReadNumeric:=true;
  584. end;
  585. Procedure Read_End(var f:TextRec);[Public,Alias:{$ifdef FPCNAMES}'FPC_'+{$endif}'READ_END'];
  586. begin
  587. if f.FlushFunc<>nil then
  588. FileFunc(f.FlushFunc)(f);
  589. end;
  590. Procedure ReadLn_End(var f : TextRec);[Public,Alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'READLN_END'];
  591. Begin
  592. { Check error and if file is open and load buf if empty }
  593. If (InOutRes<>0) then
  594. exit;
  595. if (f.mode<>fmInput) Then
  596. begin
  597. InOutRes:=104;
  598. exit;
  599. end;
  600. repeat
  601. If f.BufPos>=f.BufEnd Then
  602. begin
  603. FileFunc(f.InOutFunc)(f);
  604. if f.BufPos>=f.BufEnd then
  605. break;
  606. end;
  607. inc(f.BufPos);
  608. if (f.BufPtr^[f.BufPos-1]=#10) then
  609. exit;
  610. until false;
  611. { Flush if set }
  612. if f.FlushFunc<>nil then
  613. FileFunc(f.FlushFunc)(f);
  614. End;
  615. {$ifdef OPENSTRINGS}
  616. Procedure Read_String(var f : TextRec;var s : String);[Public,Alias:{$ifdef FPCNAMES}'FPC_'+{$endif}'READ_TEXT_STRING'];
  617. {$else}
  618. Procedure Read_String(Maxlen : Longint;var f : TextRec;var s : String);[Public,Alias:{$ifdef FPCNAMES}'FPC_'+{$endif}'READ_TEXT_STRING'];
  619. {$endif}
  620. var
  621. {$ifdef OPENSTRINGS}
  622. maxlen,
  623. {$endif}
  624. sPos,len : Longint;
  625. p,startp,maxp : pchar;
  626. Begin
  627. { Delete the string }
  628. s:='';
  629. { Check error and if file is open }
  630. If (InOutRes<>0) then
  631. exit;
  632. if (f.mode<>fmInput) Then
  633. begin
  634. InOutRes:=104;
  635. exit;
  636. end;
  637. { Read maximal until Maxlen is reached }
  638. sPos:=0;
  639. {$ifdef OPENSTRINGS}
  640. MaxLen:=high(s);
  641. {$endif}
  642. repeat
  643. If f.BufPos>=f.BufEnd Then
  644. begin
  645. FileFunc(f.InOutFunc)(f);
  646. If f.BufPos>=f.BufEnd Then
  647. break;
  648. end;
  649. p:[email protected]^[f.BufPos];
  650. if SPos+f.BufEnd-f.BufPos>MaxLen then
  651. maxp:[email protected]^[f.BufPos+MaxLen-SPos]
  652. else
  653. maxp:[email protected]^[f.BufEnd];
  654. startp:=p;
  655. { search linefeed }
  656. while (p<maxp) and (P^<>#10) do
  657. inc(p);
  658. { calculate read bytes }
  659. len:=p-startp;
  660. inc(f.BufPos,Len);
  661. Move(startp^,s[sPos+1],Len);
  662. inc(sPos,Len);
  663. { was it a LF? then leave }
  664. if p^=#10 then
  665. begin
  666. if (spos>0) and (s[spos]=#13) then
  667. dec(sPos);
  668. break;
  669. end;
  670. { Maxlen reached ? }
  671. if spos=MaxLen then
  672. break;
  673. until false;
  674. { Set final length }
  675. s[0]:=chr(sPos);
  676. End;
  677. Procedure Read_Char(var f : TextRec;var c : Char);[Public,Alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'READ_TEXT_CHAR'];
  678. Begin
  679. c:=#0;
  680. { Check error and if file is open }
  681. If (InOutRes<>0) then
  682. exit;
  683. if (f.mode<>fmInput) Then
  684. begin
  685. InOutRes:=104;
  686. exit;
  687. end;
  688. { Read next char or EOF }
  689. If f.BufPos>=f.BufEnd Then
  690. begin
  691. FileFunc(f.InOutFunc)(f);
  692. If f.BufPos>=f.BufEnd Then
  693. begin
  694. c:=#26;
  695. exit;
  696. end;
  697. end;
  698. c:=f.Bufptr^[f.BufPos];
  699. inc(f.BufPos);
  700. end;
  701. Procedure Read_PChar(var f : TextRec;var s : PChar);[Public,Alias:{$ifdef FPCNAMES}'FPC_'+{$endif}'READ_TEXT_PCHAR_AS_POINTER'];
  702. var
  703. p,maxp,startp,sidx : PChar;
  704. len : longint;
  705. Begin
  706. { Delete the string }
  707. s^:=#0;
  708. { Check error and if file is open }
  709. If (InOutRes<>0) then
  710. exit;
  711. if (f.mode<>fmInput) Then
  712. begin
  713. InOutRes:=104;
  714. exit;
  715. end;
  716. { Read until #10 is found }
  717. sidx:=s;
  718. repeat
  719. If f.BufPos>=f.BufEnd Then
  720. begin
  721. FileFunc(f.InOutFunc)(f);
  722. If f.BufPos>=f.BufEnd Then
  723. break;
  724. end;
  725. p:[email protected]^[f.BufPos];
  726. maxp:[email protected]^[f.BufEnd];
  727. startp:=p;
  728. { search linefeed }
  729. while (p<maxp) and (P^<>#10) do
  730. inc(p);
  731. { calculate read bytes }
  732. len:=p-startp;
  733. inc(f.BufPos,Len);
  734. { update output string, take MaxLen into count }
  735. Move(startp^,sidx^,Len);
  736. inc(sidx,len);
  737. { was it a LF? then leave }
  738. if p^=#10 then
  739. begin
  740. If pchar(p-1)^=#13 Then
  741. dec(p);
  742. break;
  743. end;
  744. until false;
  745. sidx^:=#0;
  746. End;
  747. Procedure Read_Array(var f : TextRec;var s : array00);[Public,Alias:{$ifdef FPCNAMES}'FPC_'+{$endif}'READ_TEXT_PCHAR_AS_ARRAY'];
  748. var
  749. p,maxp,startp,sidx : PChar;
  750. len : longint;
  751. Begin
  752. { Delete the string }
  753. s[0]:=#0;
  754. { Check error and if file is open }
  755. If (InOutRes<>0) then
  756. exit;
  757. if (f.mode<>fmInput) Then
  758. begin
  759. InOutRes:=104;
  760. exit;
  761. end;
  762. { Read until #10 is found }
  763. sidx:=pchar(@s);
  764. repeat
  765. If f.BufPos>=f.BufEnd Then
  766. begin
  767. FileFunc(f.InOutFunc)(f);
  768. If f.BufPos>=f.BufEnd Then
  769. break;
  770. end;
  771. p:[email protected]^[f.BufPos];
  772. maxp:[email protected]^[f.BufEnd];
  773. startp:=p;
  774. { search linefeed }
  775. while (p<maxp) and (P^<>#10) do
  776. inc(p);
  777. { calculate read bytes }
  778. len:=p-startp;
  779. inc(f.BufPos,Len);
  780. { update output string, take MaxLen into count }
  781. Move(startp^,sidx^,Len);
  782. inc(sidx,len);
  783. { was it a LF? then leave }
  784. if p^=#10 then
  785. begin
  786. If pchar(p-1)^=#13 Then
  787. dec(p);
  788. break;
  789. end;
  790. until false;
  791. sidx^:=#0;
  792. End;
  793. {$ifdef OPENSTRINGS}
  794. Procedure Read_AnsiString(var f : TextRec;var s : AnsiString);[Public,Alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'READ_TEXT_ANSISTRING'];
  795. {$else}
  796. Procedure Read_AnsiString(Maxlen : Longint;var f : TextRec;var s : AnsiString);[Public,Alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'READ_TEXT_ANSISTRING'];
  797. {$endif}
  798. var
  799. p,maxp,startp,sidx : PChar;
  800. {$ifdef OPENSTRINGS}
  801. maxlen,
  802. {$endif}
  803. spos,len : longint;
  804. Begin
  805. { Delete the string }
  806. Decr_ansi_ref (Pointer(S));
  807. { We assign room for 1024 characters totally at random.... }
  808. Pointer(s):=Pointer(NewAnsiString(1024));
  809. MaxLen:=1024;
  810. { Check error and if file is open }
  811. If (InOutRes<>0) then
  812. exit;
  813. if (f.mode<>fmInput) Then
  814. begin
  815. InOutRes:=104;
  816. exit;
  817. end;
  818. { Read until #10 is found }
  819. sidx:=pchar(@s);
  820. spos:=0;
  821. repeat
  822. If f.BufPos>=f.BufEnd Then
  823. begin
  824. FileFunc(f.InOutFunc)(f);
  825. If f.BufPos>=f.BufEnd Then
  826. break;
  827. end;
  828. p:[email protected]^[f.BufPos];
  829. if SPos+f.BufEnd-f.BufPos>MaxLen then
  830. maxp:[email protected]^[f.BufPos+MaxLen-SPos]
  831. else
  832. maxp:[email protected]^[f.BufEnd];
  833. startp:=p;
  834. { search linefeed }
  835. while (p<maxp) and (P^<>#10) do
  836. inc(p);
  837. { calculate read bytes }
  838. len:=p-startp;
  839. inc(f.BufPos,Len);
  840. Move(startp^,sidx^,Len);
  841. inc(sidx,len);
  842. inc(spos,len);
  843. { was it a LF? then leave }
  844. if p^=#10 then
  845. begin
  846. If pchar(sidx-1)^=#13 Then
  847. begin
  848. dec(sidx);
  849. dec(spos);
  850. end;
  851. break;
  852. end;
  853. { Maxlen reached ? }
  854. if spos=MaxLen then
  855. break;
  856. until false;
  857. sidx^:=#0;
  858. PAnsiRec(Pointer(S)-FirstOff)^.Len:=spos;
  859. End;
  860. Procedure Read_Longint(var f : TextRec;var l : Longint);[Public,Alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'READ_TEXT_LONGINT'];
  861. var
  862. hs : String;
  863. code : Word;
  864. base : longint;
  865. Begin
  866. l:=0;
  867. { Leave if error or not open file, else check for empty buf }
  868. If (InOutRes<>0) then
  869. exit;
  870. if (f.mode<>fmInput) Then
  871. begin
  872. InOutRes:=104;
  873. exit;
  874. end;
  875. If f.BufPos>=f.BufEnd Then
  876. FileFunc(f.InOutFunc)(f);
  877. hs:='';
  878. if IgnoreSpaces(f) and ReadSign(f,hs) and ReadBase(f,hs,Base) then
  879. ReadNumeric(f,hs,Base);
  880. Val(hs,l,code);
  881. If code<>0 Then
  882. HandleError(106);
  883. End;
  884. Procedure Read_Integer(var f : TextRec;var l : Integer);[Public,Alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'READ_TEXT_INTEGER'];
  885. var
  886. ll : Longint;
  887. Begin
  888. l:=0;
  889. If InOutRes <> 0 then
  890. exit;
  891. Read_Longint(f,ll);
  892. If (ll<-32768) or (ll>32767) Then
  893. HandleError(106);
  894. l:=ll;
  895. End;
  896. Procedure Read_Word(var f : TextRec;var l : Word);[Public,Alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'READ_TEXT_WORD'];
  897. var
  898. ll : Longint;
  899. Begin
  900. l:=0;
  901. If InOutRes <> 0 then
  902. exit;
  903. Read_Longint(f,ll);
  904. If (ll<0) or (ll>$ffff) Then
  905. HandleError(106);
  906. l:=ll;
  907. End;
  908. Procedure Read_Byte(var f : TextRec;var l : byte);[Public,Alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'READ_TEXT_BYTE'];
  909. var
  910. ll : Longint;
  911. Begin
  912. l:=0;
  913. If InOutRes <> 0 then
  914. exit;
  915. Read_Longint(f,ll);
  916. If (ll<0) or (ll>255) Then
  917. HandleError(106);
  918. l:=ll;
  919. End;
  920. Procedure Read_Shortint(var f : TextRec;var l : shortint);[Public,Alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'READ_TEXT_SHORTINT'];
  921. var
  922. ll : Longint;
  923. Begin
  924. l:=0;
  925. If InOutRes <> 0 then
  926. exit;
  927. Read_Longint(f,ll);
  928. If (ll<-128) or (ll>127) Then
  929. HandleError(106);
  930. l:=ll;
  931. End;
  932. Procedure Read_Cardinal(var f : TextRec;var l : cardinal);[Public,Alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'READ_TEXT_CARDINAL'];
  933. var
  934. hs : String;
  935. code : Word;
  936. base : longint;
  937. Begin
  938. l:=0;
  939. { Leave if error or not open file, else check for empty buf }
  940. If (InOutRes<>0) then
  941. exit;
  942. if (f.mode<>fmInput) Then
  943. begin
  944. InOutRes:=104;
  945. exit;
  946. end;
  947. If f.BufPos>=f.BufEnd Then
  948. FileFunc(f.InOutFunc)(f);
  949. hs:='';
  950. if IgnoreSpaces(f) and ReadSign(f,hs) and ReadBase(f,hs,Base) then
  951. ReadNumeric(f,hs,Base);
  952. val(hs,l,code);
  953. If code<>0 Then
  954. HandleError(106);
  955. End;
  956. function ReadRealStr(var f:TextRec):string;
  957. var
  958. hs : string;
  959. begin
  960. ReadRealStr:='';
  961. { Leave if error or not open file, else check for empty buf }
  962. If (InOutRes<>0) then
  963. exit;
  964. if (f.mode<>fmInput) Then
  965. begin
  966. InOutRes:=104;
  967. exit;
  968. end;
  969. If f.BufPos>=f.BufEnd Then
  970. FileFunc(f.InOutFunc)(f);
  971. hs:='';
  972. if IgnoreSpaces(f) and ReadSign(f,hs) and ReadNumeric(f,hs,10) then
  973. begin
  974. { First check for a . }
  975. if (f.Bufptr^[f.BufPos]='.') and (f.BufPos<f.BufEnd) Then
  976. begin
  977. hs:=hs+'.';
  978. Inc(f.BufPos);
  979. If f.BufPos>=f.BufEnd Then
  980. FileFunc(f.InOutFunc)(f);
  981. ReadNumeric(f,hs,10);
  982. end;
  983. { Also when a point is found check for a E }
  984. if (f.Bufptr^[f.BufPos] in ['e','E']) and (f.BufPos<f.BufEnd) Then
  985. begin
  986. hs:=hs+'E';
  987. Inc(f.BufPos);
  988. If f.BufPos>=f.BufEnd Then
  989. FileFunc(f.InOutFunc)(f);
  990. if ReadSign(f,hs) then
  991. ReadNumeric(f,hs,10);
  992. end;
  993. end;
  994. ReadRealStr:=hs;
  995. end;
  996. Procedure Read_Real(var f : TextRec;var d : Real);[Public,Alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'READ_TEXT_REAL'];
  997. var
  998. code : Word;
  999. Begin
  1000. val(ReadRealStr(f),d,code);
  1001. If code<>0 Then
  1002. HandleError(106);
  1003. End;
  1004. {$ifdef SUPPORT_SINGLE}
  1005. Procedure Read_Single(var f : TextRec;var d : single);[Public,Alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'READ_TEXT_SINGLE'];
  1006. var
  1007. code : Word;
  1008. Begin
  1009. val(ReadRealStr(f),d,code);
  1010. If code<>0 Then
  1011. HandleError(106);
  1012. End;
  1013. {$endif SUPPORT_SINGLE}
  1014. {$ifdef SUPPORT_EXTENDED}
  1015. Procedure Read_Extended(var f : TextRec;var d : extended);[Public,Alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'READ_TEXT_EXTENDED'];
  1016. var
  1017. code : Word;
  1018. Begin
  1019. val(ReadRealStr(f),d,code);
  1020. If code<>0 Then
  1021. HandleError(106);
  1022. End;
  1023. {$endif SUPPORT_EXTENDED}
  1024. {$ifdef SUPPORT_COMP}
  1025. Procedure Read_Comp(var f : TextRec;var d : comp);[Public,Alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'READ_TEXT_COMP'];
  1026. var
  1027. code : Word;
  1028. Begin
  1029. val(ReadRealStr(f),d,code);
  1030. If code<>0 Then
  1031. HandleError(106);
  1032. End;
  1033. {$endif SUPPORT_COMP}
  1034. {$ifdef SUPPORT_FIXED}
  1035. Procedure Read_Fixed(var f : TextRec;var d : fixed);[Public,Alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'READ_TEXT_FIXED'];
  1036. var
  1037. code : Word;
  1038. Begin
  1039. val(ReadRealStr(f),d,code);
  1040. If code<>0 Then
  1041. HandleError(106);
  1042. End;
  1043. {$endif SUPPORT_FIXED}
  1044. {*****************************************************************************
  1045. Initializing
  1046. *****************************************************************************}
  1047. procedure OpenStdIO(var f:text;mode,hdl:longint);
  1048. begin
  1049. Assign(f,'');
  1050. TextRec(f).Handle:=hdl;
  1051. TextRec(f).Mode:=mode;
  1052. TextRec(f).Closefunc:=@FileCloseFunc;
  1053. case mode of
  1054. fmInput : TextRec(f).InOutFunc:=@FileReadFunc;
  1055. fmOutput : begin
  1056. TextRec(f).InOutFunc:=@FileWriteFunc;
  1057. TextRec(f).FlushFunc:=@FileWriteFunc;
  1058. end;
  1059. else
  1060. HandleError(102);
  1061. end;
  1062. end;
  1063. {
  1064. $Log$
  1065. Revision 1.36 1998-12-11 18:07:39 peter
  1066. * fixed read(char) with empty buffer
  1067. Revision 1.35 1998/11/27 14:50:58 peter
  1068. + open strings, $P switch support
  1069. Revision 1.34 1998/11/16 12:21:48 peter
  1070. * fixes for 0.99.8
  1071. Revision 1.33 1998/10/23 00:03:29 peter
  1072. * write(pchar) has check for nil
  1073. Revision 1.32 1998/10/20 14:37:45 peter
  1074. * fixed maxlen which was not correct after my read_string update
  1075. Revision 1.31 1998/10/10 15:28:48 peter
  1076. + read single,fixed
  1077. + val with code:longint
  1078. + val for fixed
  1079. Revision 1.30 1998/09/29 08:39:07 michael
  1080. + Ansistring write now gets pointer.
  1081. Revision 1.29 1998/09/28 14:27:08 michael
  1082. + AnsiStrings update
  1083. Revision 1.28 1998/09/24 23:32:24 peter
  1084. * fixed small bug with a #13#10 on a line
  1085. Revision 1.27 1998/09/18 12:23:22 peter
  1086. * fixed a bug introduced by my previous update
  1087. Revision 1.26 1998/09/17 16:34:18 peter
  1088. * new eof,eoln,seekeoln,seekeof
  1089. * speed upgrade for read_string
  1090. * inoutres 104/105 updates for read_* and write_*
  1091. Revision 1.25 1998/09/14 10:48:23 peter
  1092. * FPC_ names
  1093. * Heap manager is now system independent
  1094. Revision 1.24 1998/09/08 10:14:06 peter
  1095. + textrecbufsize
  1096. Revision 1.23 1998/08/26 15:33:28 peter
  1097. * reset bufpos,bufend in opentext like tp7
  1098. Revision 1.22 1998/08/26 11:23:25 pierre
  1099. * close did not reset the bufpos and bufend fields
  1100. led to problems when using the same file several times
  1101. Revision 1.21 1998/08/17 22:42:17 michael
  1102. + Flush on close only for output files cd ../inc
  1103. Revision 1.20 1998/08/11 00:05:28 peter
  1104. * $ifdef ver0_99_5 updates
  1105. Revision 1.19 1998/07/30 13:26:16 michael
  1106. + Added support for ErrorProc variable. All internal functions are required
  1107. to call HandleError instead of runerror from now on.
  1108. This is necessary for exception support.
  1109. Revision 1.18 1998/07/29 21:44:35 michael
  1110. + Implemented reading/writing of ansistrings
  1111. Revision 1.17 1998/07/19 19:55:33 michael
  1112. + fixed rename. Changed p to p^
  1113. Revision 1.16 1998/07/10 11:02:40 peter
  1114. * support_fixed, becuase fixed is not 100% yet for the m68k
  1115. Revision 1.15 1998/07/06 15:56:43 michael
  1116. Added length checking for string reading
  1117. Revision 1.14 1998/07/02 12:14:56 carl
  1118. + Each IOCheck routine now check InOutRes before, just like TP
  1119. Revision 1.13 1998/07/01 15:30:00 peter
  1120. * better readln/writeln
  1121. Revision 1.12 1998/07/01 14:48:10 carl
  1122. * bugfix of WRITE_TEXT_BOOLEAN , was not TP compatible
  1123. + added explicit typecast in OpenText
  1124. Revision 1.11 1998/06/25 09:44:22 daniel
  1125. + RTLLITE directive to compile minimal RTL.
  1126. Revision 1.10 1998/06/04 23:46:03 peter
  1127. * comp,extended are only i386 added support_comp,support_extended
  1128. Revision 1.9 1998/06/02 16:47:56 pierre
  1129. * bug for boolean values greater than one fixed
  1130. Revision 1.8 1998/05/31 14:14:54 peter
  1131. * removed warnings using comp()
  1132. Revision 1.7 1998/05/27 00:19:21 peter
  1133. * fixed crt input
  1134. Revision 1.6 1998/05/21 19:31:01 peter
  1135. * objects compiles for linux
  1136. + assign(pchar), assign(char), rename(pchar), rename(char)
  1137. * fixed read_text_as_array
  1138. + read_text_as_pchar which was not yet in the rtl
  1139. Revision 1.5 1998/05/12 10:42:45 peter
  1140. * moved getopts to inc/, all supported OS's need argc,argv exported
  1141. + strpas, strlen are now exported in the systemunit
  1142. * removed logs
  1143. * removed $ifdef ver_above
  1144. Revision 1.4 1998/04/07 22:40:46 florian
  1145. * final fix of comp writing
  1146. }