On 18. Mai 2005, at 19:10, Raymond Toy wrote:
> I think the fix is to replace the call with
>
> (generalized-peeking-mechanism
> peek-type stream char
> (read-char stream eof-errorp stream)
> (unread-char char stream)
> nil
> (eof-or-lose stream (or eof-errorp recursive-p) eof-value))
>
> Then, read-char cannot possibly return the stream unless we are at
> really at the end, and the eof-detected-form will return the correct
> eof-value that we want.
>
I propose the following instead; there was too much dependency on the
calling sites doing the right thing in eof-detected-form for my
taste. Instead, we tell generalized-peeking-mechanism the eof-value
that read-form will return and differentiate it from the eof-value
(peek-char) should return.
This seems to DTRT for Fredrik's case, as well as for echo streams:
(let ((out (make-string-output-stream)))
(with-open-stream (s (make-echo-stream
(make-string-input-stream "123")
out))
(format s " => ~A"
(list (peek-char nil s nil #\1)
(read-char s)
(read-char s)))
(get-output-stream-string out)))
the expected result is "12 => (1 1 2)"
Cheers,
Rudi
Index: src/code/target-stream.lisp
===================================================================
RCS file: /cvsroot/sbcl/sbcl/src/code/target-stream.lisp,v
retrieving revision 1.3
diff -u -r1.3 target-stream.lisp
--- src/code/target-stream.lisp 13 Aug 2004 17:35:43 -0000 1.3
+++ src/code/target-stream.lisp 20 May 2005 09:05:07 -0000
@@ -18,21 +18,22 @@
;;;
;;; All arguments are forms which will be used for a specific purpose
;;; PEEK-TYPE - the current peek-type as defined by ANSI CL
-;;; EOF-VALUE - the eof-value argument to peek-char
+;;; EOF-RESULT - the eof-value argument to peek-char
;;; CHAR-VAR - the variable which will be used to store the current
character
;;; READ-FORM - the form which will be used to read a character
+;;; EOF-VALUE - the result returned from READ-FORM when hitting eof
;;; UNREAD-FORM - ditto for unread-char
;;; SKIPPED-CHAR-FORM - the form to execute when skipping a character
;;; EOF-DETECTED-FORM - the form to execute when EOF has been detected
-;;; (this will default to CHAR-VAR)
+;;; (this will default to EOF-RESULT)
(sb!xc:defmacro generalized-peeking-mechanism
- (peek-type eof-value char-var read-form unread-form
+ (peek-type eof-result char-var read-form eof-value unread-form
&optional (skipped-char-form nil) (eof-detected-form nil))
`(let ((,char-var ,read-form))
- (cond ((eql ,char-var ,eof-value)
+ (cond ((eql ,char-var ,eof-value)
,(if eof-detected-form
eof-detected-form
- char-var))
+ eof-result))
((characterp ,peek-type)
(do ((,char-var ,char-var ,read-form))
((or (eql ,char-var ,eof-value)
@@ -40,7 +41,7 @@
(cond ((eql ,char-var ,eof-value)
,(if eof-detected-form
eof-detected-form
- char-var))
+ eof-result))
(t ,unread-form
,char-var)))
,skipped-char-form))
@@ -51,7 +52,7 @@
(cond ((eql ,char-var ,eof-value)
,(if eof-detected-form
eof-detected-form
- char-var))
+ eof-result))
(t ,unread-form
,char-var)))
,skipped-char-form))
@@ -76,7 +77,8 @@
(t
(generalized-peeking-mechanism
peek-type eof-value char
- (ansi-stream-read-char stream eof-error-p eof-value
recursive-p)
+ (ansi-stream-read-char stream eof-error-p :eof recursive-p)
+ :eof
(ansi-stream-unread-char char stream)))))
(defun peek-char (&optional (peek-type nil)
@@ -149,10 +151,11 @@
(pop (echo-stream-unread-stuff stream)))
(t
(setf unread-char-p nil)
- (read-char in (first arg2) (second arg2))))))
+ (read-char in (first arg2) :eof)))))
(generalized-peeking-mechanism
arg1 (second arg2) char
(infn)
+ :eof
(unread-char char in)
(outfn char)))))
(t
|