text.inc 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
  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 : Longint);
  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>sizeof(s) then
  392. ArrayLen:=sizeof(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. procedure write_int64(len : longint;var t : textrec;i : int64);[public,alias:'FPC_WRITE_TEXT_INT64'];
  451. var
  452. s : string;
  453. begin
  454. if (InOutRes<>0) then
  455. exit;
  456. int_str(i,s);
  457. write_str(len,t,s);
  458. end;
  459. {$endif INT64}
  460. Procedure Write_Float(rt,fixkomma,Len : Longint;var t : TextRec;r : ValReal);[Public,Alias:'FPC_WRITE_TEXT_FLOAT'];
  461. var
  462. s : String;
  463. Begin
  464. If (InOutRes<>0) then
  465. exit;
  466. Str_real(Len,fixkomma,r,treal_type(rt),s);
  467. Write_Str(Len,t,s);
  468. End;
  469. Procedure Write_Boolean(Len : Longint;var t : TextRec;b : Boolean);[Public,Alias:'FPC_WRITE_TEXT_BOOLEAN'];
  470. Begin
  471. If (InOutRes<>0) then
  472. exit;
  473. { Can't use array[boolean] because b can be >0 ! }
  474. if b then
  475. Write_Str(Len,t,'TRUE')
  476. else
  477. Write_Str(Len,t,'FALSE');
  478. End;
  479. Procedure Write_Char(Len : Longint;var t : TextRec;c : Char);[Public,Alias:'FPC_WRITE_TEXT_CHAR'];
  480. Begin
  481. If (InOutRes<>0) then
  482. exit;
  483. if (TextRec(t).mode<>fmOutput) Then
  484. begin
  485. InOutRes:=105;
  486. exit;
  487. end;
  488. If Len>1 Then
  489. WriteBlanks(t,Len-1);
  490. If t.BufPos+1>=t.BufSize Then
  491. FileFunc(t.InOutFunc)(t);
  492. t.Bufptr^[t.BufPos]:=c;
  493. Inc(t.BufPos);
  494. End;
  495. {*****************************************************************************
  496. Read(Ln)
  497. *****************************************************************************}
  498. Function NextChar(var f:TextRec;var s:string):Boolean;
  499. begin
  500. if f.BufPos<f.BufEnd then
  501. begin
  502. if length(s)<high(s) then
  503. begin
  504. inc(s[0]);
  505. s[length(s)]:=f.BufPtr^[f.BufPos];
  506. end;
  507. Inc(f.BufPos);
  508. If f.BufPos>=f.BufEnd Then
  509. FileFunc(f.InOutFunc)(f);
  510. NextChar:=true;
  511. end
  512. else
  513. NextChar:=false;
  514. end;
  515. Function IgnoreSpaces(var f:TextRec):Boolean;
  516. {
  517. Removes all leading spaces,tab,eols from the input buffer, returns true if
  518. the buffer is empty
  519. }
  520. var
  521. s : string;
  522. begin
  523. s:='';
  524. IgnoreSpaces:=false;
  525. while f.Bufptr^[f.BufPos] in [#9,#10,#13,' '] do
  526. if not NextChar(f,s) then
  527. exit;
  528. IgnoreSpaces:=true;
  529. end;
  530. Function ReadSign(var f:TextRec;var s:string):Boolean;
  531. {
  532. Read + and - sign, return true if buffer is empty
  533. }
  534. begin
  535. ReadSign:=(not (f.Bufptr^[f.BufPos] in ['-','+'])) or NextChar(f,s);
  536. end;
  537. Function ReadBase(var f:TextRec;var s:string;var Base:longint):boolean;
  538. {
  539. Read the base $ For 16 and % For 2, if buffer is empty return true
  540. }
  541. begin
  542. case f.BufPtr^[f.BufPos] of
  543. '$' : Base:=16;
  544. '%' : Base:=2;
  545. else
  546. Base:=10;
  547. end;
  548. ReadBase:=(Base=10) or NextChar(f,s);
  549. end;
  550. Function ReadNumeric(var f:TextRec;var s:string;base:longint):Boolean;
  551. {
  552. Read numeric input, if buffer is empty then return True
  553. }
  554. var
  555. c : char;
  556. begin
  557. ReadNumeric:=false;
  558. c:=f.BufPtr^[f.BufPos];
  559. while ((base>=10) and (c in ['0'..'9'])) or
  560. ((base=16) and (c in ['A'..'F','a'..'f'])) or
  561. ((base=2) and (c in ['0'..'1'])) do
  562. begin
  563. if not NextChar(f,s) then
  564. exit;
  565. c:=f.BufPtr^[f.BufPos];
  566. end;
  567. ReadNumeric:=true;
  568. end;
  569. Procedure Read_End(var f:TextRec);[Public,Alias:'FPC_READ_END'];
  570. begin
  571. if f.FlushFunc<>nil then
  572. FileFunc(f.FlushFunc)(f);
  573. end;
  574. Procedure ReadLn_End(var f : TextRec);[Public,Alias:'FPC_READLN_END'];
  575. Begin
  576. { Check error and if file is open and load buf if empty }
  577. If (InOutRes<>0) then
  578. exit;
  579. if (f.mode<>fmInput) Then
  580. begin
  581. InOutRes:=104;
  582. exit;
  583. end;
  584. repeat
  585. If f.BufPos>=f.BufEnd Then
  586. begin
  587. FileFunc(f.InOutFunc)(f);
  588. if f.BufPos>=f.BufEnd then
  589. break;
  590. end;
  591. inc(f.BufPos);
  592. if (f.BufPtr^[f.BufPos-1]=#10) then
  593. exit;
  594. until false;
  595. { Flush if set }
  596. if f.FlushFunc<>nil then
  597. FileFunc(f.FlushFunc)(f);
  598. End;
  599. Function ReadPCharLen(var f:TextRec;s:pchar;maxlen:longint):longint;
  600. var
  601. sPos,len : Longint;
  602. p,startp,maxp : pchar;
  603. Begin
  604. ReadPCharLen:=0;
  605. { Check error and if file is open }
  606. If (InOutRes<>0) then
  607. exit;
  608. if (f.mode<>fmInput) Then
  609. begin
  610. InOutRes:=104;
  611. exit;
  612. end;
  613. { Read maximal until Maxlen is reached }
  614. sPos:=0;
  615. repeat
  616. If f.BufPos>=f.BufEnd Then
  617. begin
  618. FileFunc(f.InOutFunc)(f);
  619. If f.BufPos>=f.BufEnd Then
  620. break;
  621. end;
  622. p:[email protected]^[f.BufPos];
  623. if SPos+f.BufEnd-f.BufPos>MaxLen then
  624. maxp:[email protected]^[f.BufPos+MaxLen-SPos]
  625. else
  626. maxp:[email protected]^[f.BufEnd];
  627. startp:=p;
  628. { search linefeed }
  629. while (p<maxp) and (P^<>#10) do
  630. inc(p);
  631. { calculate read bytes }
  632. len:=p-startp;
  633. inc(f.BufPos,Len);
  634. Move(startp^,s[sPos],Len);
  635. inc(sPos,Len);
  636. { was it a LF? then leave }
  637. if (p<maxp) and (p^=#10) then
  638. begin
  639. if (spos>0) and (s[spos-1]=#13) then
  640. dec(sPos);
  641. break;
  642. end;
  643. { Maxlen reached ? }
  644. if spos=MaxLen then
  645. break;
  646. until false;
  647. ReadPCharLen:=spos;
  648. End;
  649. Procedure Read_String(var f : TextRec;var s : String);[Public,Alias:'FPC_READ_TEXT_SHORTSTR'];
  650. Begin
  651. s[0]:=chr(ReadPCharLen(f,pchar(@s[1]),high(s)));
  652. End;
  653. Procedure Read_PChar(var f : TextRec;var s : PChar);[Public,Alias:'FPC_READ_TEXT_PCHAR_AS_POINTER'];
  654. Begin
  655. pchar(s+ReadPCharLen(f,s,$7fffffff))^:=#0;
  656. End;
  657. Procedure Read_Array(var f : TextRec;var s : array of char);[Public,Alias:'FPC_READ_TEXT_PCHAR_AS_ARRAY'];
  658. Begin
  659. pchar(pchar(@s)+ReadPCharLen(f,pchar(@s),high(s)))^:=#0;
  660. End;
  661. Procedure Read_AnsiString(var f : TextRec;var s : AnsiString);[Public,Alias:'FPC_READ_TEXT_ANSISTR'];
  662. var
  663. len : longint;
  664. Begin
  665. { Delete the string }
  666. Setlength(S,0);
  667. Repeat
  668. // SetLength will reallocate the length.
  669. SetLength(S,Length(S)+255);
  670. len:=ReadPCharLen(f,pchar(Pointer(S)+Length(S)-255),255);
  671. If Len<255 then
  672. // Set actual length
  673. SetLength(S,Length(S)-255+Len);
  674. Until len<255;
  675. End;
  676. Function Read_Char(var f : TextRec):char;[Public,Alias:'FPC_READ_TEXT_CHAR'];
  677. Begin
  678. Read_Char:=#0;
  679. { Check error and if file is open }
  680. If (InOutRes<>0) then
  681. exit;
  682. if (f.mode<>fmInput) Then
  683. begin
  684. InOutRes:=104;
  685. exit;
  686. end;
  687. { Read next char or EOF }
  688. If f.BufPos>=f.BufEnd Then
  689. begin
  690. FileFunc(f.InOutFunc)(f);
  691. If f.BufPos>=f.BufEnd Then
  692. exit(#26);
  693. end;
  694. Read_Char:=f.Bufptr^[f.BufPos];
  695. inc(f.BufPos);
  696. end;
  697. Function Read_SInt(var f : TextRec):ValSInt;[Public,Alias:'FPC_READ_TEXT_SINT'];
  698. var
  699. hs : String;
  700. code : Longint;
  701. base : longint;
  702. Begin
  703. Read_SInt:=0;
  704. { Leave if error or not open file, else check for empty buf }
  705. If (InOutRes<>0) then
  706. exit;
  707. if (f.mode<>fmInput) Then
  708. begin
  709. InOutRes:=104;
  710. exit;
  711. end;
  712. If f.BufPos>=f.BufEnd Then
  713. FileFunc(f.InOutFunc)(f);
  714. hs:='';
  715. if IgnoreSpaces(f) and ReadSign(f,hs) and ReadBase(f,hs,Base) then
  716. ReadNumeric(f,hs,Base);
  717. Val(hs,Read_SInt,code);
  718. If code<>0 Then
  719. InOutRes:=106;
  720. End;
  721. Function Read_UInt(var f : TextRec):ValUInt;[Public,Alias:'FPC_READ_TEXT_UINT'];
  722. var
  723. hs : String;
  724. code : longint;
  725. base : longint;
  726. Begin
  727. Read_UInt:=0;
  728. { Leave if error or not open file, else check for empty buf }
  729. If (InOutRes<>0) then
  730. exit;
  731. if (f.mode<>fmInput) Then
  732. begin
  733. InOutRes:=104;
  734. exit;
  735. end;
  736. If f.BufPos>=f.BufEnd Then
  737. FileFunc(f.InOutFunc)(f);
  738. hs:='';
  739. if IgnoreSpaces(f) and ReadSign(f,hs) and ReadBase(f,hs,Base) then
  740. ReadNumeric(f,hs,Base);
  741. val(hs,Read_UInt,code);
  742. If code<>0 Then
  743. InOutRes:=106;
  744. End;
  745. Function Read_Float(var f : TextRec):ValReal;[Public,Alias:'FPC_READ_TEXT_FLOAT'];
  746. var
  747. hs : string;
  748. code : Word;
  749. begin
  750. Read_Float:=0.0;
  751. { Leave if error or not open file, else check for empty buf }
  752. If (InOutRes<>0) then
  753. exit;
  754. if (f.mode<>fmInput) Then
  755. begin
  756. InOutRes:=104;
  757. exit;
  758. end;
  759. If f.BufPos>=f.BufEnd Then
  760. FileFunc(f.InOutFunc)(f);
  761. hs:='';
  762. if IgnoreSpaces(f) and ReadSign(f,hs) and ReadNumeric(f,hs,10) then
  763. begin
  764. { First check for a . }
  765. if (f.Bufptr^[f.BufPos]='.') and (f.BufPos<f.BufEnd) Then
  766. begin
  767. hs:=hs+'.';
  768. Inc(f.BufPos);
  769. If f.BufPos>=f.BufEnd Then
  770. FileFunc(f.InOutFunc)(f);
  771. ReadNumeric(f,hs,10);
  772. end;
  773. { Also when a point is found check for a E }
  774. if (f.Bufptr^[f.BufPos] in ['e','E']) and (f.BufPos<f.BufEnd) Then
  775. begin
  776. hs:=hs+'E';
  777. Inc(f.BufPos);
  778. If f.BufPos>=f.BufEnd Then
  779. FileFunc(f.InOutFunc)(f);
  780. if ReadSign(f,hs) then
  781. ReadNumeric(f,hs,10);
  782. end;
  783. end;
  784. val(hs,Read_Float,code);
  785. If code<>0 Then
  786. InOutRes:=106;
  787. end;
  788. {$ifdef INT64}
  789. procedure read_qword(len : longint;var t : textrec;q : qword);[public,alias:'FPC_READ_TEXT_QWORD'];
  790. begin
  791. { !!!!!!!!!!!!! }
  792. end;
  793. {$endif INT64}
  794. {*****************************************************************************
  795. Initializing
  796. *****************************************************************************}
  797. procedure OpenStdIO(var f:text;mode,hdl:longint);
  798. begin
  799. Assign(f,'');
  800. TextRec(f).Handle:=hdl;
  801. TextRec(f).Mode:=mode;
  802. TextRec(f).Closefunc:=@FileCloseFunc;
  803. case mode of
  804. fmInput :
  805. TextRec(f).InOutFunc:=@FileReadFunc;
  806. fmOutput :
  807. begin
  808. TextRec(f).InOutFunc:=@FileWriteFunc;
  809. TextRec(f).FlushFunc:=@FileWriteFunc;
  810. end;
  811. else
  812. HandleError(102);
  813. end;
  814. end;
  815. {
  816. $Log$
  817. Revision 1.54 1999-09-07 07:44:58 peter
  818. * fixed array of char writing which didn't write the last char
  819. Revision 1.53 1999/08/19 11:16:14 peter
  820. * settextbuf size is now longint
  821. Revision 1.52 1999/08/03 21:58:45 peter
  822. * small speed improvements
  823. Revision 1.51 1999/07/26 09:43:24 florian
  824. + write helper routine for in64 implemented
  825. Revision 1.50 1999/07/08 15:18:14 michael
  826. * Now ansistring of arbitrary length can be read
  827. Revision 1.49 1999/07/05 20:04:29 peter
  828. * removed temp defines
  829. Revision 1.48 1999/07/01 15:39:52 florian
  830. + qword/int64 type released
  831. Revision 1.47 1999/06/30 22:17:24 florian
  832. + fpuint64 to system unit interface added: if it is true, the rtl
  833. uses the fpu to do int64 operations, if possible
  834. Revision 1.46 1999/05/06 09:05:16 peter
  835. * generic write_float str_float
  836. Revision 1.45 1999/04/26 18:27:26 peter
  837. * fixed write array
  838. * read array with maxlen
  839. Revision 1.44 1999/04/08 15:57:57 peter
  840. + subrange checking for readln()
  841. Revision 1.43 1999/04/07 22:05:18 peter
  842. * fixed bug with readln where it sometime didn't read until eol
  843. Revision 1.42 1999/03/16 17:49:39 jonas
  844. * changes for internal Val code (do a "make cycle OPT=-dvalintern" to test)
  845. * in text.inc: changed RTE 106 when read integer values are out of bounds to RTE 201
  846. * in systemh.inc: disabled "support_fixed" for the i386 because it gave internal errors,
  847. Revision 1.41 1999/03/02 18:23:37 peter
  848. * changed so handlerror() -> inoutres:= to have $I- support
  849. Revision 1.40 1999/03/01 15:41:04 peter
  850. * use external names
  851. * removed all direct assembler modes
  852. Revision 1.39 1999/02/17 10:13:29 peter
  853. * when error when opening a file, then reset the mode to fmclosed
  854. Revision 1.38 1999/01/28 19:38:19 peter
  855. * fixed readln(ansistring)
  856. Revision 1.37 1998/12/15 22:43:06 peter
  857. * removed temp symbols
  858. Revision 1.36 1998/12/11 18:07:39 peter
  859. * fixed read(char) with empty buffer
  860. Revision 1.35 1998/11/27 14:50:58 peter
  861. + open strings, $P switch support
  862. Revision 1.34 1998/11/16 12:21:48 peter
  863. * fixes for 0.99.8
  864. Revision 1.33 1998/10/23 00:03:29 peter
  865. * write(pchar) has check for nil
  866. Revision 1.32 1998/10/20 14:37:45 peter
  867. * fixed maxlen which was not correct after my read_string update
  868. Revision 1.31 1998/10/10 15:28:48 peter
  869. + read single,fixed
  870. + val with code:longint
  871. + val for fixed
  872. Revision 1.30 1998/09/29 08:39:07 michael
  873. + Ansistring write now gets pointer.
  874. Revision 1.29 1998/09/28 14:27:08 michael
  875. + AnsiStrings update
  876. Revision 1.28 1998/09/24 23:32:24 peter
  877. * fixed small bug with a #13#10 on a line
  878. Revision 1.27 1998/09/18 12:23:22 peter
  879. * fixed a bug introduced by my previous update
  880. Revision 1.26 1998/09/17 16:34:18 peter
  881. * new eof,eoln,seekeoln,seekeof
  882. * speed upgrade for read_string
  883. * inoutres 104/105 updates for read_* and write_*
  884. Revision 1.25 1998/09/14 10:48:23 peter
  885. * FPC_ names
  886. * Heap manager is now system independent
  887. Revision 1.24 1998/09/08 10:14:06 peter
  888. + textrecbufsize
  889. Revision 1.23 1998/08/26 15:33:28 peter
  890. * reset bufpos,bufend in opentext like tp7
  891. Revision 1.22 1998/08/26 11:23:25 pierre
  892. * close did not reset the bufpos and bufend fields
  893. led to problems when using the same file several times
  894. Revision 1.21 1998/08/17 22:42:17 michael
  895. + Flush on close only for output files cd ../inc
  896. Revision 1.20 1998/08/11 00:05:28 peter
  897. * $ifdef ver0_99_5 updates
  898. Revision 1.19 1998/07/30 13:26:16 michael
  899. + Added support for ErrorProc variable. All internal functions are required
  900. to call HandleError instead of runerror from now on.
  901. This is necessary for exception support.
  902. Revision 1.18 1998/07/29 21:44:35 michael
  903. + Implemented reading/writing of ansistrings
  904. Revision 1.17 1998/07/19 19:55:33 michael
  905. + fixed rename. Changed p to p^
  906. Revision 1.16 1998/07/10 11:02:40 peter
  907. * support_fixed, becuase fixed is not 100% yet for the m68k
  908. Revision 1.15 1998/07/06 15:56:43 michael
  909. Added length checking for string reading
  910. Revision 1.14 1998/07/02 12:14:56 carl
  911. + Each IOCheck routine now check InOutRes before, just like TP
  912. Revision 1.13 1998/07/01 15:30:00 peter
  913. * better readln/writeln
  914. Revision 1.12 1998/07/01 14:48:10 carl
  915. * bugfix of WRITE_TEXT_BOOLEAN , was not TP compatible
  916. + added explicit typecast in OpenText
  917. Revision 1.11 1998/06/25 09:44:22 daniel
  918. + RTLLITE directive to compile minimal RTL.
  919. Revision 1.10 1998/06/04 23:46:03 peter
  920. * comp,extended are only i386 added support_comp,support_extended
  921. Revision 1.9 1998/06/02 16:47:56 pierre
  922. * bug for boolean values greater than one fixed
  923. Revision 1.8 1998/05/31 14:14:54 peter
  924. * removed warnings using comp()
  925. Revision 1.7 1998/05/27 00:19:21 peter
  926. * fixed crt input
  927. Revision 1.6 1998/05/21 19:31:01 peter
  928. * objects compiles for linux
  929. + assign(pchar), assign(char), rename(pchar), rename(char)
  930. * fixed read_text_as_array
  931. + read_text_as_pchar which was not yet in the rtl
  932. Revision 1.5 1998/05/12 10:42:45 peter
  933. * moved getopts to inc/, all supported OS's need argc,argv exported
  934. + strpas, strlen are now exported in the systemunit
  935. * removed logs
  936. * removed $ifdef ver_above
  937. Revision 1.4 1998/04/07 22:40:46 florian
  938. * final fix of comp writing
  939. }