Merge branch 'read-line' into 'develop'

Fix stream-read-line return

See merge request embeddable-common-lisp/ecl!312
This commit is contained in:
Daniel Kochmański 2023-12-28 10:52:08 +00:00 committed by Marius Gerbershagen
commit 482d46ac92
3 changed files with 54 additions and 5 deletions

View file

@ -1579,7 +1579,8 @@ do_read_delimited_list(int d, cl_object in, bool proper_list)
if (!ECL_ANSI_STREAM_P(strm)) {
value0 = _ecl_funcall2(@'gray::stream-read-line', strm);
value1 = ecl_nth_value(the_env, 1);
if (Null(value0) && !Null(value1)) {
if ((Null(value0) || (ECL_STRINGP(value0) && (ecl_length(value0) == 0))) &&
!Null(value1)) {
if (!Null(eof_errorp))
FEend_of_file(strm);
value0 = eof_value;

View file

@ -532,9 +532,7 @@
(loop
(let ((ch (stream-read-char stream)))
(cond ((eq ch :eof)
(return (values (if (zerop index)
nil
(si::shrink-vector res index))
(return (values (si::shrink-vector res index)
t)))
(t
(when (char= ch #\newline)

View file

@ -507,7 +507,57 @@
;;; (LOOP (fu) nil (bar)) which is not acceptable. To verify
;;; that this is not happening we make sure we are not getting
;;; (BLOCK NIL NIL) since this is easier to test for.
(test mixed.0027.format-no-nil-form
(test mix.0027.format-no-nil-form
(is (equal (third (second (macroexpand-1 '(formatter "~
"))))
'(block nil))))
;;; Created: 2023-12-04 Gray stream proposal is a bit ambiguous about
;;; the return value of STREAM-READ-LINE. The return from this
;;; generic function is described as "A string is returned as the
;;; first value. The second value is true if the string was terminated
;;; by end-of-file instead of the end of a line." A literal reading of
;;; this indicates that an EOF with no newline should be returned as
;;; (VALUES "" T) which is what the default method in the proposal
;;; does. The following tests ensure that the default Gray method's
;;; returns are understood by CL:READ-LINE.
(require :gray-streams)
(defclass character-input-stream
(gray:fundamental-character-input-stream)
((value :reader value
:initarg :value)
(index :accessor index
:initform 0)))
(defmethod gray:stream-read-char ((stream character-input-stream))
(with-accessors ((value value)
(index index))
stream
(if (< index (length value))
(prog1 (char value index)
(incf index))
:eof)))
(defmethod gray:stream-unread-char ((stream character-input-stream) character)
(with-accessors ((value value)
(index index))
stream
(when (zerop index)
(error "Stream is at beginning, cannot unread character"))
(when (char/= character (char value (decf index)))
(error "Cannot unread a character that does not match."))
nil))
(test mix.0028.read-line-eof
(signals end-of-file
(read-line (make-instance 'character-input-stream :value ""))))
(test mix.0029.read-line-eof
(is (equal (multiple-value-list (read-line (make-instance 'character-input-stream :value "") nil :wibble))
'(:wibble t))))
(test mix.0029.read-line-eof
(is (equal (multiple-value-list (read-line (make-instance 'character-input-stream :value "a
")))
'("a" nil))))