On Mon, Nov 18, 2002 at 08:48:23AM -0500, Raymond Toy wrote:
> >>>>> "Matthew" == Matthew Danish <mdanish@...> writes:
> Matthew> +
> Matthew> (defun echo-misc (stream operation &optional arg1 arg2)
> Matthew> (let* ((in (two-way-stream-input-stream stream))
> Matthew> (out (two-way-stream-output-stream stream)))
> Matthew> @@ -990,6 +1016,20 @@
> Matthew> in-type `(and ,in-type ,out-type))))
> Matthew> (:close
> Matthew> (set-closed-flame stream))
> Matthew> + (:peek-char
> Matthew> + ;; For the special case of peeking into an echo-stream
> Matthew> + ;; arg1 is peek-type, arg2 is (eof-error-p eof-value)
> Matthew> + ;; returns peeked-char, eof-value, or errors end-of-file
> Matthew> + (flet ((outfn (c)
> Matthew> + (if (ansi-stream-p out)
> Matthew> + (funcall (ansi-stream-out out) out c)
> Matthew> + ;; gray-stream
> Matthew> + (stream-write-char out c))))
> Matthew> + (generalized-peeking-mechanism
> Matthew> + arg1 (second arg2) char
> Matthew> + (read-char in (first arg2) (second arg2))
> Matthew> + (unread-char char in)
> Matthew> + (outfn char))))
> While trying to port this patch to CMUCL, I got confused by this
> part. It seems we are still sending output characters to the
> out-stream of an echo-stream because generalized-peeking-mechanism
> calls (outfn char). If we're not supposed to send output to
> echo-stream, why do we call (outfn char)?
(outfn char) is the SKIPPING-CHAR-FORM argument, which means that it is
evaluated whenever a character in the stream is to be skipped.
Regarding peeking on echo-streams:
``In the case that peek-type is not nil, the characters that are passed
by peek-char are treated as if by read-char, and so are echoed unless
they have been marked otherwise by unread-char.'' -- CLHS on PEEK-CHAR
OUTFN is a local function which outputs characters to the output side of
OTOH, after re-reading that quote and following the link to UNREAD-CHAR,
I am thinking that there is a corner-case here that I overlooked.
Namely, it does not preserve the behavior regarding echo'ing previously
unread characters. Slightly more hair is required... I have a patch I
will be submitting shortly to sbcl-devel for this. Please use that
as well as the older patch.
This code exhibits the new bug:
(defun echo-unread-test ()
(let* ((in-stream (make-string-input-stream "abc"))
(echo-stream (make-echo-stream in-stream out-stream)))
(unread-char (read-char echo-stream) echo-stream)
(peek-char #\a echo-stream)
; (echo-unread-test) ==> "a", or should, in any case.
; Matthew Danish <mdanish@...>
; OpenPGP public key: C24B6010 on keyring.debian.org
; Signed or encrypted mail welcome.
; "There is no dark side of the moon really; matter of fact, it's all dark."