X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Flate-format.lisp;h=4f4c6b12d933316af214b491f25ad5e2c8005878;hb=cee8ef591040db9a79cdd19297867672a9529051;hp=2024d07f5536a7eae03674895474b31ef2c80925;hpb=805f1dda16b90116e3eacc8dba62c34f30ed0838;p=sbcl.git diff --git a/src/code/late-format.lisp b/src/code/late-format.lisp index 2024d07..4f4c6b1 100644 --- a/src/code/late-format.lisp +++ b/src/code/late-format.lisp @@ -451,13 +451,22 @@ (t `(prin1 ,(expand-next-arg) stream)))) -(def-format-directive #\C (colonp atsignp params) +(def-format-directive #\C (colonp atsignp params string end) (expand-bind-defaults () params - (if colonp - `(format-print-named-character ,(expand-next-arg) stream) - (if atsignp - `(prin1 ,(expand-next-arg) stream) - `(write-char ,(expand-next-arg) stream))))) + (let ((n-arg (sb!xc:gensym "ARG"))) + `(let ((,n-arg ,(expand-next-arg))) + (unless (typep ,n-arg 'character) + (error 'format-error + :complaint "~s is not of type CHARACTER." + :args (list ,n-arg) + :control-string ,string + :offset ,(1- end))) + ,(cond (colonp + `(format-print-named-character ,n-arg stream)) + (atsignp + `(prin1 ,n-arg stream)) + (t + `(write-char ,n-arg stream))))))) (def-format-directive #\W (colonp atsignp params) (expand-bind-defaults () params @@ -497,13 +506,20 @@ (def-format-directive #\X (colonp atsignp params) (expand-format-integer 16 colonp atsignp params)) -(def-format-directive #\R (colonp atsignp params) +(def-format-directive #\R (colonp atsignp params string end) (expand-bind-defaults ((base nil) (mincol 0) (padchar #\space) (commachar #\,) (commainterval 3)) params (let ((n-arg (sb!xc:gensym "ARG"))) `(let ((,n-arg ,(expand-next-arg))) + (unless (or ,base + (integerp ,n-arg)) + (error 'format-error + :complaint "~s is not of type INTEGER." + :args (list ,n-arg) + :control-string ,string + :offset ,(1- end))) (if ,base (format-print-integer stream ,n-arg ,colonp ,atsignp ,base ,mincol @@ -1033,7 +1049,7 @@ (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) @@ -1047,6 +1063,16 @@ :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)))