Reputation: 13893
In the Hyperspec, it says:
If an end of file occurs before any characters are read in the line, an error is signaled if
eof-error-p
is true.
But it doesn't say what error is signaled. I inferred from How to handle end-of-file error when using read-from-string? that the type is END-OF-FILE
, but I don't see that actually written in the Hyperspec anywhere. Am I missing something? Is this implementation-dependent?
Upvotes: 2
Views: 498
Reputation: 139321
Introduction
The behavior of READ-LINE
be a bit more complicated: READ-LINE
is not a Reader function, but a Streams function in the Specification. A line can be terminated by an EOF. That's not an error for READ-LINE, then. It's only an error when there were no characters in the line, for example when one reads past the EOF, then.
Example file
We have a file without a newline:
CL-USER 2 > (with-open-file (s "/tmp/test.text")
(loop for c = (read-char s nil nil) while c collect c))
(#\h #\e #\l #\l #\o #\Space #\w #\o #\r #\l #\d)
Reading lines from the example file
Now we call the default READ-LINE
on it:
CL-USER 6 > (with-open-file (s "/tmp/test.text")
(read-line s))
"hello world"
T
Above returns two values: the string read and T
indicating that there was no Newline at the end. Thus the end of the file terminated the line. It is not an error.
CL-USER 7 > (with-open-file (s "/tmp/test.text")
(read-line s t))
"hello world"
T
Even if we say read the line with EOF-ERROR-P
= T, we don't get an error.
We get an error, when we read past the EOF:
CL-USER 8 > (with-open-file (s "/tmp/test.text")
(read-line s t) ; gets the last line in my file
(read-line s t))
Error: End of file while reading stream #<STREAM::LATIN-1-FILE-STREAM /tmp/test.text>.
1 (abort) Return to top loop level 0.
Type :b for backtrace or :c <option number> to proceed.
Type :bug-form "<subject>" for a bug report template or :? for other options.
we can look at the condition object (using LispWorks):
CL-USER 9 : 1 > :cc
#<END-OF-FILE 801009A7C3>
CL-USER 10 : 1 > (describe *)
#<END-OF-FILE 801009A7C3> is an END-OF-FILE
REPORTER-FUNCTION #<Function 1 subfunction of (SUBFUNCTION LOAD-TIME-VALUE (DEFINE-CONDITION END-OF-FILE)) 80E0615969>
STREAM #<STREAM::LATIN-1-FILE-STREAM /tmp/test.text>
CL-USER 11 : 1 >
READ-LINE in the Spec
I would think that the ANSI Common Lisp specification (-> HyperSpec) simply lacks the usual phrase where it explicitly says what error is signaled. Probably something useful to add in the next revision (if there is ever one).
In CLtL2 all input functions where in one chapter, but the condition system wasn't really integrated into the spec then. In the ANSI CL spec the reader functions are in a later chapter and streams functions are described earlier.
Summary of the READ-LINE behavior
We can assume that this is an end-of-file
error then.
Upvotes: 2
Reputation: 21365
The read-line
function does return an error of type end-of-file
when eof-error-p
is true. This is described in the Reader Concepts section of the HyperSpec, 23.1.3.1 The EOF-ERROR-P argument.
Eof-error-p in input function calls controls what happens if input is from a file (or any other input source that has a definite end) and the end of the file is reached. If eof-error-p is true (the default), an error of type end-of-file is signaled at end of file. If it is false, then no error is signaled, and instead the function returns eof-value....
It might be worth noting that, while the read-line
entry doesn't explicitly say that the error is of type end-of-file
, the HyperSpec entry for read
does:
If eof-error-p is true, an error of type end-of-file is signaled at the end of file.
Upvotes: 3