text.inc 22 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Run time library.
  4. Copyright (c) 1999-2000 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. case TextRec(t).mode of
  93. fmInput,fmOutPut,fmAppend:
  94. Begin
  95. { Write pending buffer }
  96. If Textrec(t).Mode=fmoutput then
  97. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  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. TextRec(t).mode := fmClosed;
  104. { Reset buffer for safety }
  105. TextRec(t).BufPos:=0;
  106. TextRec(t).BufEnd:=0;
  107. End
  108. else inOutRes := 103;
  109. End;
  110. End;
  111. Procedure OpenText(var t : Text;mode,defHdl:Longint);
  112. Begin
  113. Case TextRec(t).mode Of {This gives the fastest code}
  114. fmInput,fmOutput,fmInOut : Close(t);
  115. fmClosed : ;
  116. else
  117. Begin
  118. InOutRes:=102;
  119. exit;
  120. End;
  121. End;
  122. TextRec(t).mode:=mode;
  123. TextRec(t).bufpos:=0;
  124. TextRec(t).bufend:=0;
  125. FileFunc(TextRec(t).OpenFunc)(TextRec(t));
  126. { reset the mode to closed when an error has occured }
  127. if InOutRes<>0 then
  128. TextRec(t).mode:=fmClosed;
  129. End;
  130. Procedure Rewrite(var t : Text);[IOCheck];
  131. Begin
  132. If InOutRes<>0 then
  133. exit;
  134. OpenText(t,fmOutput,1);
  135. End;
  136. Procedure Reset(var t : Text);[IOCheck];
  137. Begin
  138. If InOutRes<>0 then
  139. exit;
  140. OpenText(t,fmInput,0);
  141. End;
  142. Procedure Append(var t : Text);[IOCheck];
  143. Begin
  144. If InOutRes<>0 then
  145. exit;
  146. OpenText(t,fmAppend,1);
  147. End;
  148. Procedure Flush(var t : Text);[IOCheck];
  149. Begin
  150. If InOutRes<>0 then
  151. exit;
  152. if TextRec(t).mode<>fmOutput then
  153. begin
  154. if TextRec(t).mode=fmInput then
  155. InOutRes:=105
  156. else
  157. InOutRes:=103;
  158. exit;
  159. end;
  160. { Not the flushfunc but the inoutfunc should be used, becuase that
  161. writes the data, flushfunc doesn't need to be assigned }
  162. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  163. End;
  164. Procedure Erase(var t:Text);[IOCheck];
  165. Begin
  166. If InOutRes <> 0 then
  167. exit;
  168. If TextRec(t).mode=fmClosed Then
  169. Do_Erase(PChar(@TextRec(t).Name));
  170. End;
  171. Procedure Rename(var t : text;p:pchar);[IOCheck];
  172. Begin
  173. If InOutRes <> 0 then
  174. exit;
  175. If TextRec(t).mode=fmClosed Then
  176. Begin
  177. Do_Rename(PChar(@TextRec(t).Name),p);
  178. Move(p^,TextRec(t).Name,StrLen(p)+1);
  179. End;
  180. End;
  181. Procedure Rename(var t : Text;const s : string);[IOCheck];
  182. var
  183. p : array[0..255] Of Char;
  184. Begin
  185. If InOutRes <> 0 then
  186. exit;
  187. Move(s[1],p,Length(s));
  188. p[Length(s)]:=#0;
  189. Rename(t,Pchar(@p));
  190. End;
  191. Procedure Rename(var t : Text;c : char);[IOCheck];
  192. var
  193. p : array[0..1] Of Char;
  194. Begin
  195. If InOutRes <> 0 then
  196. exit;
  197. p[0]:=c;
  198. p[1]:=#0;
  199. Rename(t,Pchar(@p));
  200. End;
  201. Function Eof(Var t: Text): Boolean;[IOCheck];
  202. Begin
  203. If (InOutRes<>0) then
  204. exit(true);
  205. if (TextRec(t).mode<>fmInput) Then
  206. begin
  207. if TextRec(t).mode=fmOutput then
  208. InOutRes:=104
  209. else
  210. InOutRes:=103;
  211. exit(true);
  212. end;
  213. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  214. begin
  215. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  216. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  217. exit(true);
  218. end;
  219. {$ifdef EOF_CTRLZ}
  220. Eof:=(TextRec(t).Bufptr^[TextRec(t).BufPos]=#26);
  221. {$else}
  222. Eof:=false;
  223. {$endif EOL_CTRLZ}
  224. end;
  225. Function Eof:Boolean;
  226. Begin
  227. Eof:=Eof(Input);
  228. End;
  229. Function SeekEof (Var t : Text) : Boolean;
  230. Begin
  231. If (InOutRes<>0) then
  232. exit(true);
  233. if (TextRec(t).mode<>fmInput) Then
  234. begin
  235. if TextRec(t).mode=fmOutPut then
  236. InOutRes:=104
  237. else
  238. InOutRes:=103;
  239. exit(true);
  240. end;
  241. repeat
  242. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  243. begin
  244. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  245. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  246. exit(true);
  247. end;
  248. case TextRec(t).Bufptr^[TextRec(t).BufPos] of
  249. #26 : exit(true);
  250. #10,#13,
  251. #9,' ' : ;
  252. else
  253. exit(false);
  254. end;
  255. inc(TextRec(t).BufPos);
  256. until false;
  257. End;
  258. Function SeekEof : Boolean;
  259. Begin
  260. SeekEof:=SeekEof(Input);
  261. End;
  262. Function Eoln(var t:Text) : Boolean;
  263. Begin
  264. If (InOutRes<>0) then
  265. exit(true);
  266. if (TextRec(t).mode<>fmInput) Then
  267. begin
  268. if TextRec(t).mode=fmOutPut then
  269. InOutRes:=104
  270. else
  271. InOutRes:=103;
  272. exit(true);
  273. end;
  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. Eoln:=(TextRec(t).Bufptr^[TextRec(t).BufPos] in [#10,#13]);
  281. End;
  282. Function Eoln : Boolean;
  283. Begin
  284. Eoln:=Eoln(Input);
  285. End;
  286. Function SeekEoln (Var t : Text) : Boolean;
  287. Begin
  288. If (InOutRes<>0) then
  289. exit(true);
  290. if (TextRec(t).mode<>fmInput) Then
  291. begin
  292. if TextRec(t).mode=fmOutput then
  293. InOutRes:=104
  294. else
  295. InOutRes:=103;
  296. exit(true);
  297. end;
  298. repeat
  299. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  300. begin
  301. FileFunc(TextRec(t).InOutFunc)(TextRec(t));
  302. If TextRec(t).BufPos>=TextRec(t).BufEnd Then
  303. exit(true);
  304. end;
  305. case TextRec(t).Bufptr^[TextRec(t).BufPos] of
  306. #26,
  307. #10,#13 : exit(true);
  308. #9,' ' : ;
  309. else
  310. exit(false);
  311. end;
  312. inc(TextRec(t).BufPos);
  313. until false;
  314. End;
  315. Function SeekEoln : Boolean;
  316. Begin
  317. SeekEoln:=SeekEoln(Input);
  318. End;
  319. Procedure SetTextBuf(Var F : Text; Var Buf);[INTERNPROC: In_settextbuf_file_x];
  320. Procedure SetTextBuf(Var F : Text; Var Buf; Size : Longint);
  321. Begin
  322. TextRec(f).BufPtr:=@Buf;
  323. TextRec(f).BufSize:=Size;
  324. TextRec(f).BufPos:=0;
  325. TextRec(f).BufEnd:=0;
  326. End;
  327. {*****************************************************************************
  328. Write(Ln)
  329. *****************************************************************************}
  330. Procedure WriteBuffer(var f:TextRec;var b;len:longint);
  331. var
  332. p : pchar;
  333. left,
  334. idx : longint;
  335. begin
  336. p:=pchar(@b);
  337. idx:=0;
  338. left:=f.BufSize-f.BufPos;
  339. while len>left do
  340. begin
  341. move(p[idx],f.Bufptr^[f.BufPos],left);
  342. dec(len,left);
  343. inc(idx,left);
  344. inc(f.BufPos,left);
  345. FileFunc(f.InOutFunc)(f);
  346. left:=f.BufSize-f.BufPos;
  347. end;
  348. move(p[idx],f.Bufptr^[f.BufPos],len);
  349. inc(f.BufPos,len);
  350. end;
  351. Procedure WriteBlanks(var f:TextRec;len:longint);
  352. var
  353. left : longint;
  354. begin
  355. left:=f.BufSize-f.BufPos;
  356. while len>left do
  357. begin
  358. FillChar(f.Bufptr^[f.BufPos],left,' ');
  359. dec(len,left);
  360. inc(f.BufPos,left);
  361. FileFunc(f.InOutFunc)(f);
  362. left:=f.BufSize-f.BufPos;
  363. end;
  364. FillChar(f.Bufptr^[f.BufPos],len,' ');
  365. inc(f.BufPos,len);
  366. end;
  367. Procedure Write_End(var f:TextRec);[Public,Alias:'FPC_WRITE_END'];
  368. begin
  369. if f.FlushFunc<>nil then
  370. FileFunc(f.FlushFunc)(f);
  371. end;
  372. Procedure Writeln_End(var f:TextRec);[Public,Alias:'FPC_WRITELN_END'];
  373. const
  374. {$IFDEF SHORT_LINEBREAK}
  375. eollen=1;
  376. eol : array[0..0] of char=(#10);
  377. {$ELSE SHORT_LINEBREAK}
  378. eollen=2;
  379. eol : array[0..1] of char=(#13,#10);
  380. {$ENDIF SHORT_LINEBREAK}
  381. begin
  382. If InOutRes <> 0 then exit;
  383. case f.mode of
  384. fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
  385. begin
  386. { Write EOL }
  387. WriteBuffer(f,eol,eollen);
  388. { Flush }
  389. if f.FlushFunc<>nil then
  390. FileFunc(f.FlushFunc)(f);
  391. end;
  392. fmInput: InOutRes:=105
  393. else InOutRes:=103;
  394. end;
  395. end;
  396. Procedure Write_Str(Len : Longint;var f : TextRec;const s : String);[Public,Alias:'FPC_WRITE_TEXT_SHORTSTR'];
  397. Begin
  398. If (InOutRes<>0) then
  399. exit;
  400. case f.mode of
  401. fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
  402. begin
  403. If Len>Length(s) Then
  404. WriteBlanks(f,Len-Length(s));
  405. WriteBuffer(f,s[1],Length(s));
  406. end;
  407. fmInput: InOutRes:=105
  408. else InOutRes:=103;
  409. end;
  410. End;
  411. Procedure Write_Array(Len : Longint;var f : TextRec;const s : array of char);[Public,Alias:'FPC_WRITE_TEXT_PCHAR_AS_ARRAY'];
  412. var
  413. ArrayLen : longint;
  414. p : pchar;
  415. Begin
  416. If (InOutRes<>0) then
  417. exit;
  418. case f.mode of
  419. fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
  420. begin
  421. p:=pchar(@s);
  422. ArrayLen:=StrLen(p);
  423. if ArrayLen>sizeof(s) then
  424. ArrayLen:=sizeof(s);
  425. If Len>ArrayLen Then
  426. WriteBlanks(f,Len-ArrayLen);
  427. WriteBuffer(f,p^,ArrayLen);
  428. end;
  429. fmInput: InOutRes:=105
  430. else InOutRes:=103;
  431. end;
  432. End;
  433. Procedure Write_PChar(Len : Longint;var f : TextRec;p : PChar);[Public,Alias:'FPC_WRITE_TEXT_PCHAR_AS_POINTER'];
  434. var
  435. PCharLen : longint;
  436. Begin
  437. If (p=nil) or (InOutRes<>0) then
  438. exit;
  439. case f.mode of
  440. fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
  441. begin
  442. PCharLen:=StrLen(p);
  443. If Len>PCharLen Then
  444. WriteBlanks(f,Len-PCharLen);
  445. WriteBuffer(f,p^,PCharLen);
  446. end;
  447. fmInput: InOutRes:=105
  448. else InOutRes:=103;
  449. end;
  450. End;
  451. Procedure Write_Text_AnsiString (Len : Longint; Var f : TextRec; S : AnsiString);[Public,alias:'FPC_WRITE_TEXT_ANSISTR'];
  452. {
  453. Writes a AnsiString to the Text file T
  454. }
  455. var
  456. SLen : longint;
  457. begin
  458. If (pointer(S)=nil) or (InOutRes<>0) then
  459. exit;
  460. case f.mode of
  461. fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
  462. begin
  463. SLen:=Length(s);
  464. If Len>SLen Then
  465. WriteBlanks(f,Len-SLen);
  466. WriteBuffer(f,PChar(S)^,SLen);
  467. end;
  468. fmInput: InOutRes:=105
  469. else InOutRes:=103;
  470. end;
  471. end;
  472. Procedure Write_SInt(Len : Longint;var t : TextRec;l : ValSInt);[Public,Alias:'FPC_WRITE_TEXT_SINT'];
  473. var
  474. s : String;
  475. Begin
  476. If (InOutRes<>0) then
  477. exit;
  478. Str(l,s);
  479. Write_Str(Len,t,s);
  480. End;
  481. Procedure Write_UInt(Len : Longint;var t : TextRec;l : ValUInt);[Public,Alias:'FPC_WRITE_TEXT_UINT'];
  482. var
  483. s : String;
  484. Begin
  485. If (InOutRes<>0) then
  486. exit;
  487. Str(L,s);
  488. Write_Str(Len,t,s);
  489. End;
  490. procedure write_qword(len : longint;var t : textrec;q : qword);[public,alias:'FPC_WRITE_TEXT_QWORD'];
  491. var
  492. s : string;
  493. begin
  494. if (InOutRes<>0) then
  495. exit;
  496. qword_str(q,s);
  497. write_str(len,t,s);
  498. end;
  499. procedure write_int64(len : longint;var t : textrec;i : int64);[public,alias:'FPC_WRITE_TEXT_INT64'];
  500. var
  501. s : string;
  502. begin
  503. if (InOutRes<>0) then
  504. exit;
  505. int64_str(i,s);
  506. write_str(len,t,s);
  507. end;
  508. Procedure Write_Float(rt,fixkomma,Len : Longint;var t : TextRec;r : ValReal);[Public,Alias:'FPC_WRITE_TEXT_FLOAT'];
  509. var
  510. s : String;
  511. Begin
  512. If (InOutRes<>0) then
  513. exit;
  514. Str_real(Len,fixkomma,r,treal_type(rt),s);
  515. Write_Str(Len,t,s);
  516. End;
  517. Procedure Write_Boolean(Len : Longint;var t : TextRec;b : Boolean);[Public,Alias:'FPC_WRITE_TEXT_BOOLEAN'];
  518. Begin
  519. If (InOutRes<>0) then
  520. exit;
  521. { Can't use array[boolean] because b can be >0 ! }
  522. if b then
  523. Write_Str(Len,t,'TRUE')
  524. else
  525. Write_Str(Len,t,'FALSE');
  526. End;
  527. Procedure Write_Char(Len : Longint;var t : TextRec;c : Char);[Public,Alias:'FPC_WRITE_TEXT_CHAR'];
  528. Begin
  529. If (InOutRes<>0) then
  530. exit;
  531. if (TextRec(t).mode<>fmOutput) Then
  532. begin
  533. if TextRec(t).mode=fmClosed then
  534. InOutRes:=103
  535. else
  536. InOutRes:=105;
  537. exit;
  538. end;
  539. If Len>1 Then
  540. WriteBlanks(t,Len-1);
  541. If t.BufPos+1>=t.BufSize Then
  542. FileFunc(t.InOutFunc)(t);
  543. t.Bufptr^[t.BufPos]:=c;
  544. Inc(t.BufPos);
  545. End;
  546. {*****************************************************************************
  547. Read(Ln)
  548. *****************************************************************************}
  549. Function NextChar(var f:TextRec;var s:string):Boolean;
  550. begin
  551. if f.BufPos<f.BufEnd then
  552. begin
  553. if length(s)<high(s) then
  554. begin
  555. inc(s[0]);
  556. s[length(s)]:=f.BufPtr^[f.BufPos];
  557. end;
  558. Inc(f.BufPos);
  559. If f.BufPos>=f.BufEnd Then
  560. FileFunc(f.InOutFunc)(f);
  561. NextChar:=true;
  562. end
  563. else
  564. NextChar:=false;
  565. end;
  566. Function IgnoreSpaces(var f:TextRec):Boolean;
  567. {
  568. Removes all leading spaces,tab,eols from the input buffer, returns true if
  569. the buffer is empty
  570. }
  571. var
  572. s : string;
  573. begin
  574. s:='';
  575. IgnoreSpaces:=false;
  576. while f.Bufptr^[f.BufPos] in [#9,#10,#13,' '] do
  577. if not NextChar(f,s) then
  578. exit;
  579. IgnoreSpaces:=true;
  580. end;
  581. procedure ReadNumeric(var f:TextRec;var s:string);
  582. {
  583. Read numeric input, if buffer is empty then return True
  584. }
  585. begin
  586. repeat
  587. if not NextChar(f,s) then
  588. exit;
  589. until (length(s)=high(s)) or (f.BufPtr^[f.BufPos] in [#9,#10,#13,' ']);
  590. end;
  591. Procedure Read_End(var f:TextRec);[Public,Alias:'FPC_READ_END'];
  592. begin
  593. if f.FlushFunc<>nil then
  594. FileFunc(f.FlushFunc)(f);
  595. end;
  596. Procedure ReadLn_End(var f : TextRec);[Public,Alias:'FPC_READLN_END'];
  597. var prev: char;
  598. Begin
  599. { Check error and if file is open and load buf if empty }
  600. If (InOutRes<>0) then
  601. exit;
  602. if (f.mode<>fmInput) Then
  603. begin
  604. case TextRec(f).mode of
  605. fmOutPut,fmAppend:
  606. InOutRes:=104
  607. else
  608. InOutRes:=103;
  609. end;
  610. exit;
  611. end;
  612. if f.BufPos>=f.BufEnd Then
  613. begin
  614. FileFunc(f.InOutFunc)(f);
  615. if (f.BufPos>=f.BufEnd) then
  616. { Flush if set }
  617. begin
  618. if (f.FlushFunc<>nil) then
  619. FileFunc(f.FlushFunc)(f);
  620. exit;
  621. end;
  622. end;
  623. repeat
  624. prev := f.BufPtr^[f.BufPos];
  625. inc(f.BufPos);
  626. { no system uses #10#13 as line seperator (#10 = *nix, #13 = Mac, }
  627. { #13#10 = Dos), so if we've got #10, we can safely exit }
  628. if prev = #10 then
  629. exit;
  630. if f.BufPos>=f.BufEnd Then
  631. begin
  632. FileFunc(f.InOutFunc)(f);
  633. if (f.BufPos>=f.BufEnd) then
  634. { Flush if set }
  635. begin
  636. if (f.FlushFunc<>nil) then
  637. FileFunc(f.FlushFunc)(f);
  638. exit;
  639. end;
  640. end;
  641. if (prev=#13) then
  642. { is there also a #10 after it? }
  643. begin
  644. if (f.BufPtr^[f.BufPos]=#10) then
  645. { yes, skip that one as well }
  646. inc(f.BufPos);
  647. exit;
  648. end;
  649. until false;
  650. End;
  651. Function ReadPCharLen(var f:TextRec;s:pchar;maxlen:longint):longint;
  652. var
  653. sPos,len : Longint;
  654. p,startp,maxp : pchar;
  655. Begin
  656. ReadPCharLen:=0;
  657. { Check error and if file is open }
  658. If (InOutRes<>0) then
  659. exit;
  660. if (f.mode<>fmInput) Then
  661. begin
  662. case TextRec(f).mode of
  663. fmOutPut,fmAppend:
  664. InOutRes:=104
  665. else
  666. InOutRes:=103;
  667. end;
  668. exit;
  669. end;
  670. { Read maximal until Maxlen is reached }
  671. sPos:=0;
  672. repeat
  673. If f.BufPos>=f.BufEnd Then
  674. begin
  675. FileFunc(f.InOutFunc)(f);
  676. If f.BufPos>=f.BufEnd Then
  677. break;
  678. end;
  679. p:[email protected]^[f.BufPos];
  680. if SPos+f.BufEnd-f.BufPos>MaxLen then
  681. maxp:[email protected]^[f.BufPos+MaxLen-SPos]
  682. else
  683. maxp:[email protected]^[f.BufEnd];
  684. startp:=p;
  685. { search linefeed }
  686. while (p<maxp) and not(P^ in [#10,#13]) do
  687. inc(p);
  688. { calculate read bytes }
  689. len:=p-startp;
  690. inc(f.BufPos,Len);
  691. Move(startp^,s[sPos],Len);
  692. inc(sPos,Len);
  693. { was it a LF or CR? then leave }
  694. if (spos=MaxLen) or
  695. ((p<maxp) and (p^ in [#10,#13])) then
  696. break;
  697. until false;
  698. ReadPCharLen:=spos;
  699. End;
  700. Procedure Read_String(var f : TextRec;var s : String);[Public,Alias:'FPC_READ_TEXT_SHORTSTR'];
  701. Begin
  702. s[0]:=chr(ReadPCharLen(f,pchar(@s[1]),high(s)));
  703. End;
  704. Procedure Read_PChar(var f : TextRec;var s : PChar);[Public,Alias:'FPC_READ_TEXT_PCHAR_AS_POINTER'];
  705. Begin
  706. pchar(s+ReadPCharLen(f,s,$7fffffff))^:=#0;
  707. End;
  708. Procedure Read_Array(var f : TextRec;var s : array of char);[Public,Alias:'FPC_READ_TEXT_PCHAR_AS_ARRAY'];
  709. Begin
  710. pchar(pchar(@s)+ReadPCharLen(f,pchar(@s),high(s)))^:=#0;
  711. End;
  712. Procedure Read_AnsiString(var f : TextRec;var s : AnsiString);[Public,Alias:'FPC_READ_TEXT_ANSISTR'];
  713. var
  714. slen,len : longint;
  715. Begin
  716. slen:=0;
  717. Repeat
  718. // SetLength will reallocate the length.
  719. SetLength(S,slen+255);
  720. len:=ReadPCharLen(f,pchar(Pointer(S)+slen),255);
  721. inc(slen,len);
  722. Until len<255;
  723. // Set actual length
  724. SetLength(S,Slen);
  725. End;
  726. Function Read_Char(var f : TextRec):char;[Public,Alias:'FPC_READ_TEXT_CHAR'];
  727. Begin
  728. Read_Char:=#0;
  729. { Check error and if file is open }
  730. If (InOutRes<>0) then
  731. exit;
  732. if (f.mode<>fmInput) Then
  733. begin
  734. case TextRec(f).mode of
  735. fmOutPut,fmAppend:
  736. InOutRes:=104
  737. else
  738. InOutRes:=103;
  739. end;
  740. exit;
  741. end;
  742. { Read next char or EOF }
  743. If f.BufPos>=f.BufEnd Then
  744. begin
  745. FileFunc(f.InOutFunc)(f);
  746. If f.BufPos>=f.BufEnd Then
  747. exit(#26);
  748. end;
  749. Read_Char:=f.Bufptr^[f.BufPos];
  750. inc(f.BufPos);
  751. end;
  752. Function Read_SInt(var f : TextRec):ValSInt;[Public,Alias:'FPC_READ_TEXT_SINT'];
  753. var
  754. hs : String;
  755. code : Longint;
  756. Begin
  757. Read_SInt:=0;
  758. { Leave if error or not open file, else check for empty buf }
  759. If (InOutRes<>0) then
  760. exit;
  761. if (f.mode<>fmInput) Then
  762. begin
  763. case TextRec(f).mode of
  764. fmOutPut,fmAppend:
  765. InOutRes:=104
  766. else
  767. InOutRes:=103;
  768. end;
  769. exit;
  770. end;
  771. If f.BufPos>=f.BufEnd Then
  772. FileFunc(f.InOutFunc)(f);
  773. hs:='';
  774. if IgnoreSpaces(f) then
  775. ReadNumeric(f,hs);
  776. Val(hs,Read_SInt,code);
  777. If code<>0 Then
  778. InOutRes:=106;
  779. End;
  780. Function Read_UInt(var f : TextRec):ValUInt;[Public,Alias:'FPC_READ_TEXT_UINT'];
  781. var
  782. hs : String;
  783. code : longint;
  784. Begin
  785. Read_UInt:=0;
  786. { Leave if error or not open file, else check for empty buf }
  787. If (InOutRes<>0) then
  788. exit;
  789. if (f.mode<>fmInput) Then
  790. begin
  791. case TextRec(f).mode of
  792. fmOutPut,fmAppend:
  793. InOutRes:=104
  794. else
  795. InOutRes:=103;
  796. end;
  797. exit;
  798. end;
  799. If f.BufPos>=f.BufEnd Then
  800. FileFunc(f.InOutFunc)(f);
  801. hs:='';
  802. if IgnoreSpaces(f) then
  803. ReadNumeric(f,hs);
  804. val(hs,Read_UInt,code);
  805. If code<>0 Then
  806. InOutRes:=106;
  807. End;
  808. Function Read_Float(var f : TextRec):ValReal;[Public,Alias:'FPC_READ_TEXT_FLOAT'];
  809. var
  810. hs : string;
  811. code : Word;
  812. begin
  813. Read_Float:=0.0;
  814. { Leave if error or not open file, else check for empty buf }
  815. If (InOutRes<>0) then
  816. exit;
  817. if (f.mode<>fmInput) Then
  818. begin
  819. case TextRec(f).mode of
  820. fmOutPut,fmAppend:
  821. InOutRes:=104
  822. else
  823. InOutRes:=103;
  824. end;
  825. exit;
  826. end;
  827. If f.BufPos>=f.BufEnd Then
  828. FileFunc(f.InOutFunc)(f);
  829. hs:='';
  830. if IgnoreSpaces(f) then
  831. ReadNumeric(f,hs);
  832. val(hs,Read_Float,code);
  833. If code<>0 Then
  834. InOutRes:=106;
  835. end;
  836. function Read_QWord(var f : textrec) : qword;[public,alias:'FPC_READ_TEXT_QWORD'];
  837. var
  838. hs : String;
  839. code : longint;
  840. Begin
  841. Read_QWord:=0;
  842. { Leave if error or not open file, else check for empty buf }
  843. If (InOutRes<>0) then
  844. exit;
  845. if (f.mode<>fmInput) Then
  846. begin
  847. case TextRec(f).mode of
  848. fmOutPut,fmAppend:
  849. InOutRes:=104
  850. else
  851. InOutRes:=103;
  852. end;
  853. exit;
  854. end;
  855. If f.BufPos>=f.BufEnd Then
  856. FileFunc(f.InOutFunc)(f);
  857. hs:='';
  858. if IgnoreSpaces(f) then
  859. ReadNumeric(f,hs);
  860. val(hs,Read_QWord,code);
  861. If code<>0 Then
  862. InOutRes:=106;
  863. End;
  864. function Read_Int64(var f : textrec) : int64;[public,alias:'FPC_READ_TEXT_INT64'];
  865. var
  866. hs : String;
  867. code : Longint;
  868. Begin
  869. Read_Int64:=0;
  870. { Leave if error or not open file, else check for empty buf }
  871. If (InOutRes<>0) then
  872. exit;
  873. if (f.mode<>fmInput) Then
  874. begin
  875. case TextRec(f).mode of
  876. fmOutPut,fmAppend:
  877. InOutRes:=104
  878. else
  879. InOutRes:=103;
  880. end;
  881. exit;
  882. end;
  883. If f.BufPos>=f.BufEnd Then
  884. FileFunc(f.InOutFunc)(f);
  885. hs:='';
  886. if IgnoreSpaces(f) then
  887. ReadNumeric(f,hs);
  888. Val(hs,Read_Int64,code);
  889. If code<>0 Then
  890. InOutRes:=106;
  891. End;
  892. {*****************************************************************************
  893. Initializing
  894. *****************************************************************************}
  895. procedure OpenStdIO(var f:text;mode,hdl:longint);
  896. begin
  897. Assign(f,'');
  898. TextRec(f).Handle:=hdl;
  899. TextRec(f).Mode:=mode;
  900. TextRec(f).Closefunc:=@FileCloseFunc;
  901. case mode of
  902. fmInput :
  903. TextRec(f).InOutFunc:=@FileReadFunc;
  904. fmOutput :
  905. begin
  906. TextRec(f).InOutFunc:=@FileWriteFunc;
  907. TextRec(f).FlushFunc:=@FileWriteFunc;
  908. end;
  909. else
  910. HandleError(102);
  911. end;
  912. end;
  913. {
  914. $Log$
  915. Revision 1.4 2000-11-23 13:14:02 jonas
  916. * fix for web bug 1210 from Peter (merged)
  917. Revision 1.3 2000/07/14 10:33:10 michael
  918. + Conditionals fixed
  919. Revision 1.2 2000/07/13 11:33:46 michael
  920. + removed logs
  921. }