text.inc 27 KB

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