0.7.2.11:
[sbcl.git] / src / code / late-format.lisp
index 65ffe67..9063fa4 100644 (file)
@@ -11,7 +11,7 @@
 \f
 (define-condition format-error (error)
   ((complaint :reader format-error-complaint :initarg :complaint)
-   (arguments :reader format-error-arguments :initarg :arguments :initform nil)
+   (args :reader format-error-args :initarg :args :initform nil)
    (control-string :reader format-error-control-string
                   :initarg :control-string
                   :initform *default-format-error-control-string*)
                 ~?~@[~%  ~A~%  ~V@T^~]"
          (format-error-print-banner condition)
          (format-error-complaint condition)
-         (format-error-arguments condition)
+         (format-error-args condition)
          (format-error-control-string condition)
          (format-error-offset condition)))
 \f
 (def!struct format-directive
-  (string (required-argument) :type simple-string)
-  (start (required-argument) :type (and unsigned-byte fixnum))
-  (end (required-argument) :type (and unsigned-byte fixnum))
-  (character (required-argument) :type base-char)
+  (string (missing-arg) :type simple-string)
+  (start (missing-arg) :type (and unsigned-byte fixnum))
+  (end (missing-arg) :type (and unsigned-byte fixnum))
+  (character (missing-arg) :type base-char)
   (colonp nil :type (member t nil))
   (atsignp nil :type (member t nil))
   (params nil :type list))
                        :complaint "String ended before directive was found."
                        :control-string string
                        :offset start)
