text.inc 25 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130
  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. var
  32. i : longint;
  33. Begin
  34. i:=Do_Write(t.Handle,Longint(t.Bufptr),t.BufPos);
  35. if i<>t.BufPos then
  36. InOutRes:=101;
  37. t.BufPos:=0;
  38. End;
  39. Procedure FileOpenFunc(var t:TextRec);
  40. var
  41. Flags : Longint;
  42. Begin
  43. Case t.mode Of
  44. fmInput : Flags:=$1000;
  45. fmOutput : Flags:=$1101;
  46. fmAppend : Flags:=$1011;
  47. else
  48. begin
  49. InOutRes:=102;
  50. exit;
  51. end;
  52. End;
  53. Do_Open(t,PChar(@t.Name),Flags);
  54. t.CloseFunc:=@FileCloseFunc;
  55. t.FlushFunc:=nil;
  56. if t.Mode=fmInput then
  57. t.InOutFunc:=@FileReadFunc
  58. else
  59. begin
  60. t.InOutFunc:=@FileWriteFunc;
  61. { Only install flushing if its a NOT a file, and only check if there
  62. was no error opening the file, becuase else we always get a bad
  63. file handle error 6 (PFV) }
  64. if (InOutRes=0) and
  65. Do_Isdevice(t.Handle) then
  66. t.FlushFunc:=@FileWriteFunc;
  67. end;
  68. End;
  69. Procedure assign(var t:Text;const s:String);
  70. Begin
  71. FillChar(t,SizEof(TextRec),0);
  72. { only set things that are not zero }
  73. TextRec(t).Handle:=UnusedHandle;
  74. TextRec(t).mode:=fmClosed;
  75. TextRec(t).BufSize:=TextRecBufSize;
  76. TextRec(t).Bufptr:=@TextRec(t).Buffer;
  77. TextRec(t).OpenFunc:=@FileOpenFunc;
  78. Move(s[1],TextRec(t).Name,Length(s));
  79. End;
  80. Procedure assign(var t:Text;p:pchar);
  81. begin
  82. Assign(t,StrPas(p));
  83. end;
  84. Procedure assign(var t:Text;c:char);
  85. begin
  86. Assign(t,string(c));
  87. end;
  88. Procedure Close(var t : Text);[IOCheck];
  89. Begin
  90. if InOutRes<>0 then
  91. Exit;
  92. If (TextRec(t).mode<>fmClosed) Then
  93. Begin
  94. { Write pending buffer }
  95. If Textrec(t).Mode=fmoutput then
  96. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  97. TextRec(t).mode:=fmClosed;
  98. { Only close functions not connected to stdout.}
  99. If ((TextRec(t).Handle<>StdInputHandle) and
  100. (TextRec(t).Handle<>StdOutputHandle) and
  101. (TextRec(t).Handle<>StdErrorHandle)) Then
  102. FileFunc(TextRec(t).CloseFunc)(TextRec(t));
  103. { Reset buffer for safety }
  104. TextRec(t).BufPos:=0;
  105. TextRec(t).BufEnd:=0;
  106. End;
  107. End;
  108. Procedure OpenText(var t : Text;mode,defHdl:Longint);
  109. Begin
  110. Case TextRec(t).mode Of {This gives the fastest code}
  111. fmInput,fmOutput,fmInOut : Close(t);
  112. fmClosed : ;
  113. else
  114. Begin
  115. InOutRes:=102;
  116. exit;
  117. End;
  118. End;
  119. TextRec(t).mode:=mode;
  120. TextRec(t).bufpos:=0;
  121. TextRec(t).bufend:=0;
  122. FileFunc(TextRec(t).OpenFunc)(TextRec(t));
  123. { reset the mode to closed when an error has occured }
  124. if InOutRes<>0 then
  125. TextRec(t).mode:=fmClosed;
  126. End;
  127. Procedure Rewrite(var t : Text);[IOCheck];
  128. Begin
  129. If InOutRes<>0 then
  130. exit;
  131. OpenText(t,fmOutput,1);
  132. End;
  133. Procedure Reset(var t : Text);[IOCheck];
  134. Begin
  135. If InOutRes<>0 then
  136. exit;
  137. OpenText(t,fmInput,0);
  138. End;
  139. Procedure Append(var t : Text);[IOCheck];
  140. Begin
  141. If InOutRes<>0 then
  142. exit;
  143. OpenText(t,fmAppend,1);
  144. End;
  145. Procedure Flush(var t : Text);[IOCheck];
  146. Begin
  147. If InOutRes<>0 then
  148. exit;
  149. If TextRec(t).mode<>fmOutput Then
  150. begin
  151. InOutres:=105;
  152. exit;
  153. end;
  154. { Not the flushfunc but the inoutfunc should be used, becuase that
  155. writes the data, flushfunc doesn't need to be assigned }
  156. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  157. End;
  158. Procedure Erase(var t:Text);[IOCheck];
  159. Begin
  160. If InOutRes <> 0 then
  161. exit;
  162. If TextRec(t).mode=fmClosed Then
  163. Do_Erase(PChar(@TextRec(t).Name));
  164. End;
  165. Procedure Rename(var t : text;p:pchar);[IOCheck];
  166. Begin
  167. If InOutRes <> 0 then
  168. exit;
  169. If TextRec(t).mode=fmClosed Then
  170. Begin
  171. Do_Rename(PChar(@TextRec(t).Name),p);
  172. Move(p^,TextRec(t).Name,StrLen(p)+1);
  173. End;
  174. End;
  175. Procedure Rename(var t : Text;const s : string);[IOCheck];
  176. var
  177. p : array[0..255] Of Char;
  178. Begin
  179. If InOutRes <> 0 then
  180. exit;
  181. Move(s[1],p,Length(s));
  182. p[Length(s)]:=#0;
  183. Rename(t,Pchar(@p));
  184. End;
  185. Procedure Rename(var t : Text;c : char);[IOCheck];
  186. var
  187. p : array[0..1] Of Char;
  188. Begin
  189. If InOutRes <> 0 then
  190. exit;
  191. p[0]:=c;
  192. p[1]:=#0;
  193. Rename(t,Pchar(@p));
  194. End;
  195. Function Eof(Var t: Text): Boolean;[IOCheck];
  196. Begin
  197. If (InOutRes<>0) then
  198. exit(true);
  199. if (TextRec(t).mode<>fmInput) Then
  200. begin
  201. InOutRes:=104;
  202. exit(true);
  203. end;
  204. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  205. begin
  206. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  207. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  208. exit(true);
  209. end;
  210. {$ifdef EOF_CTRLZ}
  211. Eof:=(TextRec(t).Bufptr^[TextRec(t).BufPos]=#26);
  212. {$else}
  213. Eof:=false;
  214. {$endif EOL_CTRLZ}
  215. end;
  216. Function Eof:Boolean;
  217. Begin
  218. Eof:=Eof(Input);
  219. End;
  220. Function SeekEof (Var t : Text) : Boolean;
  221. Begin
  222. If (InOutRes<>0) then
  223. exit(true);
  224. if (TextRec(t).mode<>fmInput) Then
  225. begin
  226. InOutRes:=104;
  227. exit(true);
  228. end;
  229. repeat
  230. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  231. begin
  232. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  233. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  234. exit(true);
  235. end;
  236. case TextRec(t).Bufptr^[TextRec(t).BufPos] of
  237. #26 : exit(true);
  238. #10,#13,
  239. #9,' ' : ;
  240. else
  241. exit(false);
  242. end;
  243. inc(TextRec(t).BufPos);
  244. until false;
  245. End;
  246. Function SeekEof : Boolean;
  247. Begin
  248. SeekEof:=SeekEof(Input);
  249. End;
  250. Function Eoln(var t:Text) : Boolean;
  251. Begin
  252. If (InOutRes<>0) then
  253. exit(true);
  254. if (TextRec(t).mode<>fmInput) Then
  255. begin
  256. InOutRes:=104;
  257. exit(true);
  258. end;
  259. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  260. begin
  261. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  262. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  263. exit(true);
  264. end;
  265. Eoln:=(TextRec(t).Bufptr^[TextRec(t).BufPos] in [#10,#13]);
  266. End;
  267. Function Eoln : Boolean;
  268. Begin
  269. Eoln:=Eoln(Input);
  270. End;
  271. Function SeekEoln (Var t : Text) : Boolean;
  272. Begin
  273. If (InOutRes<>0) then
  274. exit(true);
  275. if (TextRec(t).mode<>fmInput) Then
  276. begin
  277. InOutRes:=104;
  278. exit(true);
  279. end;
  280. repeat
  281. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  282. begin
  283. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  284. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  285. exit(true);
  286. end;
  287. case TextRec(t).Bufptr^[TextRec(t).BufPos] of
  288. #26,
  289. #10,#13 : exit(true);
  290. #9,' ' : ;
  291. else
  292. exit(false);
  293. end;
  294. inc(TextRec(t).BufPos);
  295. until false;
  296. End;
  297. Function SeekEoln : Boolean;
  298. Begin
  299. SeekEoln:=SeekEoln(Input);
  300. End;
  301. Procedure SetTextBuf(Var F : Text; Var Buf);[INTERNPROC: In_settextbuf_file_x];
  302. Procedure SetTextBuf(Var F : Text; Var Buf; Size : Longint);
  303. Begin
  304. TextRec(f).BufPtr:=@Buf;
  305. TextRec(f).BufSize:=Size;
  306. TextRec(f).BufPos:=0;
  307. TextRec(f).BufEnd:=0;
  308. End;
  309. {*****************************************************************************
  310. Write(Ln)
  311. *****************************************************************************}
  312. Procedure WriteBuffer(var f:TextRec;var b;len:longint);
  313. var
  314. p : pchar;
  315. left,
  316. idx : longint;
  317. begin
  318. p:=pchar(@b);
  319. idx:=0;
  320. left:=f.BufSize-f.BufPos;
  321. while len>left do
  322. begin
  323. move(p[idx],f.Bufptr^[f.BufPos],left);
  324. dec(len,left);
  325. inc(idx,left);
  326. inc(f.BufPos,left);
  327. FileFunc(f.InOutFunc)(f);
  328. left:=f.BufSize-f.BufPos;
  329. end;
  330. move(p[idx],f.Bufptr^[f.BufPos],len);
  331. inc(f.BufPos,len);
  332. end;
  333. Procedure WriteBlanks(var f:TextRec;len:longint);
  334. var
  335. left : longint;
  336. begin
  337. left:=f.BufSize-f.BufPos;
  338. while len>left do
  339. begin
  340. FillChar(f.Bufptr^[f.BufPos],left,' ');
  341. dec(len,left);
  342. inc(f.BufPos,left);
  343. FileFunc(f.InOutFunc)(f);
  344. left:=f.BufSize-f.BufPos;
  345. end;
  346. FillChar(f.Bufptr^[f.BufPos],len,' ');
  347. inc(f.BufPos,len);
  348. end;
  349. Procedure Write_End(var f:TextRec);[Public,Alias:'FPC_WRITE_END'];
  350. begin
  351. if f.FlushFunc<>nil then
  352. FileFunc(f.FlushFunc)(f);
  353. end;
  354. Procedure Writeln_End(var f:TextRec);[Public,Alias:'FPC_WRITELN_END'];
  355. const
  356. {$IFDEF SHORT_LINEBREAK}
  357. eollen=1;
  358. eol : array[0..0] of char=(#10);
  359. {$ELSE SHORT_LINEBREAK}
  360. eollen=2;
  361. eol : array[0..1] of char=(#13,#10);
  362. {$ENDIF SHORT_LINEBREAK}
  363. begin
  364. If InOutRes <> 0 then exit;
  365. { Write EOL }
  366. WriteBuffer(f,eol,eollen);
  367. { Flush }
  368. if f.FlushFunc<>nil then
  369. FileFunc(f.FlushFunc)(f);
  370. end;
  371. Procedure Write_Str(Len : Longint;var f : TextRec;const s : String);[Public,Alias:'FPC_WRITE_TEXT_SHORTSTR'];
  372. Begin
  373. If (InOutRes<>0) then
  374. exit;
  375. if (f.mode<>fmOutput) Then
  376. begin
  377. InOutRes:=105;
  378. exit;
  379. end;
  380. If Len>Length(s) Then
  381. WriteBlanks(f,Len-Length(s));
  382. WriteBuffer(f,s[1],Length(s));
  383. End;
  384. Procedure Write_Array(Len : Longint;var f : TextRec;const s : array of char);[Public,Alias:'FPC_WRITE_TEXT_PCHAR_AS_ARRAY'];
  385. var
  386. ArrayLen : longint;
  387. p : pchar;
  388. Begin
  389. If (InOutRes<>0) then
  390. exit;
  391. if (f.mode<>fmOutput) Then
  392. begin
  393. InOutRes:=105;
  394. exit;
  395. end;
  396. p:=pchar(@s);
  397. ArrayLen:=StrLen(p);
  398. if ArrayLen>sizeof(s) then
  399. ArrayLen:=sizeof(s);
  400. If Len>ArrayLen Then
  401. WriteBlanks(f,Len-ArrayLen);
  402. WriteBuffer(f,p^,ArrayLen);
  403. End;
  404. Procedure Write_PChar(Len : Longint;var f : TextRec;p : PChar);[Public,Alias:'FPC_WRITE_TEXT_PCHAR_AS_POINTER'];
  405. var
  406. PCharLen : longint;
  407. Begin
  408. If (p=nil) or (InOutRes<>0) then
  409. exit;
  410. if (f.mode<>fmOutput) Then
  411. begin
  412. InOutRes:=105;
  413. exit;
  414. end;
  415. PCharLen:=StrLen(p);
  416. If Len>PCharLen Then
  417. WriteBlanks(f,Len-PCharLen);
  418. WriteBuffer(f,p^,PCharLen);
  419. End;
  420. Procedure Write_Text_AnsiString (Len : Longint; Var T : TextRec; S : Pointer);[Public,alias:'FPC_WRITE_TEXT_ANSISTR'];
  421. {
  422. Writes a AnsiString to the Text file T
  423. }
  424. begin
  425. If S=Nil then
  426. exit;
  427. Write_pchar (Len,t,PChar(S));
  428. end;
  429. Procedure Write_SInt(Len : Longint;var t : TextRec;l : ValSInt);[Public,Alias:'FPC_WRITE_TEXT_SINT'];
  430. var
  431. s : String;
  432. Begin
  433. If (InOutRes<>0) then
  434. exit;
  435. Str(l,s);
  436. Write_Str(Len,t,s);
  437. End;
  438. Procedure Write_UInt(Len : Longint;var t : TextRec;l : ValUInt);[Public,Alias:'FPC_WRITE_TEXT_UINT'];
  439. var
  440. s : String;
  441. Begin
  442. If (InOutRes<>0) then
  443. exit;
  444. Str(L,s);
  445. Write_Str(Len,t,s);
  446. End;
  447. {$ifdef INT64}
  448. procedure write_qword(len : longint;var t : textrec;q : qword);[public,alias:'FPC_WRITE_TEXT_QWORD'];
  449. var
  450. s : string;
  451. begin
  452. if (InOutRes<>0) then
  453. exit;
  454. int_str(q,s);
  455. write_str(len,t,s);
  456. end;
  457. procedure write_int64(len : longint;var t : textrec;i : int64);[public,alias:'FPC_WRITE_TEXT_INT64'];
  458. var
  459. s : string;
  460. begin
  461. if (InOutRes<>0) then
  462. exit;
  463. int_str(i,s);
  464. write_str(len,t,s);
  465. end;
  466. {$endif INT64}
  467. Procedure Write_Float(rt,fixkomma,Len : Longint;var t : TextRec;r : ValReal);[Public,Alias:'FPC_WRITE_TEXT_FLOAT'];
  468. var
  469. s : String;
  470. Begin
  471. If (InOutRes<>0) then
  472. exit;
  473. Str_real(Len,fixkomma,r,treal_type(rt),s);
  474. Write_Str(Len,t,s);
  475. End;
  476. Procedure Write_Boolean(Len : Longint;var t : TextRec;b : Boolean);[Public,Alias:'FPC_WRITE_TEXT_BOOLEAN'];
  477. Begin
  478. If (InOutRes<>0) then
  479. exit;
  480. { Can't use array[boolean] because b can be >0 ! }
  481. if b then
  482. Write_Str(Len,t,'TRUE')
  483. else
  484. Write_Str(Len,t,'FALSE');
  485. End;
  486. Procedure Write_Char(Len : Longint;var t : TextRec;c : Char);[Public,Alias:'FPC_WRITE_TEXT_CHAR'];
  487. Begin
  488. If (InOutRes<>0) then
  489. exit;
  490. if (TextRec(t).mode<>fmOutput) Then
  491. begin
  492. InOutRes:=105;
  493. exit;
  494. end;
  495. If Len>1 Then
  496. WriteBlanks(t,Len-1);
  497. If t.BufPos+1>=t.BufSize Then
  498. FileFunc(t.InOutFunc)(t);
  499. t.Bufptr^[t.BufPos]:=c;
  500. Inc(t.BufPos);
  501. End;
  502. {*****************************************************************************
  503. Read(Ln)
  504. *****************************************************************************}
  505. Function NextChar(var f:TextRec;var s:string):Boolean;
  506. begin
  507. if f.BufPos<f.BufEnd then
  508. begin
  509. if length(s)<high(s) then
  510. begin
  511. inc(s[0]);
  512. s[length(s)]:=f.BufPtr^[f.BufPos];
  513. end;
  514. Inc(f.BufPos);
  515. If f.BufPos>=f.BufEnd Then
  516. FileFunc(f.InOutFunc)(f);
  517. NextChar:=true;
  518. end
  519. else
  520. NextChar:=false;
  521. end;
  522. Function IgnoreSpaces(var f:TextRec):Boolean;
  523. {
  524. Removes all leading spaces,tab,eols from the input buffer, returns true if
  525. the buffer is empty
  526. }
  527. var
  528. s : string;
  529. begin
  530. s:='';
  531. IgnoreSpaces:=false;
  532. while f.Bufptr^[f.BufPos] in [#9,#10,#13,' '] do
  533. if not NextChar(f,s) then
  534. exit;
  535. IgnoreSpaces:=true;
  536. end;
  537. Function ReadSign(var f:TextRec;var s:string):Boolean;
  538. {
  539. Read + and - sign, return true if buffer is empty
  540. }
  541. begin
  542. ReadSign:=(not (f.Bufptr^[f.BufPos] in ['-','+'])) or NextChar(f,s);
  543. end;
  544. Function ReadBase(var f:TextRec;var s:string;var Base:longint):boolean;
  545. {
  546. Read the base $ For 16 and % For 2, if buffer is empty return true
  547. }
  548. begin
  549. case f.BufPtr^[f.BufPos] of
  550. '$' : Base:=16;
  551. '%' : Base:=2;
  552. else
  553. Base:=10;
  554. end;
  555. ReadBase:=(Base=10) or NextChar(f,s);
  556. end;
  557. Function ReadNumeric(var f:TextRec;var s:string;base:longint):Boolean;
  558. {
  559. Read numeric input, if buffer is empty then return True
  560. }
  561. var
  562. c : char;
  563. begin
  564. ReadNumeric:=false;
  565. c:=f.BufPtr^[f.BufPos];
  566. while ((base>=10) and (c in ['0'..'9'])) or
  567. ((base=16) and (c in ['A'..'F','a'..'f'])) or
  568. ((base=2) and (c in ['0'..'1'])) do
  569. begin
  570. if not NextChar(f,s) then
  571. exit;
  572. c:=f.BufPtr^[f.BufPos];
  573. end;
  574. ReadNumeric:=true;
  575. end;
  576. Procedure Read_End(var f:TextRec);[Public,Alias:'FPC_READ_END'];
  577. begin
  578. if f.FlushFunc<>nil then
  579. FileFunc(f.FlushFunc)(f);
  580. end;
  581. Procedure ReadLn_End(var f : TextRec);[Public,Alias:'FPC_READLN_END'];
  582. Begin
  583. { Check error and if file is open and load buf if empty }
  584. If (InOutRes<>0) then
  585. exit;
  586. if (f.mode<>fmInput) Then
  587. begin
  588. InOutRes:=104;
  589. exit;
  590. end;
  591. repeat
  592. If f.BufPos>=f.BufEnd Then
  593. begin
  594. FileFunc(f.InOutFunc)(f);
  595. if f.BufPos>=f.BufEnd then
  596. break;
  597. end;
  598. inc(f.BufPos);
  599. if (f.BufPtr^[f.BufPos-1]=#10) then
  600. exit;
  601. until false;
  602. { Flush if set }
  603. if f.FlushFunc<>nil then
  604. FileFunc(f.FlushFunc)(f);
  605. End;
  606. Function ReadPCharLen(var f:TextRec;s:pchar;maxlen:longint):longint;
  607. var
  608. sPos,len : Longint;
  609. p,startp,maxp : pchar;
  610. Begin
  611. ReadPCharLen:=0;
  612. { Check error and if file is open }
  613. If (InOutRes<>0) then
  614. exit;
  615. if (f.mode<>fmInput) Then
  616. begin
  617. InOutRes:=104;
  618. exit;
  619. end;
  620. { Read maximal until Maxlen is reached }
  621. sPos:=0;
  622. repeat
  623. If f.BufPos>=f.BufEnd Then
  624. begin
  625. FileFunc(f.InOutFunc)(f);
  626. If f.BufPos>=f.BufEnd Then
  627. break;
  628. end;
  629. p:[email protected]^[f.BufPos];
  630. if SPos+f.BufEnd-f.BufPos>MaxLen then
  631. maxp:[email protected]^[f.BufPos+MaxLen-SPos]
  632. else
  633. maxp:[email protected]^[f.BufEnd];
  634. startp:=p;
  635. { search linefeed }
  636. while (p<maxp) and (P^<>#10) do
  637. inc(p);
  638. { calculate read bytes }
  639. len:=p-startp;
  640. inc(f.BufPos,Len);
  641. Move(startp^,s[sPos],Len);
  642. inc(sPos,Len);
  643. { was it a LF? then leave }
  644. if (p<maxp) and (p^=#10) then
  645. begin
  646. if (spos>0) and (s[spos-1]=#13) then
  647. dec(sPos);
  648. break;
  649. end;
  650. { Maxlen reached ? }
  651. if spos=MaxLen then
  652. break;
  653. until false;
  654. ReadPCharLen:=spos;
  655. End;
  656. Procedure Read_String(var f : TextRec;var s : String);[Public,Alias:'FPC_READ_TEXT_SHORTSTR'];
  657. Begin
  658. s[0]:=chr(ReadPCharLen(f,pchar(@s[1]),high(s)));
  659. End;
  660. Procedure Read_PChar(var f : TextRec;var s : PChar);[Public,Alias:'FPC_READ_TEXT_PCHAR_AS_POINTER'];
  661. Begin
  662. pchar(s+ReadPCharLen(f,s,$7fffffff))^:=#0;
  663. End;
  664. Procedure Read_Array(var f : TextRec;var s : array of char);[Public,Alias:'FPC_READ_TEXT_PCHAR_AS_ARRAY'];
  665. Begin
  666. pchar(pchar(@s)+ReadPCharLen(f,pchar(@s),high(s)))^:=#0;
  667. End;
  668. Procedure Read_AnsiString(var f : TextRec;var s : AnsiString);[Public,Alias:'FPC_READ_TEXT_ANSISTR'];
  669. var
  670. len : longint;
  671. Begin
  672. { Delete the string }
  673. Setlength(S,0);
  674. Repeat
  675. // SetLength will reallocate the length.
  676. SetLength(S,Length(S)+255);
  677. len:=ReadPCharLen(f,pchar(Pointer(S)+Length(S)-255),255);
  678. If Len<255 then
  679. // Set actual length
  680. SetLength(S,Length(S)-255+Len);
  681. Until len<255;
  682. End;
  683. Function Read_Char(var f : TextRec):char;[Public,Alias:'FPC_READ_TEXT_CHAR'];
  684. Begin
  685. Read_Char:=#0;
  686. { Check error and if file is open }
  687. If (InOutRes<>0) then
  688. exit;
  689. if (f.mode<>fmInput) Then
  690. begin
  691. InOutRes:=104;
  692. exit;
  693. end;
  694. { Read next char or EOF }
  695. If f.BufPos>=f.BufEnd Then
  696. begin
  697. FileFunc(f.InOutFunc)(f);
  698. If f.BufPos>=f.BufEnd Then
  699. exit(#26);
  700. end;
  701. Read_Char:=f.Bufptr^[f.BufPos];
  702. inc(f.BufPos);
  703. end;
  704. Function Read_SInt(var f : TextRec):ValSInt;[Public,Alias:'FPC_READ_TEXT_SINT'];
  705. var
  706. hs : String;
  707. code : Longint;
  708. base : longint;
  709. Begin
  710. Read_SInt:=0;
  711. { Leave if error or not open file, else check for empty buf }
  712. If (InOutRes<>0) then
  713. exit;
  714. if (f.mode<>fmInput) Then
  715. begin
  716. InOutRes:=104;
  717. exit;
  718. end;
  719. If f.BufPos>=f.BufEnd Then
  720. FileFunc(f.InOutFunc)(f);
  721. hs:='';
  722. if IgnoreSpaces(f) and ReadSign(f,hs) and ReadBase(f,hs,Base) then
  723. ReadNumeric(f,hs,Base);
  724. Val(hs,Read_SInt,code);
  725. If code<>0 Then
  726. InOutRes:=106;
  727. End;
  728. Function Read_UInt(var f : TextRec):ValUInt;[Public,Alias:'FPC_READ_TEXT_UINT'];
  729. var
  730. hs : String;
  731. code : longint;
  732. base : longint;
  733. Begin
  734. Read_UInt:=0;
  735. { Leave if error or not open file, else check for empty buf }
  736. If (InOutRes<>0) then
  737. exit;
  738. if (f.mode<>fmInput) Then
  739. begin
  740. InOutRes:=104;
  741. exit;
  742. end;
  743. If f.BufPos>=f.BufEnd Then
  744. FileFunc(f.InOutFunc)(f);
  745. hs:='';
  746. if IgnoreSpaces(f) and ReadSign(f,hs) and ReadBase(f,hs,Base) then
  747. ReadNumeric(f,hs,Base);
  748. val(hs,Read_UInt,code);
  749. If code<>0 Then
  750. InOutRes:=106;
  751. End;
  752. Function Read_Float(var f : TextRec):ValReal;[Public,Alias:'FPC_READ_TEXT_FLOAT'];
  753. var
  754. hs : string;
  755. code : Word;
  756. begin
  757. Read_Float:=0.0;
  758. { Leave if error or not open file, else check for empty buf }
  759. If (InOutRes<>0) then
  760. exit;
  761. if (f.mode<>fmInput) Then
  762. begin
  763. InOutRes:=104;
  764. exit;
  765. end;
  766. If f.BufPos>=f.BufEnd Then
  767. FileFunc(f.InOutFunc)(f);
  768. hs:='';
  769. if IgnoreSpaces(f) and ReadSign(f,hs) and ReadNumeric(f,hs,10) then
  770. begin
  771. { First check for a . }
  772. if (f.Bufptr^[f.BufPos]='.') and (f.BufPos<f.BufEnd) Then
  773. begin
  774. hs:=hs+'.';
  775. Inc(f.BufPos);
  776. If f.BufPos>=f.BufEnd Then
  777. FileFunc(f.InOutFunc)(f);
  778. ReadNumeric(f,hs,10);
  779. end;
  780. { Also when a point is found check for a E }
  781. if (f.Bufptr^[f.BufPos] in ['e','E']) and (f.BufPos<f.BufEnd) Then
  782. begin
  783. hs:=hs+'E';
  784. Inc(f.BufPos);
  785. If f.BufPos>=f.BufEnd Then
  786. FileFunc(f.InOutFunc)(f);
  787. if ReadSign(f,hs) then
  788. ReadNumeric(f,hs,10);
  789. end;
  790. end;
  791. val(hs,Read_Float,code);
  792. If code<>0 Then
  793. InOutRes:=106;
  794. end;
  795. {$ifdef INT64}
  796. procedure read_qword(len : longint;var t : textrec;q : qword);[public,alias:'FPC_READ_TEXT_QWORD'];
  797. begin
  798. { !!!!!!!!!!!!! }
  799. end;
  800. {$endif INT64}
  801. {*****************************************************************************
  802. Initializing
  803. *****************************************************************************}
  804. procedure OpenStdIO(var f:text;mode,hdl:longint);
  805. begin
  806. Assign(f,'');
  807. TextRec(f).Handle:=hdl;
  808. TextRec(f).Mode:=mode;
  809. TextRec(f).Closefunc:=@FileCloseFunc;
  810. case mode of
  811. fmInput :
  812. TextRec(f).InOutFunc:=@FileReadFunc;
  813. fmOutput :
  814. begin
  815. TextRec(f).InOutFunc:=@FileWriteFunc;
  816. TextRec(f).FlushFunc:=@FileWriteFunc;
  817. end;
  818. else
  819. HandleError(102);
  820. end;
  821. end;
  822. {
  823. $Log$
  824. Revision 1.55 1999-09-08 16:12:24 peter
  825. * fixed inoutres for diskfull
  826. Revision 1.54 1999/09/07 07:44:58 peter
  827. * fixed array of char writing which didn't write the last char
  828. Revision 1.53 1999/08/19 11:16:14 peter
  829. * settextbuf size is now longint
  830. Revision 1.52 1999/08/03 21:58:45 peter
  831. * small speed improvements
  832. Revision 1.51 1999/07/26 09:43:24 florian
  833. + write helper routine for in64 implemented
  834. Revision 1.50 1999/07/08 15:18:14 michael
  835. * Now ansistring of arbitrary length can be read
  836. Revision 1.49 1999/07/05 20:04:29 peter
  837. * removed temp defines
  838. Revision 1.48 1999/07/01 15:39:52 florian
  839. + qword/int64 type released
  840. Revision 1.47 1999/06/30 22:17:24 florian
  841. + fpuint64 to system unit interface added: if it is true, the rtl
  842. uses the fpu to do int64 operations, if possible
  843. Revision 1.46 1999/05/06 09:05:16 peter
  844. * generic write_float str_float
  845. Revision 1.45 1999/04/26 18:27:26 peter
  846. * fixed write array
  847. * read array with maxlen
  848. Revision 1.44 1999/04/08 15:57:57 peter
  849. + subrange checking for readln()
  850. Revision 1.43 1999/04/07 22:05:18 peter
  851. * fixed bug with readln where it sometime didn't read until eol
  852. Revision 1.42 1999/03/16 17:49:39 jonas
  853. * changes for internal Val code (do a "make cycle OPT=-dvalintern" to test)
  854. * in text.inc: changed RTE 106 when read integer values are out of bounds to RTE 201
  855. * in systemh.inc: disabled "support_fixed" for the i386 because it gave internal errors,
  856. Revision 1.41 1999/03/02 18:23:37 peter
  857. * changed so handlerror() -> inoutres:= to have $I- support
  858. Revision 1.40 1999/03/01 15:41:04 peter
  859. * use external names
  860. * removed all direct assembler modes
  861. Revision 1.39 1999/02/17 10:13:29 peter
  862. * when error when opening a file, then reset the mode to fmclosed
  863. Revision 1.38 1999/01/28 19:38:19 peter
  864. * fixed readln(ansistring)
  865. Revision 1.37 1998/12/15 22:43:06 peter
  866. * removed temp symbols
  867. Revision 1.36 1998/12/11 18:07:39 peter
  868. * fixed read(char) with empty buffer
  869. Revision 1.35 1998/11/27 14:50:58 peter
  870. + open strings, $P switch support
  871. Revision 1.34 1998/11/16 12:21:48 peter
  872. * fixes for 0.99.8
  873. Revision 1.33 1998/10/23 00:03:29 peter
  874. * write(pchar) has check for nil
  875. Revision 1.32 1998/10/20 14:37:45 peter
  876. * fixed maxlen which was not correct after my read_string update
  877. Revision 1.31 1998/10/10 15:28:48 peter
  878. + read single,fixed
  879. + val with code:longint
  880. + val for fixed
  881. Revision 1.30 1998/09/29 08:39:07 michael
  882. + Ansistring write now gets pointer.
  883. Revision 1.29 1998/09/28 14:27:08 michael
  884. + AnsiStrings update
  885. Revision 1.28 1998/09/24 23:32:24 peter
  886. * fixed small bug with a #13#10 on a line
  887. Revision 1.27 1998/09/18 12:23:22 peter
  888. * fixed a bug introduced by my previous update
  889. Revision 1.26 1998/09/17 16:34:18 peter
  890. * new eof,eoln,seekeoln,seekeof
  891. * speed upgrade for read_string
  892. * inoutres 104/105 updates for read_* and write_*
  893. Revision 1.25 1998/09/14 10:48:23 peter
  894. * FPC_ names
  895. * Heap manager is now system independent
  896. Revision 1.24 1998/09/08 10:14:06 peter
  897. + textrecbufsize
  898. Revision 1.23 1998/08/26 15:33:28 peter
  899. * reset bufpos,bufend in opentext like tp7
  900. Revision 1.22 1998/08/26 11:23:25 pierre
  901. * close did not reset the bufpos and bufend fields
  902. led to problems when using the same file several times
  903. Revision 1.21 1998/08/17 22:42:17 michael
  904. + Flush on close only for output files cd ../inc
  905. Revision 1.20 1998/08/11 00:05:28 peter
  906. * $ifdef ver0_99_5 updates
  907. Revision 1.19 1998/07/30 13:26:16 michael
  908. + Added support for ErrorProc variable. All internal functions are required
  909. to call HandleError instead of runerror from now on.
  910. This is necessary for exception support.
  911. Revision 1.18 1998/07/29 21:44:35 michael
  912. + Implemented reading/writing of ansistrings
  913. Revision 1.17 1998/07/19 19:55:33 michael
  914. + fixed rename. Changed p to p^
  915. Revision 1.16 1998/07/10 11:02:40 peter
  916. * support_fixed, becuase fixed is not 100% yet for the m68k
  917. Revision 1.15 1998/07/06 15:56:43 michael
  918. Added length checking for string reading
  919. Revision 1.14 1998/07/02 12:14:56 carl
  920. + Each IOCheck routine now check InOutRes before, just like TP
  921. Revision 1.13 1998/07/01 15:30:00 peter
  922. * better readln/writeln
  923. Revision 1.12 1998/07/01 14:48:10 carl
  924. * bugfix of WRITE_TEXT_BOOLEAN , was not TP compatible
  925. + added explicit typecast in OpenText
  926. Revision 1.11 1998/06/25 09:44:22 daniel
  927. + RTLLITE directive to compile minimal RTL.
  928. Revision 1.10 1998/06/04 23:46:03 peter
  929. * comp,extended are only i386 added support_comp,support_extended
  930. Revision 1.9 1998/06/02 16:47:56 pierre
  931. * bug for boolean values greater than one fixed
  932. Revision 1.8 1998/05/31 14:14:54 peter
  933. * removed warnings using comp()
  934. Revision 1.7 1998/05/27 00:19:21 peter
  935. * fixed crt input
  936. Revision 1.6 1998/05/21 19:31:01 peter
  937. * objects compiles for linux
  938. + assign(pchar), assign(char), rename(pchar), rename(char)
  939. * fixed read_text_as_array
  940. + read_text_as_pchar which was not yet in the rtl
  941. Revision 1.5 1998/05/12 10:42:45 peter
  942. * moved getopts to inc/, all supported OS's need argc,argv exported
  943. + strpas, strlen are now exported in the systemunit
  944. * removed logs
  945. * removed $ifdef ver_above
  946. Revision 1.4 1998/04/07 22:40:46 florian
  947. * final fix of comp writing
  948. }