X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Fcondition.lisp;h=a62586a19598c2d7bd11c306a08f77ced71ae4ff;hb=26341a4b638f5480993e9715bfb637e560592819;hp=2633215a4efbb7d0cf07b6e14a98baf913e2f987;hpb=83e5661ae59addac315e6754013b3887b477570f;p=sbcl.git diff --git a/src/code/condition.lisp b/src/code/condition.lisp index 2633215..a62586a 100644 --- a/src/code/condition.lisp +++ b/src/code/condition.lisp @@ -346,6 +346,25 @@ (res (copy-structure sslot))))))) (res))) +;;; Early definitions of slot accessor creators. +;;; +;;; Slot accessors must be generic functions, but ANSI does not seem +;;; to specify any of them, and we cannot support it before end of +;;; warm init. So we use ordinary functions inside SBCL, and switch to +;;; GFs only at the end of building. +(declaim (notinline install-condition-slot-reader + install-condition-slot-writer)) +(defun install-condition-slot-reader (name condition slot-name) + (declare (ignore condition)) + (setf (fdefinition name) + (lambda (condition) + (condition-reader-function condition slot-name)))) +(defun install-condition-slot-writer (name condition slot-name) + (declare (ignore condition)) + (setf (fdefinition name) + (lambda (new-value condition) + (condition-writer-function condition new-value slot-name)))) + (defun %define-condition (name slots documentation report default-initargs) (let ((class (find-classoid name))) (setf (condition-classoid-slots class) slots) @@ -356,15 +375,11 @@ (dolist (slot slots) ;; Set up reader and writer functions. - (let ((name (condition-slot-name slot))) + (let ((slot-name (condition-slot-name slot))) (dolist (reader (condition-slot-readers slot)) - (setf (fdefinition reader) - (lambda (condition) - (condition-reader-function condition name)))) + (install-condition-slot-reader reader name slot-name)) (dolist (writer (condition-slot-writers slot)) - (setf (fdefinition writer) - (lambda (new-value condition) - (condition-writer-function condition new-value name)))))) + (install-condition-slot-writer writer name slot-name)))) ;; Compute effective slots and set up the class and hairy slots ;; (subsets of the effective slots.) @@ -526,7 +541,7 @@ ;;; methods) (defun describe-condition (condition stream) (format stream - "~@<~S ~_is a ~S. ~_Its slot values are ~_~S.~:>" + "~&~@<~S ~_is a ~S. ~_Its slot values are ~_~S.~:>~%" condition (type-of condition) (concatenate 'list @@ -550,10 +565,12 @@ (define-condition simple-condition () ((format-control :reader simple-condition-format-control - :initarg :format-control) + :initarg :format-control + :type format-control) (format-arguments :reader simple-condition-format-arguments :initarg :format-arguments - :initform '())) + :initform '() + :type list)) (:report simple-condition-printer)) (define-condition simple-warning (simple-condition warning) ()) @@ -660,11 +677,28 @@ :initform '())) (:report (lambda (condition stream) - (let ((error-stream (stream-error-stream condition))) - (format stream "READER-ERROR ~@[at ~W ~]on ~S:~%~?" - (file-position error-stream) error-stream - (reader-error-format-control condition) - (reader-error-format-arguments condition)))))) + (let* ((error-stream (stream-error-stream condition)) + (pos (file-position error-stream))) + (let (lineno colno) + (when (and pos + (< pos sb!xc:array-dimension-limit) + (file-position error-stream :start)) + (let ((string + (make-string pos + :element-type (stream-element-type error-stream)))) + (when (= pos (read-sequence string error-stream)) + (setq lineno (1+ (count #\Newline string)) + colno (- pos + (or (position #\Newline string :from-end t) -1) + 1)))) + (file-position error-stream pos)) + (format stream + "READER-ERROR ~@[at ~W ~]~ + ~@[(line ~W~]~@[, column ~W) ~]~ + on ~S:~%~?" + pos lineno colno error-stream + (reader-error-format-control condition) + (reader-error-format-arguments condition))))))) ;;;; various other (not specified by ANSI) CONDITIONs ;;;; @@ -672,6 +706,15 @@ ;;;; setup of CONDITION machinery, only because that makes it easier to ;;;; get cold init to work. +(define-condition values-type-error (type-error) + () + (:report + (lambda (condition stream) + (format stream + "~@" + (type-error-datum condition) + (type-error-expected-type condition))))) + ;;; KLUDGE: a condition for floating point errors when we can't or ;;; won't figure out what type they are. (In FreeBSD and OpenBSD we ;;; don't know how, at least as of sbcl-0.6.7; in Linux we probably @@ -781,7 +824,17 @@ (define-condition sb!ext::timeout (serious-condition) ()) - +(define-condition defconstant-uneql (error) + ((name :initarg :name :reader defconstant-uneql-name) + (old-value :initarg :old-value :reader defconstant-uneql-old-value) + (new-value :initarg :new-value :reader defconstant-uneql-new-value)) + (:report + (lambda (condition stream) + (format stream + "~@" + (defconstant-uneql-name condition) + (defconstant-uneql-old-value condition) + (defconstant-uneql-new-value condition))))) ;;;; special SBCL extension conditions @@ -856,7 +909,7 @@ #!+sb-doc "Transfer control to a restart named ABORT, signalling a CONTROL-ERROR if none exists." - (invoke-restart (find-restart 'abort condition)) + (invoke-restart (find-restart-or-control-error 'abort condition)) ;; ABORT signals an error in case there was a restart named ABORT ;; that did not transfer control dynamically. This could happen with ;; RESTART-BIND. @@ -866,7 +919,7 @@ #!+sb-doc "Transfer control to a restart named MUFFLE-WARNING, signalling a CONTROL-ERROR if none exists." - (invoke-restart (find-restart 'muffle-warning condition))) + (invoke-restart (find-restart-or-control-error 'muffle-warning condition))) (macrolet ((define-nil-returning-restart (name args doc) #!-sb-doc (declare (ignore doc))