format: Signal an error for ~<~@>
authorStas Boukarev <stassats@gmail.com>
Sun, 10 Mar 2013 16:15:53 +0000 (20:15 +0400)
committerStas Boukarev <stassats@gmail.com>
Sun, 10 Mar 2013 16:15:53 +0000 (20:15 +0400)
CLHS doesn't allow @ to appear in the closing directive of ~<~>.

Patch by Jan Moringen.
Fixes lp#1153148

NEWS
src/code/late-format.lisp
src/code/target-format.lisp
src/pcl/env.lisp
tests/print.impure.lisp

diff --git a/NEWS b/NEWS
index 6937c27..a69cd9f 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,8 @@ changes relative to sbcl-1.1.5:
    (regression since 1.0.42.11-bis)
   * bug fix: clear-output calls the correct gray stream routine,
     sb-gray:stream-clear-output. (lp#1153257)
+  * bug fix: an error is signalled for an invalid format modifier: ~<~@>.
+    (lp#1153148)
 
 changes in sbcl-1.1.5 relative to sbcl-1.1.4:
   * minor incompatible change: SB-SPROF:WITH-PROFILING no longer loops
index 7777866..4f4c6b1 100644 (file)
   (multiple-value-bind (segments first-semi close remaining)
       (parse-format-justification directives)
     (values
-     (if (format-directive-colonp close)
+     (if (format-directive-colonp close) ; logical block vs. justification
          (multiple-value-bind (prefix per-line-p insides suffix)
              (parse-format-logical-block segments colonp first-semi
                                          close params string end)
                     :complaint "~D illegal directive~:P found inside justification block"
                     :args (list count)
                     :references (list '(:ansi-cl :section (22 3 5 2)))))
+           ;; ANSI does not explicitly say that an error should be
+           ;; signalled, but the @ modifier is not explicitly allowed
+           ;; for ~> either.
+           (when (format-directive-atsignp close)
+             (error 'format-error
+                    :complaint "@ modifier not allowed in close ~
+                    directive of justification ~
+                    block (i.e. ~~<...~~@>."
+                    :offset (1- (format-directive-end close))
+                    :references (list '(:ansi-cl :section (22 3 6 2)))))
            (expand-format-justification segments colonp atsignp
                                         first-semi params)))
      remaining)))
index f8ab91f..3406f9b 100644 (file)
   (multiple-value-bind (segments first-semi close remaining)
       (parse-format-justification directives)
     (setf args
-          (if (format-directive-colonp close)
+          (if (format-directive-colonp close) ; logical block vs. justification
               (multiple-value-bind (prefix per-line-p insides suffix)
                   (parse-format-logical-block segments colonp first-semi
                                               close params string end)
                          :complaint "~D illegal directive~:P found inside justification block"
                          :args (list count)
                          :references (list '(:ansi-cl :section (22 3 5 2)))))
+                ;; ANSI does not explicitly say that an error should
+                ;; be signalled, but the @ modifier is not explicitly
+                ;; allowed for ~> either.
+                (when (format-directive-atsignp close)
+                  (error 'format-error
+                         :complaint "@ modifier not allowed in close ~
+                         directive of justification ~
+                         block (i.e. ~~<...~~@>."
+                         :offset (1- (format-directive-end close))
+                         :references (list '(:ansi-cl :section (22 3 6 2)))))
                 (interpret-format-justification stream orig-args args
                                                 segments colonp atsignp
                                                 first-semi params))))
index f1cf98f..61ee08c 100644 (file)
 
 (defmethod make-load-form ((object structure-object) &optional env)
   (declare (ignore env))
-  (error "~@<don't know how to dump ~S (default ~S method called).~@>"
+  (error "~@<don't know how to dump ~S (default ~S method called).~>"
          object 'make-load-form))
 
 (defmethod make-load-form ((object standard-object) &optional env)
   (declare (ignore env))
-  (error "~@<don't know how to dump ~S (default ~S method called).~@>"
+  (error "~@<don't know how to dump ~S (default ~S method called).~>"
          object 'make-load-form))
 
 (defmethod make-load-form ((object condition) &optional env)
   (declare (ignore env))
-  (error "~@<don't know how to dump ~S (default ~S method called).~@>"
+  (error "~@<don't know how to dump ~S (default ~S method called).~>"
          object 'make-load-form))
 
 (defun make-load-form-saving-slots (object &key (slot-names nil slot-names-p) environment)
index 3464c1c..ad0953d 100644 (file)
 (assert (raises-error? (format nil "~<~<~A~:>~>" '(foo))))
 (assert (string= (format nil "~<~<~A~>~>" 'foo) "FOO"))
 
+(with-test (:name (:format :justification-atsign-check))
+  (assert (raises-error? (format nil "~<~@>")))
+  (assert (raises-error? (eval '(format nil "~<~@>")))))
+
 ;;; Check that arrays that we print while *PRINT-READABLY* is true are
 ;;; in fact generating similar objects.
 (assert (equal (array-dimensions