** condition slot accessors are methods.
** (VECTOR NIL) is a subtype of STRING.
+changes in sbcl-0.8.3 relative to sbcl-0.8.2:
+ * bug fix: WITH-OUTPUT-TO-STRING (and MAKE-STRING-OUTPUT-STREAM) now
+ accept and act upon their :ELEMENT-TYPE keyword argument.
+ (reported by Edi Weitz)
+
planned incompatible changes in 0.8.x:
* (not done yet, but planned:) When the profiling interface settles
down, it might impact TRACE. They both encapsulate functions, and
,@(when index
`((setf ,index (string-input-stream-current ,var)))))))))
-(defmacro-mundanely with-output-to-string ((var &optional string)
- &body forms-decls)
+(defmacro-mundanely with-output-to-string
+ ((var &optional string &key (element-type ''character))
+ &body forms-decls)
(multiple-value-bind (forms decls) (parse-body forms-decls nil)
(if string
`(let ((,var (make-fill-pointer-output-stream ,string)))
(unwind-protect
(progn ,@forms)
(close ,var)))
- `(let ((,var (make-string-output-stream)))
+ `(let ((,var (make-string-output-stream :element-type ,element-type)))
,@decls
(unwind-protect
(progn ,@forms)
(sout #'string-sout)
(misc #'string-out-misc)
;; The string we throw stuff in.
- (string (make-string 40)
+ (string (missing-arg)
:type (simple-array character (*))))
- (:constructor make-string-output-stream ())
+ (:constructor make-string-output-stream
+ (&key (element-type 'character)
+ &aux (string (make-string 40))))
(:copier nil))
;; Index of the next location to use.
- (index 0 :type fixnum))
+ (index 0 :type fixnum)
+ ;; Requested element type
+ (element-type 'character))
#!+sb-doc
(setf (fdocumentation 'make-string-output-stream 'function)
(defun get-output-stream-string (stream)
(declare (type string-output-stream stream))
(let* ((length (string-output-stream-index stream))
- (result (make-string length)))
- (replace result (string-output-stream-string stream))
+ (element-type (string-output-stream-element-type stream))
+ (result
+ (case element-type
+ ;; Overwhelmingly common case; can be inlined.
+ ((character) (make-string length))
+ (t (make-string length :element-type element-type)))))
+ ;; For the benefit of the REPLACE transform, let's do this, so
+ ;; that the common case isn't ludicrously expensive.
+ (etypecase result
+ ((simple-array character (*))
+ (replace result (string-output-stream-string stream)))
+ ((simple-array nil (*))
+ (replace result (string-output-stream-string stream))))
(setf (string-output-stream-index stream) 0)
result))
(defknown make-echo-stream (stream stream) stream (flushable))
(defknown make-string-input-stream (string &optional index index) stream
(flushable unsafe))
-(defknown make-string-output-stream () stream (flushable))
+(defknown make-string-output-stream
+ (&key (:element-type type-specifier))
+ stream
+ (flushable))
(defknown get-output-stream-string (stream) simple-string ())
(defknown streamp (t) boolean (movable foldable flushable))
(defknown stream-element-type (stream) type-specifier
(assert (char= (read-char stream) #\a))
(assert (file-position stream :end))
(assert (eq (read-char stream nil 'foo) 'foo)))
+
+;;; MAKE-STRING-OUTPUT-STREAM and WITH-OUTPUT-TO-STRING take an
+;;; :ELEMENT-TYPE keyword argument
+(macrolet ((frob (element-type-form)
+ `(progn
+ (let ((s (with-output-to-string
+ (s nil ,@(when element-type-form
+ `(:element-type ,element-type-form))))))
+ (assert (typep s '(simple-array ,(if element-type-form
+ (eval element-type-form)
+ 'character)
+ (0)))))
+ (get-output-stream-string
+ (make-string-output-stream
+ ,@(when element-type-form
+ `(:element-type ,element-type-form)))))))
+ (frob nil)
+ (frob 'character)
+ (frob 'base-char)
+ (frob 'nil))
;;; checkins which aren't released. (And occasionally for internal
;;; versions, especially for internal versions off the main CVS
;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"0.8.2"
+"0.8.2.1"