(let ((answer (write-to-string '(bar foo :boo 1) :pretty t :escape t)))
(assert (string= answer "(?BAR? ?FOO? ?:BOO? ?1?)")))))
+;;; FORMAT string compile-time checker failure, reported by Thomas
+;;; F. Burdick
+(multiple-value-bind (f w-p f-p)
+ (compile nil '(lambda () (format nil "~{")))
+ (assert (and w-p f-p))
+ (assert (nth-value 1 (ignore-errors (funcall f)))))
+
+;;; floating point print/read consistency
+(let ((x (/ -9.349640046247849d-21 -9.381494249123696d-11)))
+ (let ((y (read-from-string (write-to-string x :readably t))))
+ (assert (eql x y))))
+
+(let ((x1 (float -5496527/100000000000000000))
+ (x2 (float -54965272/1000000000000000000)))
+ (assert (or (equal (multiple-value-list (integer-decode-float x1))
+ (multiple-value-list (integer-decode-float x2)))
+ (string/= (prin1-to-string x1) (prin1-to-string x2)))))
+
+;;; readable printing of arrays with *print-radix* t
+(let ((*print-radix* t)
+ (*print-readably* t)
+ (*print-pretty* nil))
+ (let ((output (with-output-to-string (s)
+ (write #2a((t t) (nil nil)) :stream s))))
+ (assert (equalp (read-from-string output) #2a((t t) (nil nil))))))
+
+;;; NIL parameters to "interpreted" FORMAT directives
+(assert (string= (format nil "~v%" nil) (string #\Newline)))
+
+;;; PRINC-TO-STRING should bind print-readably
+(let ((*print-readably* t))
+ (assert (string= (princ-to-string #\7)
+ (write-to-string #\7 :escape nil :readably nil))))
+
+;;; in FORMAT, ~^ inside ~:{ should go to the next case, not break
+;;; iteration, even if one argument is just a one-element list.
+(assert (string= (format nil "~:{~A~^~}" '((A) (C D))) "AC"))
+
+;;; errors should be raised if pprint and justification are mixed
+;;; injudiciously...
+(dolist (x (list "~<~:;~>~_" "~<~:;~>~I" "~<~:;~>~W"
+ "~<~:;~>~:T" "~<~:;~>~<~:>" "~_~<~:;~>"
+ "~I~<~:;~>" "~W~<~:;~>" "~:T~<~:;~>" "~<~:>~<~:;~>"))
+ (assert (raises-error? (format nil x nil)))
+ (assert (raises-error? (format nil (eval `(formatter ,x)) nil))))
+;;; ...but not in judicious cases.
+(dolist (x (list "~<~;~>~_" "~<~;~>~I" "~<~;~>~W"
+ "~<~;~>~:T" "~<~;~>~<~>" "~_~<~;~>"
+ "~I~<~;~>" "~W~<~;~>" "~:T~<~;~>" "~<~>~<~;~>"
+ "~<~:;~>~T" "~T~<~:;~>"))
+ (assert (format nil x nil))
+ (assert (format nil (eval `(formatter ,x)) nil)))
+
+;;; bug 350: bignum printing so memory-hungry that heap runs out
+;;; -- just don't stall here forever on a slow box
+(handler-case
+ (with-timeout 10
+ (print (ash 1 1000000)))
+ (timeout ()
+ (print 'timeout!)))
+
+;;; a spot of random-testing for rational printing
+(defvar *seed-state* (make-random-state))
+(print *seed-state*) ; so that we can reproduce errors
+(let ((seed (make-random-state *seed-state*)))
+ (loop repeat 42
+ do (let ((n (random (ash 1 1000) seed))
+ (d (random (ash 1 1000) seed)))
+ (when (zerop (random 2 seed))
+ (setf n (- n)))
+ (let ((r (/ n d)))
+ (loop for base from 2 to 36
+ do (let ((*print-base* base)
+ (*read-base* base)
+ (*print-radix* nil))
+ (assert (= r (read-from-string (prin1-to-string r))))
+ (if (= 36 base)
+ (decf *read-base*)
+ (incf *read-base*))
+ (assert (not (eql r (read-from-string (prin1-to-string r)))))
+ (let ((*print-radix* t))
+ (assert (= r (read-from-string
+ (princ-to-string r)))))))))
+ (write-char #\.)
+ (finish-output)))
+
+;;;; Bugs, found by PFD
+;;; NIL parameter for ~^ means `not supplied'
+(loop for (format arg result) in
+ '(("~:{~D~v^~D~}" ((3 1 4) (1 0 2) (7 nil) (5 nil 6)) "341756")
+ ("~:{~1,2,v^~A~}" ((nil 0) (3 1) (0 2)) "02"))
+ do (assert (string= (funcall #'format nil format arg) result))
+ do (assert (string= (with-output-to-string (s)
+ (funcall (eval `(formatter ,format)) s arg))
+ result)))
+
+;;; NIL first parameter for ~R is equivalent to no parameter.
+(assert (string= (format nil "~VR" nil 5) "five"))
+(assert (string= (format nil (formatter "~VR") nil 6) "six"))
+
+;;; CSR inserted a bug into Burger & Dybvig's float printer. Caught
+;;; by Raymond Toy
+(assert (string= (format nil "~F" 1d23) "1.0d+23"))
+
;;; success
(quit :unix-status 104)