text.inc 24 KB

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