[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Multi-return value functions and with-input-stream-do
Oliver Andrich writes:
> Hello everybody!
>
> ...
> and I also managed to send all information for displaying the main
> window. But then my problems started, I wanted to read something from
> the in-stream and parse it, but I got really messed up with all these
> input functions provided by LISP. Then I discovered this nice macro
> with-open-stream and thought that this macro would solve my problems.
> But I doesn't solve anything, cause make-pipe-io-stream returns a
> multi-returnvalue. How do I use with-open-stream with make-pipe-io-stream?
>
> Or how do I solve the following task? I want to constantly read from a
> pipe similar to read-char-no-hang, but I want to read a whole line and
> reading stops when an EOF is received, then all pipes produced by
> make-pipe-io-stream should be closed.
I used the following code in the Plopp! planning system to solve the problem
you described:
(defvar *WISH-PROG* "wish")
(defvar *WISH-ARGS* (list "-name" "Plopp"))
(defvar *WISH-EXIT-MSG* "after 500 exit")
(defvar *WISH* NIL "The two-way-stream to the wish process")
;;; --------------------------------------------------------------------------
;;; WITH-WISH (macro)
;;; --------------------------------------------------------------------------
(defmacro WITH-WISH (&body body)
`(let ((*wish* (run-program *wish-prog*
:arguments *wish-args*
:input :stream
:output :stream)))
(unwind-protect
(progn (read-until *wish*)
,@body)
(when *wish*
(format *wish* "~A~%" *wish-exit-msg*)
(force-output *wish*)
(setq *wish* NIL)))))
;;; --------------------------------------------------------------------------
;;; READ-UNTIL (function)
;;; --------------------------------------------------------------------------
(defun READ-UNTIL (stream &optional (prompt ""))
(flet ((read-to-end ()
(do ((s nil (cons (read-char-no-hang stream NIL NIL) s)))
((and (consp s) (null (car s)))
(coerce (nreverse (cdr s)) 'string)))))
(do* ((lp (length prompt))
(str (read-to-end) (concatenate 'string str (read-to-end)))
(ls (length str) (length str)))
((or (zerop lp)
(and (>= ls lp) (string= prompt (subseq str (- ls lp)))))
(subseq str 0 (- ls lp))))))
Within the body of WITH-WISH you can communicate with the tcl/tk process
writing to *wish* and reading from it. READ-UNTIL reads from a stream
as much as possible or until a prompt is found. (the implementation is weird
and could be much simpler, as wishes do not send prompts to pipes - anyway it
works ... at least for me ;) )
Remember to call "(force-output *wish*)" on the CLisp side and "flush stdout"
on the wish side after each output operation.
>
> I hope, that some could help me.
>
Hope it helped.
--Matthias
------------------------------------------------------------------------------
Matthias Lindner
FG Intellektik, FB Informatik
Technische Hochschule Darmstadt
Alexanderstr.10, D-64283 Darmstadt
TEL: +49 6151 166651
FAX: +49 6151 165326
NET: matthias@intellektik.informatik.th-darmstadt.de
WWW: http://aida.intellektik.informatik.th-darmstadt.de/~matthias/
------------------------------------------------------------------------------