CBFalconer wrote:
Emil Jerabek wrote:
the RTS sometimes fails to report EOLn before EOF, when a new-line character is missing in the file. For example, this simple program
program BufferedInput (Output, F);
var F: Text; Buffer: String (100);
begin Reset (F); while not EOF (F) do begin while not EOLn (F) do begin Read (F, Buffer); WriteLn ('read: `', Buffer, '''') end; WriteLn ('(end of line)'); ReadLn (F) end; WriteLn ('(end of file)') end.
produces
Input file `F': test read: `first line' (end of line) read: `second line, with no terminator' ./a.out: attempt to read past end of file `test' (error #454 at 8049c73)
on this input (where line 2 doesn't end with <LF>):
first line second line, with no terminator
And it is absolutely correct, IMO. Let's rewrite a portion doing the standard expansions:
while not EOF (F) do begin while not EOLn (F) do begin Read (F, Buffer); WriteLn ('read: `', Buffer, '''') end;
Write('(end of line)'); writeln; WHILE NOT eoln(F) DO get(f); get(f); (* <<<<< THIS triggers the error, as it should *)
No, it doesn't. Maybe its not aparent from the original program output, but the run-time error is triggered already by the call to EOLn. (Try a debugger, if you don't believe this.)
Anyway, the last `get' in your modification should _not_ generate any error, it should bypass the end-of-line character (reported as ' ' in F^), and only after that `get' EOF (F) becomes true, F^ undefined, and get (F) invalid.
Also note that both programs work if you declare `Buffer: Char;' instead of a string.
end;
The cure is to write "IF NOT eof(f) THEN readln(f);" The "(end of line)" is probably lying about in some internal buffers and failed to get completely flushed, which is an entirely different run-time failing.
GPC's run-time system doesn't buffer any output, AFAIK.
Emil Jerabek
-- Chuck F (cbfalconer@yahoo.com) (cbfalconer@worldnet.att.net) Available for consulting/temporary embedded and systems. http://cbfalconer.home.att.net USE worldnet address!