diff --git a/src/lsp/iolib.lsp b/src/lsp/iolib.lsp index 696f488b25d559e4a1281095c34247dbd78671f1..421188e608b7bf9651cd783b079386c8f7b40e58 100644 --- a/src/lsp/iolib.lsp +++ b/src/lsp/iolib.lsp @@ -51,15 +51,23 @@ Possible keywords are :INDEX, :START, and :END." Evaluates FORMs with VAR bound to a string output stream to the string that is the value of STRING-FORM. If STRING-FORM is not given, a new string is used. The stream is automatically closed on exit and the string is returned." - (if string - `(LET* ((,var (MAKE-STRING-OUTPUT-STREAM-FROM-STRING ,string)) - (,(gensym) ,element-type)) - ;; We must evaluate element-type if it has been supplied by the user. - ;; Even if we ignore the value afterwards. - ,@body) - `(LET ((,var (MAKE-STRING-OUTPUT-STREAM ,@r))) - ,@body - (GET-OUTPUT-STREAM-STRING ,var)))) + (multiple-value-bind (decls body) + (find-declarations body) + (if string + `(let ((,var (make-string-output-stream-from-string ,string))) + ,@decls + ;; We must evaluate element-type if it has been supplied by the user. + ;; Even if we ignore the value afterwards. + ,element-type + (unwind-protect (progn ,@body) + (close ,var))) + `(let ((,var (make-string-output-stream ,@r))) + ,@decls + ,element-type + (unwind-protect (progn + ,@body + (get-output-stream-string ,var)) + (close ,var)))))) (defun read-from-string (string &optional (eof-error-p t) eof-value diff --git a/src/tests/normal-tests/mixed.lsp b/src/tests/normal-tests/mixed.lsp index 4552011857acd346a71ee4f77ad18ca4a0a3bdc0..b1e9cd262285cc0327a9b740c1a46882245ac064 100644 --- a/src/tests/normal-tests/mixed.lsp +++ b/src/tests/normal-tests/mixed.lsp @@ -374,16 +374,20 @@ (signals ext:stack-overflow (labels ((f (x) (f (1+ x)))) (f 1)))) -;;; Date 2020-04-18 +;;; Date 2020-04-22 ;;; URL: https://gitlab.com/embeddable-common-lisp/ecl/-/merge_requests/197 +;;; URL: https://gitlab.com/embeddable-common-lisp/ecl/-/issues/576 ;;; Description: ;;; -;;; Ensure that with-input-from-string closes the input stream -;;; that it creates. -(test mix.0019.close-with-input-from-string-stream +;;; Ensure that with-input-from-string and with-output-to-string +;;; close the streams that they provide. +(test mix.0019.with-string-io-close-streams (let (stream-var) (with-input-from-string (inner-stream-var "test") (setf stream-var inner-stream-var) (is (open-stream-p stream-var))) - (is (streamp stream-var)) + (is (not (open-stream-p stream-var))) + (with-output-to-string (inner-stream-var) + (setf stream-var inner-stream-var) + (is (open-stream-p stream-var))) (is (not (open-stream-p stream-var)))))