(return nil)))
(setf (getf (condition-assigned-slots res) (condition-slot-name hslot))
(find-slot-default class hslot))))
-
res))
\f
;;;; DEFINE-CONDITION
(eval-when (:compile-toplevel :load-toplevel :execute)
(defun %compiler-define-condition (name direct-supers layout
all-readers all-writers)
- (sb!xc:proclaim `(ftype (function (t) t) ,@all-readers))
- (sb!xc:proclaim `(ftype (function (t t) t) ,@all-writers))
- (multiple-value-bind (class old-layout)
- (insured-find-classoid name
- #'condition-classoid-p
- #'make-condition-classoid)
- (setf (layout-classoid layout) class)
- (setf (classoid-direct-superclasses class)
- (mapcar #'find-classoid direct-supers))
- (cond ((not old-layout)
- (register-layout layout))
- ((not *type-system-initialized*)
- (setf (layout-classoid old-layout) class)
- (setq layout old-layout)
- (unless (eq (classoid-layout class) layout)
+ (with-single-package-locked-error
+ (:symbol name "defining ~A as a condition")
+ (sb!xc:proclaim `(ftype (function (t) t) ,@all-readers))
+ (sb!xc:proclaim `(ftype (function (t t) t) ,@all-writers))
+ (multiple-value-bind (class old-layout)
+ (insured-find-classoid name
+ #'condition-classoid-p
+ #'make-condition-classoid)
+ (setf (layout-classoid layout) class)
+ (setf (classoid-direct-superclasses class)
+ (mapcar #'find-classoid direct-supers))
+ (cond ((not old-layout)
+ (register-layout layout))
+ ((not *type-system-initialized*)
+ (setf (layout-classoid old-layout) class)
+ (setq layout old-layout)
+ (unless (eq (classoid-layout class) layout)
+ (register-layout layout)))
+ ((redefine-layout-warning "current"
+ old-layout
+ "new"
+ (layout-length layout)
+ (layout-inherits layout)
+ (layout-depthoid layout))
+ (register-layout layout :invalidate t))
+ ((not (classoid-layout class))
(register-layout layout)))
- ((redefine-layout-warning "current"
- old-layout
- "new"
- (layout-length layout)
- (layout-inherits layout)
- (layout-depthoid layout))
- (register-layout layout :invalidate t))
- ((not (classoid-layout class))
- (register-layout layout)))
-
- (setf (layout-info layout)
- (locally
- ;; KLUDGE: There's a FIND-CLASS DEFTRANSFORM for constant class
- ;; names which creates fast but non-cold-loadable, non-compact
- ;; code. In this context, we'd rather have compact, cold-loadable
- ;; code. -- WHN 19990928
- (declare (notinline find-classoid))
- (layout-info (classoid-layout (find-classoid 'condition)))))
-
- (setf (find-classoid name) class)
-
- ;; Initialize CPL slot.
- (setf (condition-classoid-cpl class)
- (remove-if-not #'condition-classoid-p
- (std-compute-class-precedence-list class))))
+
+ (setf (layout-info layout)
+ (locally
+ ;; KLUDGE: There's a FIND-CLASS DEFTRANSFORM for constant class
+ ;; names which creates fast but non-cold-loadable, non-compact
+ ;; code. In this context, we'd rather have compact, cold-loadable
+ ;; code. -- WHN 19990928
+ (declare (notinline find-classoid))
+ (layout-info (classoid-layout (find-classoid 'condition)))))
+
+ (setf (find-classoid name) class)
+
+ ;; Initialize CPL slot.
+ (setf (condition-classoid-cpl class)
+ (remove-if-not #'condition-classoid-p
+ (std-compute-class-precedence-list class)))))
(values))
) ; EVAL-WHEN
(defun %define-condition (name parent-types layout slots documentation
report default-initargs all-readers all-writers)
- (%compiler-define-condition name parent-types layout all-readers all-writers)
- (let ((class (find-classoid name)))
- (setf (condition-classoid-slots class) slots)
- (setf (condition-classoid-report class) report)
- (setf (condition-classoid-default-initargs class) default-initargs)
- (setf (fdocumentation name 'type) documentation)
-
- (dolist (slot slots)
-
- ;; Set up reader and writer functions.
- (let ((slot-name (condition-slot-name slot)))
- (dolist (reader (condition-slot-readers slot))
- (install-condition-slot-reader reader name slot-name))
- (dolist (writer (condition-slot-writers slot))
- (install-condition-slot-writer writer name slot-name))))
-
- ;; Compute effective slots and set up the class and hairy slots
- ;; (subsets of the effective slots.)
- (let ((eslots (compute-effective-slots class))
- (e-def-initargs
- (reduce #'append
- (mapcar #'condition-classoid-default-initargs
+ (with-single-package-locked-error
+ (:symbol name "defining ~A as a condition")
+ (%compiler-define-condition name parent-types layout all-readers all-writers)
+ (let ((class (find-classoid name)))
+ (setf (condition-classoid-slots class) slots)
+ (setf (condition-classoid-report class) report)
+ (setf (condition-classoid-default-initargs class) default-initargs)
+ (setf (fdocumentation name 'type) documentation)
+
+ (dolist (slot slots)
+
+ ;; Set up reader and writer functions.
+ (let ((slot-name (condition-slot-name slot)))
+ (dolist (reader (condition-slot-readers slot))
+ (install-condition-slot-reader reader name slot-name))
+ (dolist (writer (condition-slot-writers slot))
+ (install-condition-slot-writer writer name slot-name))))
+
+ ;; Compute effective slots and set up the class and hairy slots
+ ;; (subsets of the effective slots.)
+ (let ((eslots (compute-effective-slots class))
+ (e-def-initargs
+ (reduce #'append
+ (mapcar #'condition-classoid-default-initargs
(condition-classoid-cpl class)))))
- (dolist (slot eslots)
- (ecase (condition-slot-allocation slot)
- (:class
- (unless (condition-slot-cell slot)
- (setf (condition-slot-cell slot)
- (list (if (condition-slot-initform-p slot)
- (let ((initform (condition-slot-initform slot)))
- (if (functionp initform)
- (funcall initform)
- initform))
- *empty-condition-slot*))))
- (push slot (condition-classoid-class-slots class)))
- ((:instance nil)
- (setf (condition-slot-allocation slot) :instance)
- (when (or (functionp (condition-slot-initform slot))
- (dolist (initarg (condition-slot-initargs slot) nil)
- (when (functionp (getf e-def-initargs initarg))
- (return t))))
- (push slot (condition-classoid-hairy-slots class))))))))
- name)
+ (dolist (slot eslots)
+ (ecase (condition-slot-allocation slot)
+ (:class
+ (unless (condition-slot-cell slot)
+ (setf (condition-slot-cell slot)
+ (list (if (condition-slot-initform-p slot)
+ (let ((initform (condition-slot-initform slot)))
+ (if (functionp initform)
+ (funcall initform)
+ initform))
+ *empty-condition-slot*))))
+ (push slot (condition-classoid-class-slots class)))
+ ((:instance nil)
+ (setf (condition-slot-allocation slot) :instance)
+ (when (or (functionp (condition-slot-initform slot))
+ (dolist (initarg (condition-slot-initargs slot) nil)
+ (when (functionp (getf e-def-initargs initarg))
+ (return t))))
+ (push slot (condition-classoid-hairy-slots class))))))))
+ name))
(defmacro define-condition (name (&rest parent-types) (&rest slot-specs)
&body options)
(define-condition simple-error (simple-condition error) ())
+;;; not specified by ANSI, but too useful not to have around.
+(define-condition simple-style-warning (simple-condition style-warning) ())
+
(define-condition storage-condition (serious-condition) ())
(define-condition type-error (error)
(reader-error-format-control condition)
(reader-error-format-arguments condition)))))))
\f
-;;;; various other (not specified by ANSI) CONDITIONs
-;;;;
-;;;; These might logically belong in other files; they're here, after
-;;;; setup of CONDITION machinery, only because that makes it easier to
-;;;; get cold init to work.
-
-(define-condition simple-style-warning (simple-condition style-warning) ())
-
-(define-condition values-type-error (type-error)
- ()
- (:report
- (lambda (condition stream)
- (format stream
- "~@<The values set ~2I~:_[~{~S~^ ~}] ~I~_is not of type ~2I~_~S.~:>"
- (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
-;;; know how but the old code was broken by the conversion to POSIX
-;;; signal handling and hasn't been fixed as of sbcl-0.6.7.)
-;;;
-;;; FIXME: Perhaps this should also be a base class for all
-;;; floating point exceptions?
-(define-condition floating-point-exception (arithmetic-error)
- ((flags :initarg :traps
- :initform nil
- :reader floating-point-exception-traps))
- (:report (lambda (condition stream)
- (format stream
- "An arithmetic error ~S was signalled.~%"
- (type-of condition))
- (let ((traps (floating-point-exception-traps condition)))
- (if traps
- (format stream
- "Trapping conditions are: ~%~{ ~S~^~}~%"
- traps)
- (write-line
- "No traps are enabled? How can this be?"
- stream))))))
-
-(define-condition index-too-large-error (type-error)
- ()
- (:report
- (lambda (condition stream)
- (format stream
- "The index ~S is too large."
- (type-error-datum condition)))))
-
-(define-condition bounding-indices-bad-error (type-error)
- ((object :reader bounding-indices-bad-object :initarg :object))
- (:report
- (lambda (condition stream)
- (let* ((datum (type-error-datum condition))
- (start (car datum))
- (end (cdr datum))
- (object (bounding-indices-bad-object condition)))
- (etypecase object
- (sequence
- (format stream
- "The bounding indices ~S and ~S are bad for a sequence of length ~S."
- start end (length object)))
- (array
- ;; from WITH-ARRAY-DATA
- (format stream
- "The START and END parameters ~S and ~S are bad for an array of total size ~S."
- start end (array-total-size object))))))))
-
-(define-condition nil-array-accessed-error (type-error)
- ()
- (:report (lambda (condition stream)
- (declare (ignore condition))
- (format stream
- "An attempt to access an array of element-type ~
- NIL was made. Congratulations!"))))
-
-(define-condition io-timeout (stream-error)
- ((direction :reader io-timeout-direction :initarg :direction))
- (:report
- (lambda (condition stream)
- (declare (type stream stream))
- (format stream
- "I/O timeout ~(~A~)ing ~S"
- (io-timeout-direction condition)
- (stream-error-stream condition)))))
-
-(define-condition namestring-parse-error (parse-error)
- ((complaint :reader namestring-parse-error-complaint :initarg :complaint)
- (args :reader namestring-parse-error-args :initarg :args :initform nil)
- (namestring :reader namestring-parse-error-namestring :initarg :namestring)
- (offset :reader namestring-parse-error-offset :initarg :offset))
- (:report
- (lambda (condition stream)
- (format stream
- "parse error in namestring: ~?~% ~A~% ~V@T^"
- (namestring-parse-error-complaint condition)
- (namestring-parse-error-args condition)
- (namestring-parse-error-namestring condition)
- (namestring-parse-error-offset condition)))))
-
-(define-condition simple-package-error (simple-condition package-error) ())
-
-(define-condition reader-package-error (reader-error) ())
-
-(define-condition reader-eof-error (end-of-file)
- ((context :reader reader-eof-error-context :initarg :context))
- (:report
- (lambda (condition stream)
- (format stream
- "unexpected end of file on ~S ~A"
- (stream-error-stream condition)
- (reader-eof-error-context condition)))))
-
-(define-condition reader-impossible-number-error (reader-error)
- ((error :reader reader-impossible-number-error-error :initarg :error))
- (:report
- (lambda (condition stream)
- (let ((error-stream (stream-error-stream condition)))
- (format stream "READER-ERROR ~@[at ~W ~]on ~S:~%~?~%Original error: ~A"
- (file-position error-stream) error-stream
- (reader-error-format-control condition)
- (reader-error-format-arguments condition)
- (reader-impossible-number-error-error condition))))))
-
-(define-condition timeout (serious-condition) ())
-\f
;;;; special SBCL extension conditions
;;; an error apparently caused by a bug in SBCL itself
;;; FIXME: this is not the right place for this.
(defun print-reference (reference stream)
(ecase (car reference)
+ (:amop
+ (format stream "AMOP")
+ (format stream ", ")
+ (destructuring-bind (type data) (cdr reference)
+ (ecase type
+ (:generic-function (format stream "Generic Function ~S" data))
+ (:section (format stream "Section ~{~D~^.~}" data)))))
(:ansi-cl
(format stream "The ANSI Standard")
(format stream ", ")
(:special-operator (format stream "Special Operator ~S" data))
(:macro (format stream "Macro ~S" data))
(:section (format stream "Section ~{~D~^.~}" data))
- (:glossary (format stream "Glossary Entry ~S" data)))))
+ (:glossary (format stream "Glossary entry for ~S" data))
+ (:issue (format stream "writeup for Issue ~A" data)))))
(:sbcl
(format stream "The SBCL Manual")
(format stream ", ")
(print-reference r s)
(unless (null (cdr rs))
(terpri s)))))))
-
+
(define-condition duplicate-definition (reference-condition warning)
((name :initarg :name :reader duplicate-definition-name))
(:report (lambda (c s)
(reference-condition simple-warning)
()
(:default-initargs
- :references (list '(:ansi-cl :function make-array)
- '(:ansi-cl :function upgraded-array-element-type))))
+ :references (list
+ '(:ansi-cl :function make-array)
+ '(:ansi-cl :function sb!xc:upgraded-array-element-type))))
(define-condition displaced-to-array-too-small-error
(reference-condition simple-error)
(define-condition extension-failure (reference-condition simple-error)
())
+
+#!+sb-package-locks
+(progn
+
+(define-condition package-lock-violation (reference-condition package-error)
+ ((format-control :initform nil :initarg :format-control
+ :reader package-error-format-control)
+ (format-arguments :initform nil :initarg :format-arguments
+ :reader package-error-format-arguments))
+ (:report
+ (lambda (condition stream)
+ (let ((control (package-error-format-control condition)))
+ (if control
+ (apply #'format stream
+ (format nil "~~@<Lock on package ~A violated when ~A.~~:@>"
+ (package-name (package-error-package condition))
+ control)
+ (package-error-format-arguments condition))
+ (format stream "~@<Lock on package ~A violated.~:@>"
+ (package-name (package-error-package condition)))))))
+ ;; no :default-initargs -- reference-stuff provided by the
+ ;; signalling form in target-package.lisp
+ #!+sb-doc
+ (:documentation
+ "Subtype of CL:PACKAGE-ERROR. A subtype of this error is signalled
+when a package-lock is violated."))
+
+(define-condition package-locked-error (package-lock-violation) ()
+ #!+sb-doc
+ (:documentation
+ "Subtype of SB-EXT:PACKAGE-LOCK-VIOLATION. An error of this type is
+signalled when an operation on a package violates a package lock."))
+
+(define-condition symbol-package-locked-error (package-lock-violation)
+ ((symbol :initarg :symbol :reader package-locked-error-symbol))
+ #!+sb-doc
+ (:documentation
+ "Subtype of SB-EXT:PACKAGE-LOCK-VIOLATION. An error of this type is
+signalled when an operation on a symbol violates a package lock. The
+symbol that caused the violation is accessed by the function
+SB-EXT:PACKAGE-LOCKED-ERROR-SYMBOL."))
+
+) ; progn
+\f
+;;;; various other (not specified by ANSI) CONDITIONs
+;;;;
+;;;; These might logically belong in other files; they're here, after
+;;;; setup of CONDITION machinery, only because that makes it easier to
+;;;; get cold init to work.
+
+(define-condition encapsulated-condition (condition)
+ ((condition :initarg :condition :reader encapsulated-condition)))
+
+;;; This comes to play if we have multiple levels of encapsulated
+;;; errors and we need to dump them with MAKE-CONDITION-LOAD-FORM.
+;;; Should not see much/any use, but better to have it.
+(def!method make-load-form ((condition encapsulated-condition) &optional env)
+ `(make-condition 'encapsulated-condition
+ :condition ,(make-condition-load-form (encapsulated-condition condition) env)))
+
+(define-condition values-type-error (type-error)
+ ()
+ (:report
+ (lambda (condition stream)
+ (format stream
+ "~@<The values set ~2I~:_[~{~S~^ ~}] ~I~_is not of type ~2I~_~S.~:>"
+ (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
+;;; know how but the old code was broken by the conversion to POSIX
+;;; signal handling and hasn't been fixed as of sbcl-0.6.7.)
+;;;
+;;; FIXME: Perhaps this should also be a base class for all
+;;; floating point exceptions?
+(define-condition floating-point-exception (arithmetic-error)
+ ((flags :initarg :traps
+ :initform nil
+ :reader floating-point-exception-traps))
+ (:report (lambda (condition stream)
+ (format stream
+ "An arithmetic error ~S was signalled.~%"
+ (type-of condition))
+ (let ((traps (floating-point-exception-traps condition)))
+ (if traps
+ (format stream
+ "Trapping conditions are: ~%~{ ~S~^~}~%"
+ traps)
+ (write-line
+ "No traps are enabled? How can this be?"
+ stream))))))
+
+(define-condition index-too-large-error (type-error)
+ ()
+ (:report
+ (lambda (condition stream)
+ (format stream
+ "The index ~S is too large."
+ (type-error-datum condition)))))
+
+(define-condition bounding-indices-bad-error (reference-condition type-error)
+ ((object :reader bounding-indices-bad-object :initarg :object))
+ (:report
+ (lambda (condition stream)
+ (let* ((datum (type-error-datum condition))
+ (start (car datum))
+ (end (cdr datum))
+ (object (bounding-indices-bad-object condition)))
+ (etypecase object
+ (sequence
+ (format stream
+ "The bounding indices ~S and ~S are bad ~
+ for a sequence of length ~S."
+ start end (length object)))
+ (array
+ ;; from WITH-ARRAY-DATA
+ (format stream
+ "The START and END parameters ~S and ~S are ~
+ bad for an array of total size ~S."
+ start end (array-total-size object)))))))
+ (:default-initargs
+ :references
+ (list '(:ansi-cl :glossary "bounding index designator")
+ '(:ansi-cl :issue "SUBSEQ-OUT-OF-BOUNDS:IS-AN-ERROR"))))
+
+(define-condition nil-array-accessed-error (reference-condition type-error)
+ ()
+ (:report (lambda (condition stream)
+ (declare (ignore condition))
+ (format stream
+ "An attempt to access an array of element-type ~
+ NIL was made. Congratulations!")))
+ (:default-initargs
+ :references (list '(:ansi-cl :function sb!xc:upgraded-array-element-type)
+ '(:ansi-cl :section (15 1 2 1))
+ '(:ansi-cl :section (15 1 2 2)))))
+
+(define-condition io-timeout (stream-error)
+ ((direction :reader io-timeout-direction :initarg :direction))
+ (:report
+ (lambda (condition stream)
+ (declare (type stream stream))
+ (format stream
+ "I/O timeout ~(~A~)ing ~S"
+ (io-timeout-direction condition)
+ (stream-error-stream condition)))))
+
+(define-condition namestring-parse-error (parse-error)
+ ((complaint :reader namestring-parse-error-complaint :initarg :complaint)
+ (args :reader namestring-parse-error-args :initarg :args :initform nil)
+ (namestring :reader namestring-parse-error-namestring :initarg :namestring)
+ (offset :reader namestring-parse-error-offset :initarg :offset))
+ (:report
+ (lambda (condition stream)
+ (format stream
+ "parse error in namestring: ~?~% ~A~% ~V@T^"
+ (namestring-parse-error-complaint condition)
+ (namestring-parse-error-args condition)
+ (namestring-parse-error-namestring condition)
+ (namestring-parse-error-offset condition)))))
+
+(define-condition simple-package-error (simple-condition package-error) ())
+
+(define-condition reader-package-error (reader-error) ())
+
+(define-condition reader-eof-error (end-of-file)
+ ((context :reader reader-eof-error-context :initarg :context))
+ (:report
+ (lambda (condition stream)
+ (format stream
+ "unexpected end of file on ~S ~A"
+ (stream-error-stream condition)
+ (reader-eof-error-context condition)))))
+
+(define-condition reader-impossible-number-error (reader-error)
+ ((error :reader reader-impossible-number-error-error :initarg :error))
+ (:report
+ (lambda (condition stream)
+ (let ((error-stream (stream-error-stream condition)))
+ (format stream "READER-ERROR ~@[at ~W ~]on ~S:~%~?~%Original error: ~A"
+ (file-position error-stream) error-stream
+ (reader-error-format-control condition)
+ (reader-error-format-arguments condition)
+ (reader-impossible-number-error-error condition))))))
+
+(define-condition timeout (serious-condition) ())
\f
;;;; restart definitions