-                (schar string posn))))
+                (schar string posn)))
+          (check-ordering ()
+            (when (or colonp atsignp)
+              (error 'format-error
+                     :complaint "parameters found after #\\: or #\\@ modifier"
+                     :control-string string
+                     :offset posn))))
       (loop
        (let ((char (get-char)))
          (cond ((or (char<= #\0 char #\9) (char= char #\+) (char= char #\-))
+                (check-ordering)
                 (multiple-value-bind (param new-posn)
                     (parse-integer string :start posn :junk-allowed t)
                   (push (cons posn param) params)
@@ -87,7 +94,9 @@
                      (decf posn))
                     (t
                      (return)))))
-               ((or (char= char #\v) (char= char #\V))
+               ((or (char= char #\v)
+                    (char= char #\V))
+                (check-ordering)
                 (push (cons posn :arg) params)
                 (incf posn)
                 (case (get-char)
                   (t
                    (return))))
                ((char= char #\#)
+                (check-ordering)
                 (push (cons posn :remaining) params)
                 (incf posn)
                 (case (get-char)
                   (t
                    (return))))
                ((char= char #\')
+                (check-ordering)
                 (incf posn)
                 (push (cons posn (get-char)) params)
                 (incf posn)
                 (unless (char= (get-char) #\,)
                   (decf posn)))
                ((char= char #\,)
+                (check-ordering)
                 (push (cons posn nil) params))
                ((char= char #\:)
                 (if colonp
                     (setf atsignp t)))
                (t
                 (when (char= (schar string (1- posn)) #\,)
+                  (check-ordering)
                   (push (cons (1- posn) nil) params))
                 (return))))
        (incf posn))
                             (error
                              'format-error
                              :complaint
-                             "too many parameters, expected no more than ~D"
-                             :arguments (list ,(length specs))
+                             "too many parameters, expected no more than ~W"
+                             :args (list ,(length specs))
                              :offset (caar ,params)))
                       ,,@body)))
        `(progn
                          :complaint "no previous argument"))
                 (caar *simple-args*))
                (t
+                (/show0 "THROWing NEED-ORIG-ARGS from tilde-P")
                 (throw 'need-orig-args nil)))))
       (if atsignp
          `(write-string (if (eql ,arg 1) "y" "ies") stream)
                 "both colon and atsign modifiers used simultaneously")
          (expand-bind-defaults ((posn 0)) params
            (unless *orig-args-available*
+             (/show0 "THROWing NEED-ORIG-ARGS from tilde-@*")
              (throw 'need-orig-args nil))
            `(if (<= 0 ,posn (length orig-args))
                 (setf args (nthcdr ,posn orig-args))
                 (error 'format-error
-                       :complaint "Index ~D out of bounds. Should have been ~
-                                   between 0 and ~D."
-                       :arguments (list ,posn (length orig-args))
+                       :complaint "Index ~W out of bounds. Should have been ~
+                                   between 0 and ~W."
+                       :args (list ,posn (length orig-args))
                        :offset ,(1- end)))))
       (if colonp
          (expand-bind-defaults ((n 1)) params
            (unless *orig-args-available*
+             (/show0 "THROWing NEED-ORIG-ARGS from tilde-:*")
              (throw 'need-orig-args nil))
            `(do ((cur-posn 0 (1+ cur-posn))
                  (arg-ptr orig-args (cdr arg-ptr)))
                        (setf args (nthcdr new-posn orig-args))
                        (error 'format-error
                               :complaint
-                              "Index ~D is out of bounds; should have been ~
-                               between 0 and ~D."
-                              :arguments
-                              (list new-posn (length orig-args))
+                              "Index ~W is out of bounds; should have been ~
+                               between 0 and ~W."
+                              :args (list new-posn (length orig-args))
                               :offset ,(1- end)))))))
          (if params
              (expand-bind-defaults ((n 1)) params
   (expand-bind-defaults () params
     `(handler-bind
         ((format-error
-          #'(lambda (condition)
-              (error 'format-error
-                     :complaint
-                     "~A~%while processing indirect format string:"
-                     :arguments (list condition)
-                     :print-banner nil
-                     :control-string ,string
-                     :offset ,(1- end)))))
+          (lambda (condition)
+            (error 'format-error
+                   :complaint
+                   "~A~%while processing indirect format string:"
+                   :args (list condition)
+                   :print-banner nil
+                   :control-string ,string
+                   :offset ,(1- end)))))
        ,(if atsignp
            (if *orig-args-available*
                `(setf args (%format stream ,(expand-next-arg) orig-args args))
                 (if *orig-args-available*
                     `((handler-bind
                           ((format-error
-                            #'(lambda (condition)
-                                (error 'format-error
-                                       :complaint
-                       "~A~%while processing indirect format string:"
-                                       :arguments (list condition)
-                                       :print-banner nil
-                                       :control-string ,string
-                                       :offset ,(1- end)))))
+                            (lambda (condition)
+                              (error 'format-error
+                                     :complaint
+                             "~A~%while processing indirect format string:"
+                                     :args (list condition)
+                                     :print-banner nil
+                                     :control-string ,string
+                                     :offset ,(1- end)))))
                         (setf args
                               (%format stream inside-string orig-args args))))
                     (throw 'need-orig-args nil))
                              :complaint
                              "cannot include format directives inside the ~
                               ~:[suffix~;prefix~] segment of ~~<...~~:>"
-                             :arguments (list prefix-p)
+                             :args (list prefix-p)
                              :offset (1- (format-directive-end directive)))
                       (apply #'concatenate 'string list)))))
        (case (length segments)
                       (line-len '(or (sb!impl::line-length stream) 72)))
                      (format-directive-params first-semi)
                    `(setf extra-space ,extra line-len ,line-len))))
-          ,@(mapcar #'(lambda (segment)
-                        `(push (with-output-to-string (stream)
-                                 ,@(expand-directive-list segment))
-                               segments))
+          ,@(mapcar (lambda (segment)
+                      `(push (with-output-to-string (stream)
+                               ,@(expand-directive-list segment))
+                             segments))
                     segments))
         (format-justification stream
                               ,@(if newline-segment-p
                                  ;; subseq expansion.
                                  (subseq foo (1+ slash) (1- end)))))
           (first-colon (position #\: name))
-          (last-colon (if first-colon (position #\: name :from-end t)))
-          (package-name (if last-colon
+          (second-colon (if first-colon (position #\: name :start (1+ first-colon))))
+          (package-name (if first-colon
                             (subseq name 0 first-colon)
                             "COMMON-LISP-USER"))
           (package (find-package package-name)))
        ;; FIND-UNDELETED-PACKAGE-OR-LOSE?
        (error 'format-error
               :complaint "no package named ~S"
-              :arguments (list package-name)))
-      (intern (if first-colon
-                 (subseq name (1+ first-colon))
-                 name)
+              :args (list package-name)))
+      (intern (cond
+               ((and second-colon (= second-colon (1+ first-colon)))
+                (subseq name (1+ second-colon)))
+               (first-colon
+                (subseq name (1+ first-colon)))
+               (t name))
              package))))