diff tests/automated/lisp-tests.el @ 5118:e0db3c197671 ben-lisp-object

merge up to latest default branch, doesn't compile yet
author Ben Wing <ben@xemacs.org>
date Sat, 26 Dec 2009 21:18:49 -0600
parents 4cf435fcebbc
children 95b04754ea8c
line wrap: on
line diff
--- a/tests/automated/lisp-tests.el	Sat Dec 26 00:20:27 2009 -0600
+++ b/tests/automated/lisp-tests.el	Sat Dec 26 21:18:49 2009 -0600
@@ -889,6 +889,20 @@
       (check-function-argcounts '(lambda ,arglist nil) ,min ,max)
       (check-function-argcounts (byte-compile '(lambda ,arglist nil)) ,min ,max))))
 
+;; Test subr-arity. 
+(loop for (function-name arity) in
+  '((let (1 . unevalled))
+    (prog1 (1 . unevalled))
+    (list (0 . many))
+    (type-of (1 . 1))
+    (garbage-collect (0 . 0)))
+  do (Assert (equal (subr-arity (symbol-function function-name)) arity)))
+  
+(Check-Error wrong-type-argument (subr-arity
+                                  (lambda () (message "Hi there!"))))
+  
+(Check-Error wrong-type-argument (subr-arity nil))
+
 ;;-----------------------------------------------------
 ;; Detection of cyclic variable indirection loops
 ;;-----------------------------------------------------
@@ -1279,6 +1293,10 @@
 (Assert (= (read (format "%d"  most-negative-fixnum)) most-negative-fixnum))
 (Assert (= (read (format "%ld" most-negative-fixnum)) most-negative-fixnum))
 
+;; These used to crash. 
+(Assert (eql (read (format "%f" 1.2e+302)) 1.2e+302))
+(Assert (eql (read (format "%.1000d" 1)) 1))
+
 ;;; "%u" is undocumented, and Emacs Lisp has no unsigned type.
 ;;; What to do if "%u" is used with a negative number?
 ;;; For non-bignum XEmacsen, the most reasonable thing seems to be to print an
@@ -1295,3 +1313,786 @@
 ;; Check all-completions ignore element start with space.
 (Assert (not (all-completions "" '((" hidden" . "object")))))
 (Assert (all-completions " " '((" hidden" . "object"))))
+
+(let* ((literal-with-uninterned
+	'(first-element
+	  [#1=#:G32976 #2=#:G32974 #3=#:G32971 #4=#:G32969 alias
+		       #s(hash-table size 256 data (969 ?\xF9 55 ?7 166 ?\xA6))
+		       #5=#:G32970 #6=#:G32972]))
+       (print-readably t)
+       (print-gensym t)
+       (printed-with-uninterned (prin1-to-string literal-with-uninterned))
+       (awkward-regexp "#1=#")
+       (first-match-start (string-match awkward-regexp
+					printed-with-uninterned)))
+  (Assert (null (string-match awkward-regexp printed-with-uninterned
+			      (1+ first-match-start)))))
+
+(let ((char-table-with-string #s(char-table data (?\x00 "text")))
+      (char-table-with-symbol #s(char-table data (?\x00 text))))
+  (Assert (not (string-equal (prin1-to-string char-table-with-string)
+                             (prin1-to-string char-table-with-symbol)))
+          "Check that char table elements are quoted correctly when printing"))
+
+
+(let ((test-file-name
+       (make-temp-file (expand-file-name "sR4KDwU" (temp-directory))
+		       nil ".el")))
+  (find-file test-file-name)
+  (erase-buffer)
+  (insert 
+       "\
+;; Lisp should not be able to modify #$, which is
+;; Vload_file_name_internal of lread.c.
+(Check-Error setting-constant (aset #$ 0 ?\\ ))
+
+;; But modifying load-file-name should work:
+(let ((new-char ?\\ )
+      old-char)
+  (setq old-char (aref load-file-name 0))
+  (if (= new-char old-char)
+      (setq new-char ?/))
+  (aset load-file-name 0 new-char)
+  (Assert (= new-char (aref load-file-name 0))
+	  \"Check that we can modify the string value of load-file-name\"))
+
+(let* ((new-load-file-name \"hi there\")
+       (load-file-name new-load-file-name))
+  (Assert (eq new-load-file-name load-file-name)
+	  \"Checking that we can bind load-file-name successfully.\"))
+
+")
+   (write-region (point-min) (point-max) test-file-name nil 'quiet)
+   (set-buffer-modified-p nil)
+   (kill-buffer nil)
+   (load test-file-name nil t nil)
+   (delete-file test-file-name))
+
+(flet ((cl-floor (x &optional y)
+	 (let ((q (floor x y)))
+	   (list q (- x (if y (* y q) q)))))
+       (cl-ceiling (x &optional y)
+	 (let ((res (cl-floor x y)))
+	   (if (= (car (cdr res)) 0) res
+	     (list (1+ (car res)) (- (car (cdr res)) (or y 1))))))
+       (cl-truncate (x &optional y)
+	 (if (eq (>= x 0) (or (null y) (>= y 0)))
+	     (cl-floor x y) (cl-ceiling x y)))
+       (cl-round (x &optional y)
+	 (if y
+	     (if (and (integerp x) (integerp y))
+		 (let* ((hy (/ y 2))
+			(res (cl-floor (+ x hy) y)))
+		   (if (and (= (car (cdr res)) 0)
+			    (= (+ hy hy) y)
+			    (/= (% (car res) 2) 0))
+		       (list (1- (car res)) hy)
+		     (list (car res) (- (car (cdr res)) hy))))
+	       (let ((q (round (/ x y))))
+		 (list q (- x (* q y)))))
+	   (if (integerp x) (list x 0)
+	     (let ((q (round x)))
+	       (list q (- x q))))))
+       (Assert-rounding (first second &key
+			 one-floor-result two-floor-result 
+			 one-ffloor-result two-ffloor-result 
+			 one-ceiling-result two-ceiling-result
+			 one-fceiling-result two-fceiling-result
+			 one-round-result two-round-result
+			 one-fround-result two-fround-result
+			 one-truncate-result two-truncate-result
+			 one-ftruncate-result two-ftruncate-result)
+	 (Assert (equal one-floor-result (multiple-value-list
+					  (floor first)))
+		 (format "checking (floor %S) gives %S"
+			 first one-floor-result))
+	 (Assert (equal one-floor-result (multiple-value-list
+					  (floor first 1)))
+		 (format "checking (floor %S 1) gives %S"
+			 first one-floor-result))
+	 (Check-Error arith-error (floor first 0))
+	 (Check-Error arith-error (floor first 0.0))
+	 (Assert (equal two-floor-result (multiple-value-list
+					  (floor first second)))
+		 (format
+		  "checking (floor %S %S) gives %S"
+		  first second two-floor-result))
+	 (Assert (equal (cl-floor first second)
+			(multiple-value-list (floor first second)))
+		 (format
+		  "checking (floor %S %S) gives the same as the old code"
+		  first second))
+	 (Assert (equal one-ffloor-result (multiple-value-list
+					   (ffloor first)))
+		 (format "checking (ffloor %S) gives %S"
+			 first one-ffloor-result))
+	 (Assert (equal one-ffloor-result (multiple-value-list
+					   (ffloor first 1)))
+		 (format "checking (ffloor %S 1) gives %S"
+			 first one-ffloor-result))
+	 (Check-Error arith-error (ffloor first 0))
+	 (Check-Error arith-error (ffloor first 0.0))
+	 (Assert (equal two-ffloor-result (multiple-value-list
+					   (ffloor first second)))
+		 (format "checking (ffloor %S %S) gives %S"
+			 first second two-ffloor-result))
+	 (Assert (equal one-ceiling-result (multiple-value-list
+					    (ceiling first)))
+		 (format "checking (ceiling %S) gives %S"
+			 first one-ceiling-result))
+	 (Assert (equal one-ceiling-result (multiple-value-list
+					    (ceiling first 1)))
+		 (format "checking (ceiling %S 1) gives %S"
+			 first one-ceiling-result))
+	 (Check-Error arith-error (ceiling first 0))
+	 (Check-Error arith-error (ceiling first 0.0))
+	 (Assert (equal two-ceiling-result (multiple-value-list
+					    (ceiling first second)))
+		 (format "checking (ceiling %S %S) gives %S"
+			 first second two-ceiling-result))
+	 (Assert (equal (cl-ceiling first second)
+			(multiple-value-list (ceiling first second)))
+		 (format
+		  "checking (ceiling %S %S) gives the same as the old code"
+		  first second))
+	 (Assert (equal one-fceiling-result (multiple-value-list
+					     (fceiling first)))
+		 (format "checking (fceiling %S) gives %S"
+			 first one-fceiling-result))
+	 (Assert (equal one-fceiling-result (multiple-value-list
+					     (fceiling first 1)))
+		 (format "checking (fceiling %S 1) gives %S"
+			 first one-fceiling-result))
+	 (Check-Error arith-error (fceiling first 0))
+	 (Check-Error arith-error (fceiling first 0.0))
+	 (Assert (equal two-fceiling-result (multiple-value-list
+					  (fceiling first second)))
+		 (format "checking (fceiling %S %S) gives %S"
+			 first second two-fceiling-result))
+	 (Assert (equal one-round-result (multiple-value-list
+					  (round first)))
+		 (format "checking (round %S) gives %S"
+			 first one-round-result))
+	 (Assert (equal one-round-result (multiple-value-list
+					  (round first 1)))
+		 (format "checking (round %S 1) gives %S"
+			 first one-round-result))
+	 (Check-Error arith-error (round first 0))
+	 (Check-Error arith-error (round first 0.0))
+	 (Assert (equal two-round-result (multiple-value-list
+					  (round first second)))
+		 (format "checking (round %S %S) gives %S"
+			 first second two-round-result))
+	 (Assert (equal one-fround-result (multiple-value-list
+					   (fround first)))
+		 (format "checking (fround %S) gives %S"
+			 first one-fround-result))
+	 (Assert (equal one-fround-result (multiple-value-list
+					   (fround first 1)))
+		 (format "checking (fround %S 1) gives %S"
+			 first one-fround-result))
+	 (Check-Error arith-error (fround first 0))
+	 (Check-Error arith-error (fround first 0.0))
+	 (Assert (equal two-fround-result (multiple-value-list
+					   (fround first second)))
+		 (format "checking (fround %S %S) gives %S"
+			 first second two-fround-result))
+	 (Assert (equal (cl-round first second)
+			(multiple-value-list (round first second)))
+		 (format
+		  "checking (round %S %S) gives the same as the old code"
+		  first second))
+	 (Assert (equal one-truncate-result (multiple-value-list
+					     (truncate first)))
+		 (format "checking (truncate %S) gives %S"
+			 first one-truncate-result))
+	 (Assert (equal one-truncate-result (multiple-value-list
+					     (truncate first 1)))
+		 (format "checking (truncate %S 1) gives %S"
+			 first one-truncate-result))
+	 (Check-Error arith-error (truncate first 0))
+	 (Check-Error arith-error (truncate first 0.0))
+	 (Assert (equal two-truncate-result (multiple-value-list
+					     (truncate first second)))
+		 (format "checking (truncate %S %S) gives %S"
+			 first second two-truncate-result))
+	 (Assert (equal (cl-truncate first second)
+			(multiple-value-list (truncate first second)))
+		 (format
+		  "checking (truncate %S %S) gives the same as the old code"
+		  first second))
+	 (Assert (equal one-ftruncate-result (multiple-value-list
+					      (ftruncate first)))
+		 (format "checking (ftruncate %S) gives %S"
+			 first one-ftruncate-result))
+	 (Assert (equal one-ftruncate-result (multiple-value-list
+					      (ftruncate first 1)))
+		 (format "checking (ftruncate %S 1) gives %S"
+			 first one-ftruncate-result))
+	 (Check-Error arith-error (ftruncate first 0))
+	 (Check-Error arith-error (ftruncate first 0.0))
+	 (Assert (equal two-ftruncate-result (multiple-value-list
+					      (ftruncate first second)))
+		 (format "checking (ftruncate %S %S) gives %S"
+			 first second two-ftruncate-result)))
+       (Assert-rounding-floating (pie ee)
+	 (let ((pie-type (type-of pie)))
+	   (assert (eq pie-type (type-of ee)) t
+		   "This code assumes the two arguments have the same type.")
+	   (Assert-rounding pie ee
+  	    :one-floor-result (list 3 (- pie 3))
+            :two-floor-result (list 1 (- pie (* 1 ee)))
+            :one-ffloor-result (list (coerce 3 pie-type) (- pie 3.0))
+            :two-ffloor-result (list (coerce 1 pie-type) (- pie (* 1.0 ee)))
+            :one-ceiling-result (list 4 (- pie 4))
+            :two-ceiling-result (list 2 (- pie (* 2 ee)))
+            :one-fceiling-result (list (coerce 4 pie-type) (- pie 4.0))
+            :two-fceiling-result (list (coerce 2 pie-type) (- pie (* 2.0 ee)))
+            :one-round-result (list 3 (- pie 3))
+            :two-round-result (list 1 (- pie (* 1 ee)))
+            :one-fround-result (list (coerce 3 pie-type) (- pie 3.0))
+            :two-fround-result (list (coerce 1 pie-type) (- pie (* 1.0 ee)))
+            :one-truncate-result (list 3 (- pie 3))
+            :two-truncate-result (list 1 (- pie (* 1 ee)))
+            :one-ftruncate-result (list (coerce 3 pie-type) (- pie 3.0))
+            :two-ftruncate-result (list (coerce 1 pie-type)
+					(- pie (* 1.0 ee))))
+  	 (Assert-rounding pie (- ee)
+            :one-floor-result (list 3 (- pie 3))
+            :two-floor-result (list -2 (- pie (* -2 (- ee))))
+            :one-ffloor-result (list (coerce 3 pie-type) (- pie 3.0))
+            :two-ffloor-result (list (coerce -2 pie-type)
+				     (- pie (* -2.0 (- ee))))
+            :one-ceiling-result (list 4 (- pie 4))
+            :two-ceiling-result (list -1 (- pie (* -1 (- ee))))
+            :one-fceiling-result (list (coerce 4 pie-type) (- pie 4.0))
+            :two-fceiling-result (list (coerce -1 pie-type)
+				       (- pie (* -1.0 (- ee))))
+            :one-round-result (list 3 (- pie 3))
+            :two-round-result (list -1 (- pie (* -1 (- ee))))
+            :one-fround-result (list (coerce 3 pie-type) (- pie 3.0))
+            :two-fround-result (list (coerce -1 pie-type)
+				     (- pie (* -1.0 (- ee))))
+            :one-truncate-result (list 3 (- pie 3))
+            :two-truncate-result (list -1 (- pie (* -1 (- ee))))
+            :one-ftruncate-result (list (coerce 3 pie-type) (- pie 3.0))
+            :two-ftruncate-result (list (coerce -1 pie-type)
+					(- pie (* -1.0 (- ee)))))
+  	 (Assert-rounding (- pie) ee
+            :one-floor-result (list -4 (- (- pie) -4))
+            :two-floor-result (list -2 (- (- pie) (* -2 ee)))
+            :one-ffloor-result (list (coerce -4 pie-type) (- (- pie) -4.0))
+            :two-ffloor-result (list (coerce -2 pie-type)
+				     (- (- pie) (* -2.0 ee)))
+            :one-ceiling-result (list -3 (- (- pie) -3))
+            :two-ceiling-result (list -1 (- (- pie) (* -1 ee)))
+            :one-fceiling-result (list (coerce -3 pie-type) (- (- pie) -3.0))
+            :two-fceiling-result (list (coerce -1 pie-type)
+				       (- (- pie) (* -1.0 ee)))
+            :one-round-result (list -3 (- (- pie) -3))
+            :two-round-result (list -1 (- (- pie) (* -1 ee)))
+            :one-fround-result (list (coerce -3 pie-type) (- (- pie) -3.0))
+            :two-fround-result (list (coerce -1 pie-type)
+				     (- (- pie) (* -1.0 ee)))
+            :one-truncate-result (list -3 (- (- pie) -3))
+            :two-truncate-result (list -1 (- (- pie) (* -1 ee)))
+            :one-ftruncate-result (list (coerce -3 pie-type) (- (- pie) -3.0))
+            :two-ftruncate-result (list (coerce -1 pie-type)
+					(- (- pie) (* -1.0 ee))))
+  	 (Assert-rounding (- pie) (- ee)
+            :one-floor-result (list -4 (- (- pie) -4))
+            :two-floor-result (list 1 (- (- pie) (* 1 (- ee))))
+            :one-ffloor-result (list (coerce -4 pie-type) (- (- pie) -4.0))
+            :two-ffloor-result (list (coerce 1 pie-type)
+				     (- (- pie) (* 1.0 (- ee))))
+            :one-ceiling-result (list -3 (- (- pie) -3))
+            :two-ceiling-result (list 2 (- (- pie) (* 2 (- ee))))
+            :one-fceiling-result (list (coerce -3 pie-type) (- (- pie) -3.0))
+            :two-fceiling-result (list (coerce 2 pie-type)
+				       (- (- pie) (* 2.0 (- ee))))
+            :one-round-result (list -3 (- (- pie) -3))
+            :two-round-result (list 1 (- (- pie) (* 1 (- ee))))
+            :one-fround-result (list (coerce -3 pie-type) (- (- pie) -3.0))
+            :two-fround-result (list (coerce 1 pie-type)
+				     (- (- pie) (* 1.0 (- ee))))
+            :one-truncate-result (list -3 (- (- pie) -3))
+            :two-truncate-result (list 1 (- (- pie) (* 1 (- ee))))
+            :one-ftruncate-result (list (coerce -3 pie-type) (- (- pie) -3.0))
+            :two-ftruncate-result (list (coerce 1 pie-type)
+					(- (- pie) (* 1.0 (- ee)))))
+  	 (Assert-rounding ee pie
+            :one-floor-result (list 2 (- ee 2))
+            :two-floor-result (list 0 ee)
+            :one-ffloor-result (list (coerce 2 pie-type) (- ee 2.0))
+            :two-ffloor-result (list (coerce 0 pie-type) ee)
+            :one-ceiling-result (list 3 (- ee 3))
+            :two-ceiling-result (list 1 (- ee pie))
+            :one-fceiling-result (list (coerce 3 pie-type) (- ee 3.0))
+            :two-fceiling-result (list (coerce 1 pie-type) (- ee pie))
+            :one-round-result (list 3 (- ee 3))
+            :two-round-result (list 1 (- ee (* 1 pie)))
+            :one-fround-result (list (coerce 3 pie-type) (- ee 3.0))
+            :two-fround-result (list (coerce 1 pie-type) (- ee (* 1.0 pie)))
+            :one-truncate-result (list 2 (- ee 2))
+            :two-truncate-result (list 0 ee)
+            :one-ftruncate-result (list (coerce 2 pie-type) (- ee 2.0))
+            :two-ftruncate-result (list (coerce 0 pie-type) ee))
+  	 (Assert-rounding ee (- pie)
+            :one-floor-result (list 2 (- ee 2))
+            :two-floor-result (list -1 (- ee (* -1 (- pie))))
+            :one-ffloor-result (list (coerce 2 pie-type) (- ee 2.0))
+            :two-ffloor-result (list (coerce -1 pie-type)
+				     (- ee (* -1.0 (- pie))))
+            :one-ceiling-result (list 3 (- ee 3))
+            :two-ceiling-result (list 0 ee)
+            :one-fceiling-result (list (coerce 3 pie-type) (- ee 3.0))
+            :two-fceiling-result (list (coerce 0 pie-type) ee)
+            :one-round-result (list 3 (- ee 3))
+            :two-round-result (list -1 (- ee (* -1 (- pie))))
+            :one-fround-result (list (coerce 3 pie-type) (- ee 3.0))
+            :two-fround-result (list (coerce -1 pie-type)
+				     (- ee (* -1.0 (- pie))))
+            :one-truncate-result (list 2 (- ee 2))
+            :two-truncate-result (list 0 ee)
+            :one-ftruncate-result (list (coerce 2 pie-type) (- ee 2.0))
+            :two-ftruncate-result (list (coerce 0 pie-type) ee)))))
+    ;; First, two integers: 
+  (Assert-rounding 27 8 :one-floor-result '(27 0) :two-floor-result '(3 3)
+    :one-ffloor-result '(27.0 0) :two-ffloor-result '(3.0 3)
+    :one-ceiling-result '(27 0) :two-ceiling-result '(4 -5)
+    :one-fceiling-result '(27.0 0) :two-fceiling-result '(4.0 -5)
+    :one-round-result '(27 0) :two-round-result '(3 3)
+    :one-fround-result '(27.0 0) :two-fround-result '(3.0 3)
+    :one-truncate-result '(27 0) :two-truncate-result '(3 3)
+    :one-ftruncate-result '(27.0 0) :two-ftruncate-result '(3.0 3))
+  (Assert-rounding 27 -8 :one-floor-result '(27 0)  :two-floor-result '(-4 -5)
+    :one-ffloor-result '(27.0 0) :two-ffloor-result '(-4.0 -5) 
+    :one-ceiling-result '(27 0) :two-ceiling-result '(-3 3)
+    :one-fceiling-result '(27.0 0)  :two-fceiling-result '(-3.0 3)
+    :one-round-result '(27 0) :two-round-result '(-3 3)
+    :one-fround-result '(27.0 0) :two-fround-result '(-3.0 3)
+    :one-truncate-result '(27 0) :two-truncate-result '(-3 3)
+    :one-ftruncate-result '(27.0 0)  :two-ftruncate-result '(-3.0 3))
+  (Assert-rounding -27 8
+    :one-floor-result '(-27 0) :two-floor-result '(-4 5)
+    :one-ffloor-result '(-27.0 0) :two-ffloor-result '(-4.0 5)
+    :one-ceiling-result '(-27 0) :two-ceiling-result '(-3 -3)
+    :one-fceiling-result '(-27.0 0) :two-fceiling-result '(-3.0 -3)
+    :one-round-result '(-27 0) :two-round-result '(-3 -3)
+    :one-fround-result '(-27.0 0) :two-fround-result '(-3.0 -3)
+    :one-truncate-result '(-27 0) :two-truncate-result '(-3 -3)
+    :one-ftruncate-result '(-27.0 0) :two-ftruncate-result '(-3.0 -3))
+  (Assert-rounding -27 -8
+    :one-floor-result '(-27 0) :two-floor-result '(3 -3)
+    :one-ffloor-result '(-27.0 0) :two-ffloor-result '(3.0 -3)
+    :one-ceiling-result '(-27 0) :two-ceiling-result '(4 5)
+    :one-fceiling-result '(-27.0 0) :two-fceiling-result '(4.0 5)
+    :one-round-result '(-27 0) :two-round-result '(3 -3)
+    :one-fround-result '(-27.0 0) :two-fround-result '(3.0 -3)
+    :one-truncate-result '(-27 0) :two-truncate-result '(3 -3)
+    :one-ftruncate-result '(-27.0 0) :two-ftruncate-result '(3.0 -3))
+  (Assert-rounding 8 27
+    :one-floor-result '(8 0) :two-floor-result '(0 8)
+    :one-ffloor-result '(8.0 0) :two-ffloor-result '(0.0 8)
+    :one-ceiling-result '(8 0) :two-ceiling-result '(1 -19)
+    :one-fceiling-result '(8.0 0) :two-fceiling-result '(1.0 -19)
+    :one-round-result '(8 0) :two-round-result '(0 8)
+    :one-fround-result '(8.0 0) :two-fround-result '(0.0 8)
+    :one-truncate-result '(8 0) :two-truncate-result '(0 8)
+    :one-ftruncate-result '(8.0 0) :two-ftruncate-result '(0.0 8))
+  (Assert-rounding 8 -27
+    :one-floor-result '(8 0) :two-floor-result '(-1 -19)
+    :one-ffloor-result '(8.0 0) :two-ffloor-result '(-1.0 -19)
+    :one-ceiling-result '(8 0) :two-ceiling-result '(0 8)
+    :one-fceiling-result '(8.0 0) :two-fceiling-result '(0.0 8)
+    :one-round-result '(8 0) :two-round-result '(0 8)
+    :one-fround-result '(8.0 0) :two-fround-result '(0.0 8)
+    :one-truncate-result '(8 0) :two-truncate-result '(0 8)
+    :one-ftruncate-result '(8.0 0) :two-ftruncate-result '(0.0 8))
+  (Assert-rounding -8 27
+    :one-floor-result '(-8 0) :two-floor-result '(-1 19)
+    :one-ffloor-result '(-8.0 0) :two-ffloor-result '(-1.0 19)
+    :one-ceiling-result '(-8 0) :two-ceiling-result '(0 -8)
+    :one-fceiling-result '(-8.0 0) :two-fceiling-result '(0.0 -8)
+    :one-round-result '(-8 0) :two-round-result '(0 -8)
+    :one-fround-result '(-8.0 0) :two-fround-result '(0.0 -8)
+    :one-truncate-result '(-8 0) :two-truncate-result '(0 -8)
+    :one-ftruncate-result '(-8.0 0) :two-ftruncate-result '(0.0 -8))
+  (Assert-rounding -8 -27
+    :one-floor-result '(-8 0) :two-floor-result '(0 -8)
+    :one-ffloor-result '(-8.0 0) :two-ffloor-result '(0.0 -8)
+    :one-ceiling-result '(-8 0) :two-ceiling-result '(1 19)
+    :one-fceiling-result '(-8.0 0) :two-fceiling-result '(1.0 19)
+    :one-round-result '(-8 0) :two-round-result '(0 -8)
+    :one-fround-result '(-8.0 0) :two-fround-result '(0.0 -8)
+    :one-truncate-result '(-8 0) :two-truncate-result '(0 -8)
+    :one-ftruncate-result '(-8.0 0) :two-ftruncate-result '(0.0 -8))
+  (Assert-rounding 32 4
+    :one-floor-result '(32 0) :two-floor-result '(8 0)
+    :one-ffloor-result '(32.0 0) :two-ffloor-result '(8.0 0)
+    :one-ceiling-result '(32 0) :two-ceiling-result '(8 0)
+    :one-fceiling-result '(32.0 0) :two-fceiling-result '(8.0 0)
+    :one-round-result '(32 0) :two-round-result '(8 0)
+    :one-fround-result '(32.0 0) :two-fround-result '(8.0 0)
+    :one-truncate-result '(32 0) :two-truncate-result '(8 0)
+    :one-ftruncate-result '(32.0 0) :two-ftruncate-result '(8.0 0))
+  (Assert-rounding 32 -4
+    :one-floor-result '(32 0) :two-floor-result '(-8 0)
+    :one-ffloor-result '(32.0 0) :two-ffloor-result '(-8.0 0)
+    :one-ceiling-result '(32 0) :two-ceiling-result '(-8 0)
+    :one-fceiling-result '(32.0 0) :two-fceiling-result '(-8.0 0)
+    :one-round-result '(32 0) :two-round-result '(-8 0)
+    :one-fround-result '(32.0 0) :two-fround-result '(-8.0 0)
+    :one-truncate-result '(32 0) :two-truncate-result '(-8 0)
+    :one-ftruncate-result '(32.0 0) :two-ftruncate-result '(-8.0 0))
+  (Assert-rounding 12 9
+    :one-floor-result '(12 0) :two-floor-result '(1 3)
+    :one-ffloor-result '(12.0 0) :two-ffloor-result '(1.0 3)
+    :one-ceiling-result '(12 0) :two-ceiling-result '(2 -6)
+    :one-fceiling-result '(12.0 0) :two-fceiling-result '(2.0 -6)
+    :one-round-result '(12 0) :two-round-result '(1 3)
+    :one-fround-result '(12.0 0) :two-fround-result '(1.0 3)
+    :one-truncate-result '(12 0) :two-truncate-result '(1 3)
+    :one-ftruncate-result '(12.0 0) :two-ftruncate-result '(1.0 3))
+  (Assert-rounding 10 4
+    :one-floor-result '(10 0) :two-floor-result '(2 2)
+    :one-ffloor-result '(10.0 0) :two-ffloor-result '(2.0 2)
+    :one-ceiling-result '(10 0) :two-ceiling-result '(3 -2)
+    :one-fceiling-result '(10.0 0) :two-fceiling-result '(3.0 -2)
+    :one-round-result '(10 0) :two-round-result '(2 2)
+    :one-fround-result '(10.0 0) :two-fround-result '(2.0 2)
+    :one-truncate-result '(10 0) :two-truncate-result '(2 2)
+    :one-ftruncate-result '(10.0 0) :two-ftruncate-result '(2.0 2))
+  (Assert-rounding 14 4
+    :one-floor-result '(14 0) :two-floor-result '(3 2)
+    :one-ffloor-result '(14.0 0) :two-ffloor-result '(3.0 2)
+    :one-ceiling-result '(14 0) :two-ceiling-result '(4 -2)
+    :one-fceiling-result '(14.0 0) :two-fceiling-result '(4.0 -2)
+    :one-round-result '(14 0) :two-round-result '(4 -2)
+    :one-fround-result '(14.0 0) :two-fround-result '(4.0 -2)
+    :one-truncate-result '(14 0) :two-truncate-result '(3 2)
+    :one-ftruncate-result '(14.0 0) :two-ftruncate-result '(3.0 2))
+  ;; Now, two floats:
+  (Assert-rounding-floating pi e)
+  (when (featurep 'bigfloat)
+    (Assert-rounding-floating (coerce pi 'bigfloat) (coerce e 'bigfloat)))
+  (when (featurep 'bignum)
+    (assert (not (evenp most-positive-fixnum)) t
+      "In the unlikely event that most-positive-fixnum is even, rewrite this.")
+    (Assert-rounding (1+ most-positive-fixnum) (* 2 most-positive-fixnum)
+      :one-floor-result `(,(1+ most-positive-fixnum) 0)
+      :two-floor-result `(0 ,(1+ most-positive-fixnum))
+      :one-ffloor-result `(,(float (1+ most-positive-fixnum)) 0)
+      :two-ffloor-result `(0.0 ,(1+ most-positive-fixnum))
+      :one-ceiling-result `(,(1+ most-positive-fixnum) 0)
+      :two-ceiling-result `(1 ,(1+ (- most-positive-fixnum)))
+      :one-fceiling-result `(,(float (1+ most-positive-fixnum)) 0)
+      :two-fceiling-result `(1.0 ,(1+ (- most-positive-fixnum)))
+      :one-round-result `(,(1+ most-positive-fixnum) 0)
+      :two-round-result `(1 ,(1+ (- most-positive-fixnum)))
+      :one-fround-result `(,(float (1+ most-positive-fixnum)) 0)
+      :two-fround-result `(1.0 ,(1+ (- most-positive-fixnum)))
+      :one-truncate-result `(,(1+ most-positive-fixnum) 0)
+      :two-truncate-result `(0 ,(1+ most-positive-fixnum))
+      :one-ftruncate-result `(,(float (1+ most-positive-fixnum)) 0)
+      :two-ftruncate-result `(0.0 ,(1+ most-positive-fixnum)))
+    (Assert-rounding (1+ most-positive-fixnum) (- (* 2 most-positive-fixnum))
+      :one-floor-result `(,(1+ most-positive-fixnum) 0)
+      :two-floor-result `(-1 ,(1+ (- most-positive-fixnum)))
+      :one-ffloor-result `(,(float (1+ most-positive-fixnum)) 0)
+      :two-ffloor-result `(-1.0 ,(1+ (- most-positive-fixnum)))
+      :one-ceiling-result `(,(1+ most-positive-fixnum) 0)
+      :two-ceiling-result `(0 ,(1+ most-positive-fixnum))
+      :one-fceiling-result `(,(float (1+ most-positive-fixnum)) 0)
+      :two-fceiling-result `(0.0 ,(1+ most-positive-fixnum))
+      :one-round-result `(,(1+ most-positive-fixnum) 0)
+      :two-round-result `(-1 ,(1+ (- most-positive-fixnum)))
+      :one-fround-result `(,(float (1+ most-positive-fixnum)) 0)
+      :two-fround-result `(-1.0 ,(1+ (- most-positive-fixnum)))
+      :one-truncate-result `(,(1+ most-positive-fixnum) 0)
+      :two-truncate-result `(0 ,(1+ most-positive-fixnum))
+      :one-ftruncate-result `(,(float (1+ most-positive-fixnum)) 0)
+      :two-ftruncate-result `(0.0 ,(1+ most-positive-fixnum)))
+    (Assert-rounding (- (1+ most-positive-fixnum)) (* 2 most-positive-fixnum)
+      :one-floor-result `(,(- (1+ most-positive-fixnum)) 0)
+      :two-floor-result `(-1 ,(1- most-positive-fixnum))
+      :one-ffloor-result `(,(float (- (1+ most-positive-fixnum))) 0)
+      :two-ffloor-result `(-1.0 ,(1- most-positive-fixnum))
+      :one-ceiling-result `(,(- (1+ most-positive-fixnum)) 0)
+      :two-ceiling-result `(0 ,(- (1+ most-positive-fixnum)))
+      :one-fceiling-result `(,(float (- (1+ most-positive-fixnum))) 0)
+      :two-fceiling-result `(0.0 ,(- (1+ most-positive-fixnum)))
+      :one-round-result `(,(- (1+ most-positive-fixnum)) 0)
+      :two-round-result `(-1 ,(1- most-positive-fixnum))
+      :one-fround-result `(,(float (- (1+ most-positive-fixnum))) 0)
+      :two-fround-result `(-1.0 ,(1- most-positive-fixnum))
+      :one-truncate-result `(,(- (1+ most-positive-fixnum)) 0)
+      :two-truncate-result `(0 ,(- (1+ most-positive-fixnum)))
+      :one-ftruncate-result `(,(float (- (1+ most-positive-fixnum))) 0)
+      :two-ftruncate-result `(0.0 ,(- (1+ most-positive-fixnum))))
+    ;; Test the handling of values with .5: 
+    (Assert-rounding (1+ (* 2 most-positive-fixnum)) 2
+      :one-floor-result `(,(1+ (* 2 most-positive-fixnum)) 0)
+      :two-floor-result `(,most-positive-fixnum 1)
+      :one-ffloor-result `(,(float (1+ (* 2 most-positive-fixnum))) 0)
+      ;; We can't just call #'float here; we must use code that converts a
+      ;; bignum with value most-positive-fixnum (the creation of which is
+      ;; not directly possible in Lisp) to a float, not code that converts
+      ;; the fixnum with value most-positive-fixnum to a float. The eval is
+      ;; to avoid compile-time optimisation that can break this.
+      :two-ffloor-result `(,(eval '(- (1+ most-positive-fixnum) 1 0.0)) 1)
+      :one-ceiling-result `(,(1+ (* 2 most-positive-fixnum)) 0)
+      :two-ceiling-result `(,(1+ most-positive-fixnum) -1)
+      :one-fceiling-result `(,(float (1+ (* 2 most-positive-fixnum))) 0)
+      :two-fceiling-result `(,(float (1+ most-positive-fixnum)) -1)
+      :one-round-result `(,(1+ (* 2 most-positive-fixnum)) 0)
+      :two-round-result `(,(1+ most-positive-fixnum) -1)
+      :one-fround-result `(,(float (1+ (* 2 most-positive-fixnum))) 0)
+      :two-fround-result `(,(float (1+ most-positive-fixnum)) -1)
+      :one-truncate-result `(,(1+ (* 2 most-positive-fixnum)) 0)
+      :two-truncate-result `(,most-positive-fixnum 1)
+      :one-ftruncate-result `(,(float (1+ (* 2 most-positive-fixnum))) 0)
+      ;; See the comment above on :two-ffloor-result:
+      :two-ftruncate-result `(,(eval '(- (1+ most-positive-fixnum) 1 0.0)) 1))
+    (Assert-rounding (1+ (* 2 (1- most-positive-fixnum))) 2
+      :one-floor-result `(,(1+ (* 2 (1- most-positive-fixnum))) 0)
+      :two-floor-result `(,(1- most-positive-fixnum) 1)
+      :one-ffloor-result `(,(float (1+ (* 2 (1- most-positive-fixnum)))) 0)
+      ;; See commentary above on float conversions.
+      :two-ffloor-result `(,(eval '(- (1+ most-positive-fixnum) 2 0.0)) 1)
+      :one-ceiling-result `(,(1+ (* 2 (1- most-positive-fixnum))) 0)
+      :two-ceiling-result `(,most-positive-fixnum -1)
+      :one-fceiling-result `(,(float (1+ (* 2 (1- most-positive-fixnum)))) 0)
+      :two-fceiling-result `(,(eval '(- (1+ most-positive-fixnum) 1 0.0)) -1)
+      :one-round-result `(,(1+ (* 2 (1- most-positive-fixnum))) 0)
+      :two-round-result `(,(1- most-positive-fixnum) 1)
+      :one-fround-result `(,(float (1+ (* 2 (1- most-positive-fixnum)))) 0)
+      :two-fround-result `(,(eval '(- (1+ most-positive-fixnum) 2 0.0)) 1)
+      :one-truncate-result `(,(1+ (* 2 (1- most-positive-fixnum))) 0)
+      :two-truncate-result `(,(1- most-positive-fixnum) 1)
+      :one-ftruncate-result `(,(float (1+ (* 2 (1- most-positive-fixnum)))) 0)
+      ;; See commentary above
+      :two-ftruncate-result `(,(eval '(- (1+ most-positive-fixnum) 2 0.0))
+			      1)))
+  (when (featurep 'ratio)
+    (Assert-rounding (read "4/3") (read "8/7")
+     :one-floor-result '(1 1/3) :two-floor-result '(1 4/21)
+     :one-ffloor-result '(1.0 1/3) :two-ffloor-result '(1.0 4/21)
+     :one-ceiling-result '(2 -2/3) :two-ceiling-result '(2 -20/21)
+     :one-fceiling-result '(2.0 -2/3) :two-fceiling-result '(2.0 -20/21)
+     :one-round-result '(1 1/3) :two-round-result '(1 4/21)
+     :one-fround-result '(1.0 1/3) :two-fround-result '(1.0 4/21)
+     :one-truncate-result '(1 1/3) :two-truncate-result '(1 4/21)
+     :one-ftruncate-result '(1.0 1/3) :two-ftruncate-result '(1.0 4/21))
+    (Assert-rounding (read "-4/3") (read "8/7")
+     :one-floor-result '(-2 2/3) :two-floor-result '(-2 20/21)
+     :one-ffloor-result '(-2.0 2/3) :two-ffloor-result '(-2.0 20/21)
+     :one-ceiling-result '(-1 -1/3) :two-ceiling-result '(-1 -4/21)
+     :one-fceiling-result '(-1.0 -1/3) :two-fceiling-result '(-1.0 -4/21)
+     :one-round-result '(-1 -1/3) :two-round-result '(-1 -4/21)
+     :one-fround-result '(-1.0 -1/3) :two-fround-result '(-1.0 -4/21)
+     :one-truncate-result '(-1 -1/3) :two-truncate-result '(-1 -4/21)
+     :one-ftruncate-result '(-1.0 -1/3) :two-ftruncate-result '(-1.0 -4/21))))
+
+;; Run this function in a Common Lisp with two arguments to get results that
+;; we should compare against, above. Though note the dancing-around with the
+;; bigfloats and bignums above, too; you can't necessarily just use the
+;; output here.
+
+(defun generate-rounding-output (first second)
+  (let ((print-readably t))
+    (princ first)
+    (princ " ")
+    (princ second)
+    (princ " :one-floor-result ")
+    (princ (list 'quote (multiple-value-list (floor first))))
+    (princ " :two-floor-result ")
+    (princ (list 'quote (multiple-value-list (floor first second))))
+    (princ " :one-ffloor-result ")
+    (princ (list 'quote (multiple-value-list (ffloor first))))
+    (princ " :two-ffloor-result ")
+    (princ (list 'quote (multiple-value-list (ffloor first second))))
+    (princ " :one-ceiling-result ")
+    (princ (list 'quote (multiple-value-list (ceiling first))))
+    (princ " :two-ceiling-result ")
+    (princ (list 'quote (multiple-value-list (ceiling first second))))
+    (princ " :one-fceiling-result ")
+    (princ (list 'quote (multiple-value-list (fceiling first))))
+    (princ " :two-fceiling-result ")
+    (princ (list 'quote (multiple-value-list (fceiling first second))))
+    (princ " :one-round-result ")
+    (princ (list 'quote (multiple-value-list (round first))))
+    (princ " :two-round-result ")
+    (princ (list 'quote (multiple-value-list (round first second))))
+    (princ " :one-fround-result ")
+    (princ (list 'quote (multiple-value-list (fround first))))
+    (princ " :two-fround-result ")
+    (princ (list 'quote (multiple-value-list (fround first second))))
+    (princ " :one-truncate-result ")
+    (princ (list 'quote (multiple-value-list (truncate first))))
+    (princ " :two-truncate-result ")
+    (princ (list 'quote (multiple-value-list (truncate first second))))
+    (princ " :one-ftruncate-result ")
+    (princ (list 'quote (multiple-value-list (ftruncate first))))
+    (princ " :two-ftruncate-result ")
+    (princ (list 'quote (multiple-value-list (ftruncate first second))))))
+
+;; Multiple value tests. 
+
+(flet ((foo (x y) 
+	 (floor (+ x y) y))
+       (foo-zero (x y)
+	 (values (floor (+ x y) y)))
+       (multiple-value-function-returning-t ()
+	 (values t pi e degrees-to-radians radians-to-degrees))
+       (multiple-value-function-returning-nil ()
+	 (values nil pi e radians-to-degrees degrees-to-radians))
+       (function-throwing-multiple-values ()
+	 (let* ((listing '(0 3 4 nil "string" symbol))
+		(tail listing)
+		elt)
+	   (while t
+	     (setq tail (cdr listing)
+		   elt (car listing)
+		   listing tail)
+	     (when (null elt)
+	       (throw 'VoN61Lo4Y (multiple-value-function-returning-t)))))))
+  (Assert
+   (= (+ (floor 5 3) (floor 19 4)) (+ 1 4) 5)
+   "Checking that multiple values are discarded correctly as func args")
+  (Assert
+   (= 2 (length (multiple-value-list (foo 400 (1+ most-positive-fixnum)))))
+   "Checking multiple values are passed through correctly as return values")
+  (Assert
+   (= 1 (length (multiple-value-list
+		 (foo-zero 400 (1+ most-positive-fixnum)))))
+   "Checking multiple values are discarded correctly when forced")
+  (Check-Error setting-constant (setq multiple-values-limit 20))
+  (Assert
+   (equal '(-1 1)
+	  (multiple-value-list (floor -3 4)))
+   "Checking #'multiple-value-list gives a sane result")
+  (let ((ey 40000)
+	(bee "this is a string")
+	(cee #s(hash-table size 256 data (969 ?\xF9))))
+    (Assert
+     (equal
+      (multiple-value-list (values ey bee cee))
+      (multiple-value-list (values-list (list ey bee cee))))
+     "Checking that #'values and #'values-list are correctly related")
+    (Assert
+     (equal
+      (multiple-value-list (values-list (list ey bee cee)))
+      (multiple-value-list (apply #'values (list ey bee cee))))
+     "Checking #'values-list and #'apply with #values are correctly related"))
+  (Assert
+   (= (multiple-value-call #'+ (floor 5 3) (floor 19 4)) 10)
+   "Checking #'multiple-value-call gives reasonable results.")
+  (Assert
+   (= (multiple-value-call (values '+ '*) (floor 5 3) (floor 19 4)) 10)
+   "Checking #'multiple-value-call correct when first arg multiple.")
+  (Assert
+   (= 1 (length (multiple-value-list (prog1 (floor pi) "hi there"))))
+   "Checking #'prog1 does not pass back multiple values")
+  (Assert
+   (= 2 (length (multiple-value-list
+		 (multiple-value-prog1 (floor pi) "hi there"))))
+   "Checking #'multiple-value-prog1 passes back multiple values")
+  (multiple-value-bind (floored remainder this-is-nil)
+      (floor pi 1.0)
+    (Assert (= floored 3)
+	    "Checking floored bound correctly")
+    (Assert (eql remainder (- pi 3.0))
+	    "Checking remainder bound correctly") 
+    (Assert (null this-is-nil)
+	    "Checking trailing arg bound but nil"))
+  (let ((ey 40000)
+	(bee "this is a string")
+	(cee #s(hash-table size 256 data (969 ?\xF9))))
+    (multiple-value-setq (ey bee cee)
+      (ffloor e 1.0))
+    (Assert (eql 2.0 ey) "Checking ey set correctly")
+    (Assert (eql bee (- e 2.0)) "Checking bee set correctly")
+    (Assert (null cee) "Checking cee set to nil correctly"))
+  (Assert
+   (= 3 (length (multiple-value-list (eval '(values nil t pi)))))
+   "Checking #'eval passes back multiple values")
+  (Assert
+   (= 2 (length (multiple-value-list (apply #'floor '(5 3)))))
+   "Checking #'apply passes back multiple values")
+  (Assert 
+   (= 2 (length (multiple-value-list (funcall #'floor 5 3))))
+   "Checking #'funcall passes back multiple values")
+  (Assert 
+   (equal '(1 2) (multiple-value-list 
+		  (multiple-value-call #'floor (values 5 3))))
+   "Checking #'multiple-value-call passes back multiple values correctly")
+  (Assert
+   (= 1 (length (multiple-value-list
+		 (and (multiple-value-function-returning-nil) t))))
+   "Checking multiple values from non-trailing forms discarded by #'and")
+  (Assert
+   (= 5 (length (multiple-value-list 
+		 (and t (multiple-value-function-returning-nil)))))
+   "Checking multiple values from final forms not discarded by #'and")
+  (Assert
+   (= 1 (length (multiple-value-list
+		 (or (multiple-value-function-returning-t) t))))
+   "Checking multiple values from non-trailing forms discarded by #'and")
+  (Assert
+   (= 5 (length (multiple-value-list 
+		 (or nil (multiple-value-function-returning-t)))))
+   "Checking multiple values from final forms not discarded by #'and")
+  (Assert
+   (= 1 (length (multiple-value-list
+		 (cond ((multiple-value-function-returning-t))))))
+   "Checking cond doesn't pass back multiple values in tests.")
+  (Assert
+   (equal (list nil pi e radians-to-degrees degrees-to-radians)
+	  (multiple-value-list
+	   (cond (t (multiple-value-function-returning-nil)))))
+   "Checking cond passes back multiple values in clauses.")
+  (Assert
+   (= 1 (length (multiple-value-list
+		 (prog1 (multiple-value-function-returning-nil)))))
+   "Checking prog1 discards multiple values correctly.")
+  (Assert
+   (= 5 (length (multiple-value-list
+		 (multiple-value-prog1
+		  (multiple-value-function-returning-nil)))))
+   "Checking multiple-value-prog1 passes back multiple values correctly.")
+  (Assert
+   (equal (list t pi e degrees-to-radians radians-to-degrees)
+	  (multiple-value-list
+	   (catch 'VoN61Lo4Y (function-throwing-multiple-values)))))
+  (Assert
+   (equal (list t pi e degrees-to-radians radians-to-degrees)
+	  (multiple-value-list
+	   (loop
+	     for eye in `(a b c d ,e f g ,nil ,pi)
+	     do (when (null eye)
+		  (return (multiple-value-function-returning-t))))))
+   "Checking #'loop passes back multiple values correctly.")
+  (Assert
+   (null (or))
+   "Checking #'or behaves correctly with zero arguments.")
+  (Assert
+   (eq t (and))
+   "Checking #'and behaves correctly with zero arguments.")
+  (Assert
+   (= (* 3.0 (- pi 3.0))
+      (letf (((values three one-four-one-five-nine) (floor pi)))
+        (* three one-four-one-five-nine)))
+   "checking letf handles #'values in a basic sense"))
+
+(Assert (equalp "hi there" "Hi There")
+	"checking equalp isn't case-sensitive")
+(Assert (equalp 99 99.0)
+	"checking equalp compares numerical values of different types")
+(Assert (null (equalp 99 ?c))
+	"checking equalp does not convert characters to numbers")
+;; Fixed in Hg d0ea57eb3de4.
+(Assert (null (equalp "hi there" [hi there]))
+	"checking equalp doesn't error with string and non-string")
+
+;;; end of lisp-tests.el