c1dc599c132c9af0c97685fe2529098d71e042cf
[sbcl.git] / src / code / condition.lisp
1 ;;;; stuff originally from CMU CL's error.lisp which can or should
2 ;;;; come late (mostly related to the CONDITION class itself)
3 ;;;;
4
5 ;;;; This software is part of the SBCL system. See the README file for
6 ;;;; more information.
7 ;;;;
8 ;;;; This software is derived from the CMU CL system, which was
9 ;;;; written at Carnegie Mellon University and released into the
10 ;;;; public domain. The software is in the public domain and is
11 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
12 ;;;; files for more information.
13
14 (in-package "SB!KERNEL")
15 \f
16 ;;;; the CONDITION class
17
18 (/show0 "condition.lisp 20")
19
20 (eval-when (:compile-toplevel :load-toplevel :execute)
21
22 (/show0 "condition.lisp 24")
23
24 (def!struct (condition-classoid (:include classoid)
25                                 (:constructor make-condition-classoid))
26   ;; list of CONDITION-SLOT structures for the direct slots of this
27   ;; class
28   (slots nil :type list)
29   ;; list of CONDITION-SLOT structures for all of the effective class
30   ;; slots of this class
31   (class-slots nil :type list)
32   ;; report function or NIL
33   (report nil :type (or function null))
34   ;; list of specifications of the form
35   ;;
36   ;;   (INITARG INITFORM THUNK)
37   ;;
38   ;; where THUNK, when called without arguments, returns the value for
39   ;; INITARG.
40   (direct-default-initargs () :type list)
41   ;; class precedence list as a list of CLASS objects, with all
42   ;; non-CONDITION classes removed
43   (cpl () :type list)
44   ;; a list of all the effective instance allocation slots of this
45   ;; class that have a non-constant initform or default-initarg.
46   ;; Values for these slots must be computed in the dynamic
47   ;; environment of MAKE-CONDITION.
48   (hairy-slots nil :type list))
49
50 (/show0 "condition.lisp 49")
51
52 ) ; EVAL-WHEN
53
54 (!defstruct-with-alternate-metaclass condition
55   :slot-names (actual-initargs assigned-slots)
56   :boa-constructor %make-condition-object
57   :superclass-name t
58   :metaclass-name condition-classoid
59   :metaclass-constructor make-condition-classoid
60   :dd-type structure)
61
62 (defun make-condition-object (actual-initargs)
63   (%make-condition-object actual-initargs nil))
64
65 (defstruct (condition-slot (:copier nil))
66   (name (missing-arg) :type symbol)
67   ;; list of all applicable initargs
68   (initargs (missing-arg) :type list)
69   ;; names of reader and writer functions
70   (readers (missing-arg) :type list)
71   (writers (missing-arg) :type list)
72   ;; true if :INITFORM was specified
73   (initform-p (missing-arg) :type (member t nil))
74   ;; If this is a function, call it with no args. Otherwise, it's the
75   ;; actual value.
76   (initform (missing-arg) :type t)
77   ;; allocation of this slot, or NIL until defaulted
78   (allocation nil :type (member :instance :class nil))
79   ;; If ALLOCATION is :CLASS, this is a cons whose car holds the value.
80   (cell nil :type (or cons null))
81   ;; slot documentation
82   (documentation nil :type (or string null)))
83
84 ;;; KLUDGE: It's not clear to me why CONDITION-CLASS has itself listed
85 ;;; in its CPL, while other classes derived from CONDITION-CLASS don't
86 ;;; have themselves listed in their CPLs. This behavior is inherited
87 ;;; from CMU CL, and didn't seem to be explained there, and I haven't
88 ;;; figured out whether it's right. -- WHN 19990612
89 (eval-when (:compile-toplevel :load-toplevel :execute)
90   (/show0 "condition.lisp 103")
91   (let ((condition-class (locally
92                            ;; KLUDGE: There's a DEFTRANSFORM
93                            ;; FIND-CLASSOID for constant class names
94                            ;; which creates fast but
95                            ;; non-cold-loadable, non-compact code. In
96                            ;; this context, we'd rather have compact,
97                            ;; cold-loadable code. -- WHN 19990928
98                            (declare (notinline find-classoid))
99                            (find-classoid 'condition))))
100     (setf (condition-classoid-cpl condition-class)
101           (list condition-class)))
102   (/show0 "condition.lisp 103"))
103
104 (setf (condition-classoid-report (locally
105                                    ;; KLUDGE: There's a DEFTRANSFORM
106                                    ;; FIND-CLASSOID for constant class
107                                    ;; names which creates fast but
108                                    ;; non-cold-loadable, non-compact
109                                    ;; code. In this context, we'd
110                                    ;; rather have compact,
111                                    ;; cold-loadable code. -- WHN
112                                    ;; 19990928
113                                    (declare (notinline find-classoid))
114                                    (find-classoid 'condition)))
115       (lambda (cond stream)
116         (format stream "Condition ~S was signalled." (type-of cond))))
117
118 (eval-when (:compile-toplevel :load-toplevel :execute)
119
120 (defun find-condition-layout (name parent-types)
121   (let* ((cpl (remove-duplicates
122                (reverse
123                 (reduce #'append
124                         (mapcar (lambda (x)
125                                   (condition-classoid-cpl
126                                    (find-classoid x)))
127                                 parent-types)))))
128          (cond-layout (info :type :compiler-layout 'condition))
129          (olayout (info :type :compiler-layout name))
130          ;; FIXME: Does this do the right thing in case of multiple
131          ;; inheritance? A quick look at DEFINE-CONDITION didn't make
132          ;; it obvious what ANSI intends to be done in the case of
133          ;; multiple inheritance, so it's not actually clear what the
134          ;; right thing is..
135          (new-inherits
136           (order-layout-inherits (concatenate 'simple-vector
137                                               (layout-inherits cond-layout)
138                                               (mapcar #'classoid-layout cpl)))))
139     (if (and olayout
140              (not (mismatch (layout-inherits olayout) new-inherits)))
141         olayout
142         (make-layout :classoid (make-undefined-classoid name)
143                      :inherits new-inherits
144                      :depthoid -1
145                      :length (layout-length cond-layout)))))
146
147 ) ; EVAL-WHEN
148
149 ;;; FIXME: ANSI's definition of DEFINE-CONDITION says
150 ;;;   Condition reporting is mediated through the PRINT-OBJECT method
151 ;;;   for the condition type in question, with *PRINT-ESCAPE* always
152 ;;;   being nil. Specifying (:REPORT REPORT-NAME) in the definition of
153 ;;;   a condition type C is equivalent to:
154 ;;;     (defmethod print-object ((x c) stream)
155 ;;;       (if *print-escape* (call-next-method) (report-name x stream)))
156 ;;; The current code doesn't seem to quite match that.
157 (def!method print-object ((x condition) stream)
158   (if *print-escape*
159       (if (and (typep x 'simple-condition) (slot-value x 'format-control))
160           (print-unreadable-object (x stream :type t :identity t)
161             (write (simple-condition-format-control x)
162                    :stream stream
163                    :lines 1))
164           (print-unreadable-object (x stream :type t :identity t)))
165       ;; KLUDGE: A comment from CMU CL here said
166       ;;   7/13/98 BUG? CPL is not sorted and results here depend on order of
167       ;;   superclasses in define-condition call!
168       (dolist (class (condition-classoid-cpl (classoid-of x))
169                      (error "no REPORT? shouldn't happen!"))
170         (let ((report (condition-classoid-report class)))
171           (when report
172             (return (funcall report x stream)))))))
173 \f
174 ;;;; slots of CONDITION objects
175
176 (defvar *empty-condition-slot* '(empty))
177
178 (defun find-slot-default (class slot)
179   (let ((initargs (condition-slot-initargs slot))
180         (cpl (condition-classoid-cpl class)))
181     ;; When CLASS or a superclass has a default initarg for SLOT, use
182     ;; that.
183     (dolist (class cpl)
184       (let ((direct-default-initargs
185               (condition-classoid-direct-default-initargs class)))
186         (dolist (initarg initargs)
187           (let ((initfunction (third (assoc initarg direct-default-initargs))))
188             (when initfunction
189               (return-from find-slot-default (funcall initfunction)))))))
190
191     ;; Otherwise use the initform of SLOT, if there is one.
192     (if (condition-slot-initform-p slot)
193         (let ((initform (condition-slot-initform slot)))
194           (if (functionp initform)
195               (funcall initform)
196               initform))
197         (error "unbound condition slot: ~S" (condition-slot-name slot)))))
198
199 (defun find-condition-class-slot (condition-class slot-name)
200   (dolist (sclass
201            (condition-classoid-cpl condition-class)
202            (error "There is no slot named ~S in ~S."
203                   slot-name condition-class))
204     (dolist (slot (condition-classoid-slots sclass))
205       (when (eq (condition-slot-name slot) slot-name)
206         (return-from find-condition-class-slot slot)))))
207
208 (defun condition-writer-function (condition new-value name)
209   (dolist (cslot (condition-classoid-class-slots
210                   (layout-classoid (%instance-layout condition)))
211                  (setf (getf (condition-assigned-slots condition) name)
212                        new-value))
213     (when (eq (condition-slot-name cslot) name)
214       (return (setf (car (condition-slot-cell cslot)) new-value)))))
215
216 (defun condition-reader-function (condition name)
217   (let ((class (layout-classoid (%instance-layout condition))))
218     (dolist (cslot (condition-classoid-class-slots class))
219       (when (eq (condition-slot-name cslot) name)
220         (return-from condition-reader-function
221                      (car (condition-slot-cell cslot)))))
222     (let ((val (getf (condition-assigned-slots condition) name
223                      *empty-condition-slot*)))
224       (if (eq val *empty-condition-slot*)
225           (let ((actual-initargs (condition-actual-initargs condition))
226                 (slot (find-condition-class-slot class name)))
227             (unless slot
228               (error "missing slot ~S of ~S" name condition))
229             (do ((initargs actual-initargs (cddr initargs)))
230                 ((endp initargs)
231                  (setf (getf (condition-assigned-slots condition) name)
232                        (find-slot-default class slot)))
233               (when (member (car initargs) (condition-slot-initargs slot))
234                 (return-from condition-reader-function
235                   (setf (getf (condition-assigned-slots condition)
236                               name)
237                         (cadr initargs))))))
238           val))))
239 \f
240 ;;;; MAKE-CONDITION
241
242 (defun make-condition (type &rest args)
243   #!+sb-doc
244   "Make an instance of a condition object using the specified initargs."
245   ;; Note: ANSI specifies no exceptional situations in this function.
246   ;; signalling simple-type-error would not be wrong.
247   (let* ((type (or (and (symbolp type) (find-classoid type nil))
248                     type))
249          (class (typecase type
250                   (condition-classoid type)
251                   (class
252                    ;; Punt to CLOS.
253                    (return-from make-condition
254                      (apply #'make-instance type args)))
255                   (classoid
256                    (error 'simple-type-error
257                           :datum type
258                           :expected-type 'condition-class
259                           :format-control "~S is not a condition class."
260                           :format-arguments (list type)))
261                   (t
262                    (error 'simple-type-error
263                           :datum type
264                           :expected-type 'condition-class
265                           :format-control
266                           "~s does not designate a condition class."
267                           :format-arguments (list type)))))
268          (res (make-condition-object args)))
269     (setf (%instance-layout res) (classoid-layout class))
270     ;; Set any class slots with initargs present in this call.
271     (dolist (cslot (condition-classoid-class-slots class))
272       (dolist (initarg (condition-slot-initargs cslot))
273         (let ((val (getf args initarg *empty-condition-slot*)))
274           (unless (eq val *empty-condition-slot*)
275             (setf (car (condition-slot-cell cslot)) val)))))
276     ;; Default any slots with non-constant defaults now.
277     (dolist (hslot (condition-classoid-hairy-slots class))
278       (when (dolist (initarg (condition-slot-initargs hslot) t)
279               (unless (eq (getf args initarg *empty-condition-slot*)
280                           *empty-condition-slot*)
281                 (return nil)))
282         (setf (getf (condition-assigned-slots res) (condition-slot-name hslot))
283               (find-slot-default class hslot))))
284     res))
285 \f
286 ;;;; DEFINE-CONDITION
287
288 (eval-when (:compile-toplevel :load-toplevel :execute)
289 (defun %compiler-define-condition (name direct-supers layout
290                                    all-readers all-writers)
291   (with-single-package-locked-error
292       (:symbol name "defining ~A as a condition")
293     (sb!xc:proclaim `(ftype (function (t) t) ,@all-readers))
294     (sb!xc:proclaim `(ftype (function (t t) t) ,@all-writers))
295     (multiple-value-bind (class old-layout)
296         (insured-find-classoid name
297                                #'condition-classoid-p
298                                #'make-condition-classoid)
299       (setf (layout-classoid layout) class)
300       (setf (classoid-direct-superclasses class)
301             (mapcar #'find-classoid direct-supers))
302       (cond ((not old-layout)
303              (register-layout layout))
304             ((not *type-system-initialized*)
305              (setf (layout-classoid old-layout) class)
306              (setq layout old-layout)
307              (unless (eq (classoid-layout class) layout)
308                (register-layout layout)))
309             ((redefine-layout-warning "current"
310                                       old-layout
311                                       "new"
312                                       (layout-length layout)
313                                       (layout-inherits layout)
314                                       (layout-depthoid layout)
315                                       (layout-n-untagged-slots layout))
316              (register-layout layout :invalidate t))
317             ((not (classoid-layout class))
318              (register-layout layout)))
319
320       (setf (layout-info layout)
321             (locally
322                 ;; KLUDGE: There's a FIND-CLASS DEFTRANSFORM for constant class
323                 ;; names which creates fast but non-cold-loadable, non-compact
324                 ;; code. In this context, we'd rather have compact, cold-loadable
325                 ;; code. -- WHN 19990928
326                 (declare (notinline find-classoid))
327               (layout-info (classoid-layout (find-classoid 'condition)))))
328
329       (setf (find-classoid name) class)
330
331       ;; Initialize CPL slot.
332       (setf (condition-classoid-cpl class)
333             (remove-if-not #'condition-classoid-p
334                            (std-compute-class-precedence-list class)))))
335   (values))
336 ) ; EVAL-WHEN
337
338 ;;; Compute the effective slots of CLASS, copying inherited slots and
339 ;;; destructively modifying direct slots.
340 ;;;
341 ;;; FIXME: It'd be nice to explain why it's OK to destructively modify
342 ;;; direct slots. Presumably it follows from the semantics of
343 ;;; inheritance and redefinition of conditions, but finding the cite
344 ;;; and documenting it here would be good. (Or, if this is not in fact
345 ;;; ANSI-compliant, fixing it would also be good.:-)
346 (defun compute-effective-slots (class)
347   (collect ((res (copy-list (condition-classoid-slots class))))
348     (dolist (sclass (cdr (condition-classoid-cpl class)))
349       (dolist (sslot (condition-classoid-slots sclass))
350         (let ((found (find (condition-slot-name sslot) (res)
351                            :key #'condition-slot-name)))
352           (cond (found
353                  (setf (condition-slot-initargs found)
354                        (union (condition-slot-initargs found)
355                               (condition-slot-initargs sslot)))
356                  (unless (condition-slot-initform-p found)
357                    (setf (condition-slot-initform-p found)
358                          (condition-slot-initform-p sslot))
359                    (setf (condition-slot-initform found)
360                          (condition-slot-initform sslot)))
361                  (unless (condition-slot-allocation found)
362                    (setf (condition-slot-allocation found)
363                          (condition-slot-allocation sslot))))
364                 (t
365                  (res (copy-structure sslot)))))))
366     (res)))
367
368 ;;; Early definitions of slot accessor creators.
369 ;;;
370 ;;; Slot accessors must be generic functions, but ANSI does not seem
371 ;;; to specify any of them, and we cannot support it before end of
372 ;;; warm init. So we use ordinary functions inside SBCL, and switch to
373 ;;; GFs only at the end of building.
374 (declaim (notinline install-condition-slot-reader
375                     install-condition-slot-writer))
376 (defun install-condition-slot-reader (name condition slot-name)
377   (declare (ignore condition))
378   (setf (fdefinition name)
379         (lambda (condition)
380           (condition-reader-function condition slot-name))))
381 (defun install-condition-slot-writer (name condition slot-name)
382   (declare (ignore condition))
383   (setf (fdefinition name)
384         (lambda (new-value condition)
385           (condition-writer-function condition new-value slot-name))))
386
387 (defvar *define-condition-hooks* nil)
388
389 (defun %set-condition-report (name report)
390   (setf (condition-classoid-report (find-classoid name))
391         report))
392
393 (defun %define-condition (name parent-types layout slots documentation
394                           direct-default-initargs all-readers all-writers
395                           source-location)
396   (with-single-package-locked-error
397       (:symbol name "defining ~A as a condition")
398     (%compiler-define-condition name parent-types layout all-readers all-writers)
399     (sb!c:with-source-location (source-location)
400       (setf (layout-source-location layout)
401             source-location))
402     (let ((class (find-classoid name)))
403       (setf (condition-classoid-slots class) slots
404             (condition-classoid-direct-default-initargs class) direct-default-initargs
405             (fdocumentation name 'type) documentation)
406
407       (dolist (slot slots)
408
409         ;; Set up reader and writer functions.
410         (let ((slot-name (condition-slot-name slot)))
411           (dolist (reader (condition-slot-readers slot))
412             (install-condition-slot-reader reader name slot-name))
413           (dolist (writer (condition-slot-writers slot))
414             (install-condition-slot-writer writer name slot-name))))
415
416       ;; Compute effective slots and set up the class and hairy slots
417       ;; (subsets of the effective slots.)
418       (let ((eslots (compute-effective-slots class))
419             (e-def-initargs
420              (reduce #'append
421                      (mapcar #'condition-classoid-direct-default-initargs
422                              (condition-classoid-cpl class)))))
423         (dolist (slot eslots)
424           (ecase (condition-slot-allocation slot)
425             (:class
426              (unless (condition-slot-cell slot)
427                (setf (condition-slot-cell slot)
428                      (list (if (condition-slot-initform-p slot)
429                                (let ((initform (condition-slot-initform slot)))
430                                  (if (functionp initform)
431                                      (funcall initform)
432                                      initform))
433                                *empty-condition-slot*))))
434              (push slot (condition-classoid-class-slots class)))
435             ((:instance nil)
436              (setf (condition-slot-allocation slot) :instance)
437              (when (or (functionp (condition-slot-initform slot))
438                        (dolist (initarg (condition-slot-initargs slot) nil)
439                          (when (functionp (third (assoc initarg e-def-initargs)))
440                            (return t))))
441                (push slot (condition-classoid-hairy-slots class)))))))
442       (when (boundp '*define-condition-hooks*)
443         (dolist (fun *define-condition-hooks*)
444           (funcall fun class))))
445     name))
446
447 (defmacro define-condition (name (&rest parent-types) (&rest slot-specs)
448                                  &body options)
449   #!+sb-doc
450   "DEFINE-CONDITION Name (Parent-Type*) (Slot-Spec*) Option*
451    Define NAME as a condition type. This new type inherits slots and its
452    report function from the specified PARENT-TYPEs. A slot spec is a list of:
453      (slot-name :reader <rname> :initarg <iname> {Option Value}*
454
455    The DEFINE-CLASS slot options :ALLOCATION, :INITFORM, [slot] :DOCUMENTATION
456    and :TYPE and the overall options :DEFAULT-INITARGS and
457    [type] :DOCUMENTATION are also allowed.
458
459    The :REPORT option is peculiar to DEFINE-CONDITION. Its argument is either
460    a string or a two-argument lambda or function name. If a function, the
461    function is called with the condition and stream to report the condition.
462    If a string, the string is printed.
463
464    Condition types are classes, but (as allowed by ANSI and not as described in
465    CLtL2) are neither STANDARD-OBJECTs nor STRUCTURE-OBJECTs. WITH-SLOTS and
466    SLOT-VALUE may not be used on condition objects."
467   (let* ((parent-types (or parent-types '(condition)))
468          (layout (find-condition-layout name parent-types))
469          (documentation nil)
470          (report nil)
471          (direct-default-initargs ()))
472     (collect ((slots)
473               (all-readers nil append)
474               (all-writers nil append))
475       (dolist (spec slot-specs)
476         (when (keywordp spec)
477           (warn "Keyword slot name indicates probable syntax error:~%  ~S"
478                 spec))
479         (let* ((spec (if (consp spec) spec (list spec)))
480                (slot-name (first spec))
481                (allocation :instance)
482                (initform-p nil)
483                documentation
484                initform)
485           (collect ((initargs)
486                     (readers)
487                     (writers))
488             (do ((options (rest spec) (cddr options)))
489                 ((null options))
490               (unless (and (consp options) (consp (cdr options)))
491                 (error "malformed condition slot spec:~%  ~S." spec))
492               (let ((arg (second options)))
493                 (case (first options)
494                   (:reader (readers arg))
495                   (:writer (writers arg))
496                   (:accessor
497                    (readers arg)
498                    (writers `(setf ,arg)))
499                   (:initform
500                    (when initform-p
501                      (error "more than one :INITFORM in ~S" spec))
502                    (setq initform-p t)
503                    (setq initform arg))
504                   (:initarg (initargs arg))
505                   (:allocation
506                    (setq allocation arg))
507                   (:documentation
508                    (when documentation
509                      (error "more than one :DOCUMENTATION in ~S" spec))
510                    (unless (stringp arg)
511                      (error "slot :DOCUMENTATION argument is not a string: ~S"
512                             arg))
513                    (setq documentation arg))
514                   (:type)
515                   (t
516                    (error "unknown slot option:~%  ~S" (first options))))))
517
518             (all-readers (readers))
519             (all-writers (writers))
520             (slots `(make-condition-slot
521                      :name ',slot-name
522                      :initargs ',(initargs)
523                      :readers ',(readers)
524                      :writers ',(writers)
525                      :initform-p ',initform-p
526                      :documentation ',documentation
527                      :initform ,(when initform-p
528                                   `#'(lambda () ,initform)))))))
529
530       (dolist (option options)
531         (unless (consp option)
532           (error "bad option:~%  ~S" option))
533         (case (first option)
534           (:documentation (setq documentation (second option)))
535           (:report
536            (let ((arg (second option)))
537              (setq report
538                    (if (stringp arg)
539                        `#'(lambda (condition stream)
540                             (declare (ignore condition))
541                             (write-string ,arg stream))
542                        `#'(lambda (condition stream)
543                             (funcall #',arg condition stream))))))
544           (:default-initargs
545            (doplist (initarg initform) (rest option)
546              (push ``(,',initarg ,',initform ,#'(lambda () ,initform))
547                    direct-default-initargs)))
548           (t
549            (error "unknown option: ~S" (first option)))))
550
551       `(progn
552          (eval-when (:compile-toplevel)
553            (%compiler-define-condition ',name ',parent-types ',layout
554                                        ',(all-readers) ',(all-writers)))
555          (eval-when (:load-toplevel :execute)
556            (%define-condition ',name
557                               ',parent-types
558                               ',layout
559                               (list ,@(slots))
560                               ,documentation
561                               (list ,@direct-default-initargs)
562                               ',(all-readers)
563                               ',(all-writers)
564                               (sb!c:source-location))
565            ;; This needs to be after %DEFINE-CONDITION in case :REPORT
566            ;; is a lambda referring to condition slot accessors:
567            ;; they're not proclaimed as functions before it has run if
568            ;; we're under EVAL or loaded as source.
569            (%set-condition-report ',name ,report)
570            ',name)))))
571 \f
572 ;;;; various CONDITIONs specified by ANSI
573
574 (define-condition serious-condition (condition) ())
575
576 (define-condition error (serious-condition) ())
577
578 (define-condition warning (condition) ())
579 (define-condition style-warning (warning) ())
580
581 (defun simple-condition-printer (condition stream)
582   (let ((control (simple-condition-format-control condition)))
583     (if control
584         (apply #'format stream
585                control
586                (simple-condition-format-arguments condition))
587         (error "No format-control for ~S" condition))))
588
589 (define-condition simple-condition ()
590   ((format-control :reader simple-condition-format-control
591                    :initarg :format-control
592                    :initform nil
593                    :type format-control)
594    (format-arguments :reader simple-condition-format-arguments
595                      :initarg :format-arguments
596                      :initform nil
597                      :type list))
598   (:report simple-condition-printer))
599
600 (define-condition simple-warning (simple-condition warning) ())
601
602 (define-condition simple-error (simple-condition error) ())
603
604 (define-condition storage-condition (serious-condition) ())
605
606 (define-condition type-error (error)
607   ((datum :reader type-error-datum :initarg :datum)
608    (expected-type :reader type-error-expected-type :initarg :expected-type))
609   (:report
610    (lambda (condition stream)
611      (format stream
612              "~@<The value ~2I~:_~S ~I~_is not of type ~2I~_~S.~:>"
613              (type-error-datum condition)
614              (type-error-expected-type condition)))))
615
616 (def!method print-object ((condition type-error) stream)
617   (if *print-escape*
618       (flet ((maybe-string (thing)
619                (ignore-errors
620                  (write-to-string thing :lines 1 :readably nil :array nil :pretty t))))
621         (let ((type (maybe-string (type-error-expected-type condition)))
622               (datum (maybe-string (type-error-datum condition))))
623           (if (and type datum)
624               (print-unreadable-object (condition stream :type t)
625                 (format stream "~@<expected-type: ~A ~_datum: ~A~:@>" type datum))
626               (call-next-method))))
627       (call-next-method)))
628
629 ;;; not specified by ANSI, but too useful not to have around.
630 (define-condition simple-style-warning (simple-condition style-warning) ())
631 (define-condition simple-type-error (simple-condition type-error) ())
632
633 ;; Can't have a function called SIMPLE-TYPE-ERROR or TYPE-ERROR...
634 (declaim (ftype (sfunction (t t t &rest t) nil) bad-type))
635 (defun bad-type (datum type control &rest arguments)
636   (error 'simple-type-error
637          :datum datum
638          :expected-type type
639          :format-control control
640          :format-arguments arguments))
641
642 (define-condition program-error (error) ())
643 (define-condition parse-error   (error) ())
644 (define-condition control-error (error) ())
645 (define-condition stream-error  (error)
646   ((stream :reader stream-error-stream :initarg :stream)))
647
648 (define-condition end-of-file (stream-error) ()
649   (:report
650    (lambda (condition stream)
651      (format stream
652              "end of file on ~S"
653              (stream-error-stream condition)))))
654
655 (define-condition closed-stream-error (stream-error) ()
656   (:report
657    (lambda (condition stream)
658      (format stream "~S is closed" (stream-error-stream condition)))))
659
660 (define-condition file-error (error)
661   ((pathname :reader file-error-pathname :initarg :pathname))
662   (:report
663    (lambda (condition stream)
664      (format stream "error on file ~S" (file-error-pathname condition)))))
665
666 (define-condition package-error (error)
667   ((package :reader package-error-package :initarg :package)))
668
669 (define-condition cell-error (error)
670   ((name :reader cell-error-name :initarg :name)))
671
672 (def!method print-object ((condition cell-error) stream)
673   (if (and *print-escape* (slot-boundp condition 'name))
674       (print-unreadable-object (condition stream :type t :identity t)
675         (princ (cell-error-name condition) stream))
676       (call-next-method)))
677
678 (define-condition unbound-variable (cell-error) ()
679   (:report
680    (lambda (condition stream)
681      (format stream
682              "The variable ~S is unbound."
683              (cell-error-name condition)))))
684
685 (define-condition undefined-function (cell-error) ()
686   (:report
687    (lambda (condition stream)
688      (format stream
689              "The function ~/sb-impl::print-symbol-with-prefix/ is undefined."
690              (cell-error-name condition)))))
691
692 (define-condition special-form-function (undefined-function) ()
693   (:report
694    (lambda (condition stream)
695      (format stream
696              "Cannot FUNCALL the SYMBOL-FUNCTION of special operator ~S."
697              (cell-error-name condition)))))
698
699 (define-condition arithmetic-error (error)
700   ((operation :reader arithmetic-error-operation
701               :initarg :operation
702               :initform nil)
703    (operands :reader arithmetic-error-operands
704              :initarg :operands))
705   (:report (lambda (condition stream)
706              (format stream
707                      "arithmetic error ~S signalled"
708                      (type-of condition))
709              (when (arithmetic-error-operation condition)
710                (format stream
711                        "~%Operation was ~S, operands ~S."
712                        (arithmetic-error-operation condition)
713                        (arithmetic-error-operands condition))))))
714
715 (define-condition division-by-zero         (arithmetic-error) ())
716 (define-condition floating-point-overflow  (arithmetic-error) ())
717 (define-condition floating-point-underflow (arithmetic-error) ())
718 (define-condition floating-point-inexact   (arithmetic-error) ())
719 (define-condition floating-point-invalid-operation (arithmetic-error) ())
720
721 (define-condition print-not-readable (error)
722   ((object :reader print-not-readable-object :initarg :object))
723   (:report
724    (lambda (condition stream)
725      (let ((obj (print-not-readable-object condition))
726            (*print-array* nil))
727        (format stream "~S cannot be printed readably." obj)))))
728
729 (define-condition reader-error (parse-error stream-error) ()
730   (:report (lambda (condition stream)
731              (%report-reader-error condition stream))))
732
733 ;;; a READER-ERROR whose REPORTing is controlled by FORMAT-CONTROL and
734 ;;; FORMAT-ARGS (the usual case for READER-ERRORs signalled from
735 ;;; within SBCL itself)
736 ;;;
737 ;;; (Inheriting CL:SIMPLE-CONDITION here isn't quite consistent with
738 ;;; the letter of the ANSI spec: this is not a condition signalled by
739 ;;; SIGNAL when a format-control is supplied by the function's first
740 ;;; argument. It seems to me (WHN) to be basically in the spirit of
741 ;;; the spec, but if not, it'd be straightforward to do our own
742 ;;; DEFINE-CONDITION SB-INT:SIMPLISTIC-CONDITION with
743 ;;; FORMAT-CONTROL and FORMAT-ARGS slots, and use that condition in
744 ;;; place of CL:SIMPLE-CONDITION here.)
745 (define-condition simple-reader-error (reader-error simple-condition)
746   ()
747   (:report (lambda (condition stream)
748              (%report-reader-error condition stream :simple t))))
749
750 ;;; base REPORTing of a READER-ERROR
751 ;;;
752 ;;; When SIMPLE, we expect and use SIMPLE-CONDITION-ish FORMAT-CONTROL
753 ;;; and FORMAT-ARGS slots.
754 (defun %report-reader-error (condition stream &key simple position)
755   (let ((error-stream (stream-error-stream condition)))
756     (pprint-logical-block (stream nil)
757       (if simple
758           (apply #'format stream
759                  (simple-condition-format-control condition)
760                  (simple-condition-format-arguments condition))
761           (prin1 (class-name (class-of condition)) stream))
762       (format stream "~2I~@[~_~_~:{~:(~A~): ~S~:^, ~:_~}~]~_~_Stream: ~S"
763               (stream-error-position-info error-stream position)
764               error-stream))))
765 \f
766 ;;;; special SBCL extension conditions
767
768 ;;; an error apparently caused by a bug in SBCL itself
769 ;;;
770 ;;; Note that we don't make any serious effort to use this condition
771 ;;; for *all* errors in SBCL itself. E.g. type errors and array
772 ;;; indexing errors can occur in functions called from SBCL code, and
773 ;;; will just end up as ordinary TYPE-ERROR or invalid index error,
774 ;;; because the signalling code has no good way to know that the
775 ;;; underlying problem is a bug in SBCL. But in the fairly common case
776 ;;; that the signalling code does know that it's found a bug in SBCL,
777 ;;; this condition is appropriate, reusing boilerplate and helping
778 ;;; users to recognize it as an SBCL bug.
779 (define-condition bug (simple-error)
780   ()
781   (:report
782    (lambda (condition stream)
783      (format stream
784              "~@<  ~? ~:@_~?~:>"
785              (simple-condition-format-control condition)
786              (simple-condition-format-arguments condition)
787              "~@<This is probably a bug in SBCL itself. (Alternatively, ~
788               SBCL might have been corrupted by bad user code, e.g. by an ~
789               undefined Lisp operation like ~S, or by stray pointers from ~
790               alien code or from unsafe Lisp code; or there might be a bug ~
791               in the OS or hardware that SBCL is running on.) If it seems to ~
792               be a bug in SBCL itself, the maintainers would like to know ~
793               about it. Bug reports are welcome on the SBCL ~
794               mailing lists, which you can find at ~
795               <http://sbcl.sourceforge.net/>.~:@>"
796              '((fmakunbound 'compile))))))
797
798 (define-condition simple-storage-condition (storage-condition simple-condition)
799   ())
800
801 ;;; a condition for use in stubs for operations which aren't supported
802 ;;; on some platforms
803 ;;;
804 ;;; E.g. in sbcl-0.7.0.5, it might be appropriate to do something like
805 ;;;   #-(or freebsd linux)
806 ;;;   (defun load-foreign (&rest rest)
807 ;;;     (error 'unsupported-operator :name 'load-foreign))
808 ;;;   #+(or freebsd linux)
809 ;;;   (defun load-foreign ... actual definition ...)
810 ;;; By signalling a standard condition in this case, we make it
811 ;;; possible for test code to distinguish between (1) intentionally
812 ;;; unimplemented and (2) unintentionally just screwed up somehow.
813 ;;; (Before this condition was defined, test code tried to deal with
814 ;;; this by checking for FBOUNDP, but that didn't work reliably. In
815 ;;; sbcl-0.7.0, a package screwup left the definition of
816 ;;; LOAD-FOREIGN in the wrong package, so it was unFBOUNDP even on
817 ;;; architectures where it was supposed to be supported, and the
818 ;;; regression tests cheerfully passed because they assumed that
819 ;;; unFBOUNDPness meant they were running on an system which didn't
820 ;;; support the extension.)
821 (define-condition unsupported-operator (simple-error) ())
822 \f
823 ;;; (:ansi-cl :function remove)
824 ;;; (:ansi-cl :section (a b c))
825 ;;; (:ansi-cl :glossary "similar")
826 ;;;
827 ;;; (:sbcl :node "...")
828 ;;; (:sbcl :variable *ed-functions*)
829 ;;;
830 ;;; FIXME: this is not the right place for this.
831 (defun print-reference (reference stream)
832   (ecase (car reference)
833     (:amop
834      (format stream "AMOP")
835      (format stream ", ")
836      (destructuring-bind (type data) (cdr reference)
837        (ecase type
838          (:readers "Readers for ~:(~A~) Metaobjects"
839                    (substitute #\  #\- (symbol-name data)))
840          (:initialization
841           (format stream "Initialization of ~:(~A~) Metaobjects"
842                   (substitute #\  #\- (symbol-name data))))
843          (:generic-function (format stream "Generic Function ~S" data))
844          (:function (format stream "Function ~S" data))
845          (:section (format stream "Section ~{~D~^.~}" data)))))
846     (:ansi-cl
847      (format stream "The ANSI Standard")
848      (format stream ", ")
849      (destructuring-bind (type data) (cdr reference)
850        (ecase type
851          (:function (format stream "Function ~S" data))
852          (:special-operator (format stream "Special Operator ~S" data))
853          (:macro (format stream "Macro ~S" data))
854          (:section (format stream "Section ~{~D~^.~}" data))
855          (:glossary (format stream "Glossary entry for ~S" data))
856          (:issue (format stream "writeup for Issue ~A" data)))))
857     (:sbcl
858      (format stream "The SBCL Manual")
859      (format stream ", ")
860      (destructuring-bind (type data) (cdr reference)
861        (ecase type
862          (:node (format stream "Node ~S" data))
863          (:variable (format stream "Variable ~S" data))
864          (:function (format stream "Function ~S" data)))))
865     ;; FIXME: other documents (e.g. CLIM, Franz documentation :-)
866     ))
867 (define-condition reference-condition ()
868   ((references :initarg :references :reader reference-condition-references)))
869 (defvar *print-condition-references* t)
870 (def!method print-object :around ((o reference-condition) s)
871   (call-next-method)
872   (unless (or *print-escape* *print-readably*)
873     (when (and *print-condition-references*
874                (reference-condition-references o))
875       (format s "~&See also:~%")
876       (pprint-logical-block (s nil :per-line-prefix "  ")
877         (do* ((rs (reference-condition-references o) (cdr rs))
878               (r (car rs) (car rs)))
879              ((null rs))
880           (print-reference r s)
881           (unless (null (cdr rs))
882             (terpri s)))))))
883
884 (define-condition simple-reference-error (reference-condition simple-error)
885   ())
886
887 (define-condition simple-reference-warning (reference-condition simple-warning)
888   ())
889
890 (define-condition arguments-out-of-domain-error
891     (arithmetic-error reference-condition)
892   ())
893
894 (define-condition duplicate-definition (reference-condition warning)
895   ((name :initarg :name :reader duplicate-definition-name))
896   (:report (lambda (c s)
897              (format s "~@<Duplicate definition for ~S found in ~
898                         one file.~@:>"
899                      (duplicate-definition-name c))))
900   (:default-initargs :references (list '(:ansi-cl :section (3 2 2 3)))))
901
902 (define-condition constant-modified (reference-condition warning)
903   ((fun-name :initarg :fun-name :reader constant-modified-fun-name))
904   (:report (lambda (c s)
905              (format s "~@<Destructive function ~S called on ~
906                         constant data.~@:>"
907                      (constant-modified-fun-name c))))
908   (:default-initargs :references (list '(:ansi-cl :special-operator quote)
909                                        '(:ansi-cl :section (3 2 2 3)))))
910
911 (define-condition package-at-variance (reference-condition simple-warning)
912   ()
913   (:default-initargs :references (list '(:ansi-cl :macro defpackage)
914                                        '(:sbcl :variable *on-package-variance*))))
915
916 (define-condition package-at-variance-error (reference-condition simple-condition
917                                              package-error)
918   ()
919   (:default-initargs :references (list '(:ansi-cl :macro defpackage))))
920
921 (define-condition defconstant-uneql (reference-condition error)
922   ((name :initarg :name :reader defconstant-uneql-name)
923    (old-value :initarg :old-value :reader defconstant-uneql-old-value)
924    (new-value :initarg :new-value :reader defconstant-uneql-new-value))
925   (:report
926    (lambda (condition stream)
927      (format stream
928              "~@<The constant ~S is being redefined (from ~S to ~S)~@:>"
929              (defconstant-uneql-name condition)
930              (defconstant-uneql-old-value condition)
931              (defconstant-uneql-new-value condition))))
932   (:default-initargs :references (list '(:ansi-cl :macro defconstant)
933                                        '(:sbcl :node "Idiosyncrasies"))))
934
935 (define-condition array-initial-element-mismatch
936     (reference-condition simple-warning)
937   ()
938   (:default-initargs
939       :references (list
940                    '(:ansi-cl :function make-array)
941                    '(:ansi-cl :function sb!xc:upgraded-array-element-type))))
942
943 (define-condition type-warning (reference-condition simple-warning)
944   ()
945   (:default-initargs :references (list '(:sbcl :node "Handling of Types"))))
946 (define-condition type-style-warning (reference-condition simple-style-warning)
947   ()
948   (:default-initargs :references (list '(:sbcl :node "Handling of Types"))))
949
950 (define-condition local-argument-mismatch (reference-condition simple-warning)
951   ()
952   (:default-initargs :references (list '(:ansi-cl :section (3 2 2 3)))))
953
954 (define-condition format-args-mismatch (reference-condition)
955   ()
956   (:default-initargs :references (list '(:ansi-cl :section (22 3 10 2)))))
957
958 (define-condition format-too-few-args-warning
959     (format-args-mismatch simple-warning)
960   ())
961 (define-condition format-too-many-args-warning
962     (format-args-mismatch simple-style-warning)
963   ())
964
965 (define-condition implicit-generic-function-warning (style-warning)
966   ((name :initarg :name :reader implicit-generic-function-name))
967   (:report
968    (lambda (condition stream)
969      (let ((*package* (find-package :keyword)))
970        (format stream "~@<Implicitly creating new generic function ~S.~:@>"
971                (implicit-generic-function-name condition))))))
972
973 (define-condition extension-failure (reference-condition simple-error)
974   ())
975
976 (define-condition structure-initarg-not-keyword
977     (reference-condition simple-style-warning)
978   ()
979   (:default-initargs :references (list '(:ansi-cl :section (2 4 8 13)))))
980
981 #!+sb-package-locks
982 (progn
983
984 (define-condition package-lock-violation (package-error
985                                           reference-condition
986                                           simple-condition)
987   ((current-package :initform *package*
988                     :reader package-lock-violation-in-package))
989   (:report
990    (lambda (condition stream)
991      (let ((control (simple-condition-format-control condition))
992            (error-package (package-name (package-error-package condition)))
993            (current-package (package-name (package-lock-violation-in-package condition))))
994        (if control
995            (apply #'format stream
996                   (format nil "~~@<Lock on package ~A violated when ~A while in package ~A.~~:@>"
997                           error-package
998                           control
999                           current-package)
1000                   (simple-condition-format-arguments condition))
1001            (format stream "~@<Lock on package ~A violated while in package ~A.~:@>"
1002                    error-package
1003                    current-package)))))
1004   ;; no :default-initargs -- reference-stuff provided by the
1005   ;; signalling form in target-package.lisp
1006   #!+sb-doc
1007   (:documentation
1008    "Subtype of CL:PACKAGE-ERROR. A subtype of this error is signalled
1009 when a package-lock is violated."))
1010
1011 (define-condition package-locked-error (package-lock-violation) ()
1012   #!+sb-doc
1013   (:documentation
1014    "Subtype of SB-EXT:PACKAGE-LOCK-VIOLATION. An error of this type is
1015 signalled when an operation on a package violates a package lock."))
1016
1017 (define-condition symbol-package-locked-error (package-lock-violation)
1018   ((symbol :initarg :symbol :reader package-locked-error-symbol))
1019   #!+sb-doc
1020   (:documentation
1021    "Subtype of SB-EXT:PACKAGE-LOCK-VIOLATION. An error of this type is
1022 signalled when an operation on a symbol violates a package lock. The
1023 symbol that caused the violation is accessed by the function
1024 SB-EXT:PACKAGE-LOCKED-ERROR-SYMBOL."))
1025
1026 ) ; progn
1027
1028 (define-condition undefined-alien-error (cell-error) ()
1029   (:report
1030    (lambda (condition stream)
1031      (if (slot-boundp condition 'name)
1032          (format stream "Undefined alien: ~S" (cell-error-name condition))
1033          (format stream "Undefined alien symbol.")))))
1034
1035 (define-condition undefined-alien-variable-error (undefined-alien-error) ()
1036   (:report
1037    (lambda (condition stream)
1038      (declare (ignore condition))
1039      (format stream "Attempt to access an undefined alien variable."))))
1040
1041 (define-condition undefined-alien-function-error (undefined-alien-error) ()
1042   (:report
1043    (lambda (condition stream)
1044      (declare (ignore condition))
1045      (format stream "Attempt to call an undefined alien function."))))
1046
1047 \f
1048 ;;;; various other (not specified by ANSI) CONDITIONs
1049 ;;;;
1050 ;;;; These might logically belong in other files; they're here, after
1051 ;;;; setup of CONDITION machinery, only because that makes it easier to
1052 ;;;; get cold init to work.
1053
1054 ;;; OAOOM warning: see cross-condition.lisp
1055 (define-condition encapsulated-condition (condition)
1056   ((condition :initarg :condition :reader encapsulated-condition)))
1057
1058 ;;; KLUDGE: a condition for floating point errors when we can't or
1059 ;;; won't figure out what type they are. (In FreeBSD and OpenBSD we
1060 ;;; don't know how, at least as of sbcl-0.6.7; in Linux we probably
1061 ;;; know how but the old code was broken by the conversion to POSIX
1062 ;;; signal handling and hasn't been fixed as of sbcl-0.6.7.)
1063 ;;;
1064 ;;; FIXME: Perhaps this should also be a base class for all
1065 ;;; floating point exceptions?
1066 (define-condition floating-point-exception (arithmetic-error)
1067   ((flags :initarg :traps
1068           :initform nil
1069           :reader floating-point-exception-traps))
1070   (:report (lambda (condition stream)
1071              (format stream
1072                      "An arithmetic error ~S was signalled.~%"
1073                      (type-of condition))
1074              (let ((traps (floating-point-exception-traps condition)))
1075                (if traps
1076                    (format stream
1077                            "Trapping conditions are: ~%~{ ~S~^~}~%"
1078                            traps)
1079                    (write-line
1080                     "No traps are enabled? How can this be?"
1081                     stream))))))
1082
1083 (define-condition invalid-array-index-error (type-error)
1084   ((array :initarg :array :reader invalid-array-index-error-array)
1085    (axis :initarg :axis :reader invalid-array-index-error-axis))
1086   (:report
1087    (lambda (condition stream)
1088      (let ((array (invalid-array-index-error-array condition)))
1089        (format stream "Index ~W out of bounds for ~@[axis ~W of ~]~S, ~
1090                        should be nonnegative and <~W."
1091                (type-error-datum condition)
1092                (when (> (array-rank array) 1)
1093                  (invalid-array-index-error-axis condition))
1094                (type-of array)
1095                ;; Extract the bound from (INTEGER 0 (BOUND))
1096                (caaddr (type-error-expected-type condition)))))))
1097
1098 (define-condition invalid-array-error (reference-condition type-error) ()
1099   (:report
1100    (lambda (condition stream)
1101      (let ((*print-array* nil))
1102        (format stream
1103                "~@<Displaced array originally of type ~S has been invalidated ~
1104                 due its displaced-to array ~S having become too small to hold ~
1105                 it: the displaced array's dimensions have all been set to zero ~
1106                 to trap accesses to it.~:@>"
1107                (type-error-expected-type condition)
1108                (array-displacement (type-error-datum condition))))))
1109   (:default-initargs
1110       :references
1111       (list '(:ansi-cl :function adjust-array))))
1112
1113 (define-condition index-too-large-error (type-error)
1114   ()
1115   (:report
1116    (lambda (condition stream)
1117      (format stream
1118              "The index ~S is too large."
1119              (type-error-datum condition)))))
1120
1121 (define-condition bounding-indices-bad-error (reference-condition type-error)
1122   ((object :reader bounding-indices-bad-object :initarg :object))
1123   (:report
1124    (lambda (condition stream)
1125      (let* ((datum (type-error-datum condition))
1126             (start (car datum))
1127             (end (cdr datum))
1128             (object (bounding-indices-bad-object condition)))
1129        (etypecase object
1130          (sequence
1131           (format stream
1132                   "The bounding indices ~S and ~S are bad ~
1133                    for a sequence of length ~S."
1134                   start end (length object)))
1135          (array
1136           ;; from WITH-ARRAY-DATA
1137           (format stream
1138                   "The START and END parameters ~S and ~S are ~
1139                    bad for an array of total size ~S."
1140                   start end (array-total-size object)))))))
1141   (:default-initargs
1142       :references
1143       (list '(:ansi-cl :glossary "bounding index designator")
1144             '(:ansi-cl :issue "SUBSEQ-OUT-OF-BOUNDS:IS-AN-ERROR"))))
1145
1146 (define-condition nil-array-accessed-error (reference-condition type-error)
1147   ()
1148   (:report (lambda (condition stream)
1149              (declare (ignore condition))
1150              (format stream
1151                      "An attempt to access an array of element-type ~
1152                       NIL was made.  Congratulations!")))
1153   (:default-initargs
1154       :references (list '(:ansi-cl :function sb!xc:upgraded-array-element-type)
1155                         '(:ansi-cl :section (15 1 2 1))
1156                         '(:ansi-cl :section (15 1 2 2)))))
1157
1158 (define-condition namestring-parse-error (parse-error)
1159   ((complaint :reader namestring-parse-error-complaint :initarg :complaint)
1160    (args :reader namestring-parse-error-args :initarg :args :initform nil)
1161    (namestring :reader namestring-parse-error-namestring :initarg :namestring)
1162    (offset :reader namestring-parse-error-offset :initarg :offset))
1163   (:report
1164    (lambda (condition stream)
1165      (format stream
1166              "parse error in namestring: ~?~%  ~A~%  ~V@T^"
1167              (namestring-parse-error-complaint condition)
1168              (namestring-parse-error-args condition)
1169              (namestring-parse-error-namestring condition)
1170              (namestring-parse-error-offset condition)))))
1171
1172 (define-condition simple-package-error (simple-condition package-error) ())
1173
1174 (define-condition simple-reader-package-error (simple-reader-error package-error) ())
1175
1176 (define-condition reader-eof-error (end-of-file)
1177   ((context :reader reader-eof-error-context :initarg :context))
1178   (:report
1179    (lambda (condition stream)
1180      (format stream
1181              "unexpected end of file on ~S ~A"
1182              (stream-error-stream condition)
1183              (reader-eof-error-context condition)))))
1184
1185 (define-condition reader-impossible-number-error (simple-reader-error)
1186   ((error :reader reader-impossible-number-error-error :initarg :error))
1187   (:report
1188    (lambda (condition stream)
1189      (let ((error-stream (stream-error-stream condition)))
1190        (format stream
1191                "READER-ERROR ~@[at ~W ~]on ~S:~%~?~%Original error: ~A"
1192                (file-position-or-nil-for-error error-stream) error-stream
1193                (simple-condition-format-control condition)
1194                (simple-condition-format-arguments condition)
1195                (reader-impossible-number-error-error condition))))))
1196
1197 (define-condition standard-readtable-modified-error (reference-condition error)
1198   ((operation :initarg :operation :reader standard-readtable-modified-operation))
1199   (:report (lambda (condition stream)
1200              (format stream "~S would modify the standard readtable."
1201                      (standard-readtable-modified-operation condition))))
1202   (:default-initargs :references `((:ansi-cl :section (2 1 1 2))
1203                                    (:ansi-cl :glossary "standard readtable"))))
1204
1205 (define-condition standard-pprint-dispatch-table-modified-error
1206     (reference-condition error)
1207   ((operation :initarg :operation
1208               :reader standard-pprint-dispatch-table-modified-operation))
1209   (:report (lambda (condition stream)
1210              (format stream "~S would modify the standard pprint dispatch table."
1211                      (standard-pprint-dispatch-table-modified-operation
1212                       condition))))
1213   (:default-initargs
1214       :references `((:ansi-cl :glossary "standard pprint dispatch table"))))
1215
1216 (define-condition timeout (serious-condition)
1217   ((seconds :initarg :seconds :initform nil :reader timeout-seconds))
1218   (:report (lambda (condition stream)
1219              (format stream "Timeout occurred~@[ after ~A seconds~]."
1220                      (timeout-seconds condition)))))
1221
1222 (define-condition io-timeout (stream-error timeout)
1223   ((direction :reader io-timeout-direction :initarg :direction))
1224   (:report
1225    (lambda (condition stream)
1226      (declare (type stream stream))
1227      (format stream
1228              "I/O timeout while doing ~(~A~) on ~S."
1229              (io-timeout-direction condition)
1230              (stream-error-stream condition)))))
1231
1232 (define-condition deadline-timeout (timeout) ()
1233   (:report (lambda (condition stream)
1234              (format stream "A deadline was reached after ~A seconds."
1235                      (timeout-seconds condition)))))
1236
1237 (define-condition declaration-type-conflict-error (reference-condition
1238                                                    simple-error)
1239   ()
1240   (:default-initargs
1241       :format-control "symbol ~S cannot be both the name of a type and the name of a declaration"
1242     :references (list '(:ansi-cl :section (3 8 21)))))
1243
1244 ;;; Single stepping conditions
1245
1246 (define-condition step-condition ()
1247   ((form :initarg :form :reader step-condition-form))
1248
1249   #!+sb-doc
1250   (:documentation "Common base class of single-stepping conditions.
1251 STEP-CONDITION-FORM holds a string representation of the form being
1252 stepped."))
1253
1254 #!+sb-doc
1255 (setf (fdocumentation 'step-condition-form 'function)
1256       "Form associated with the STEP-CONDITION.")
1257
1258 (define-condition step-form-condition (step-condition)
1259   ((args :initarg :args :reader step-condition-args))
1260   (:report
1261    (lambda (condition stream)
1262      (let ((*print-circle* t)
1263            (*print-pretty* t)
1264            (*print-readably* nil))
1265        (format stream
1266                  "Evaluating call:~%~<  ~@;~A~:>~%~
1267                   ~:[With arguments:~%~{  ~S~%~}~;With unknown arguments~]~%"
1268                (list (step-condition-form condition))
1269                (eq (step-condition-args condition) :unknown)
1270                (step-condition-args condition)))))
1271   #!+sb-doc
1272   (:documentation "Condition signalled by code compiled with
1273 single-stepping information when about to execute a form.
1274 STEP-CONDITION-FORM holds the form, STEP-CONDITION-PATHNAME holds the
1275 pathname of the original file or NIL, and STEP-CONDITION-SOURCE-PATH
1276 holds the source-path to the original form within that file or NIL.
1277 Associated with this condition are always the restarts STEP-INTO,
1278 STEP-NEXT, and STEP-CONTINUE."))
1279
1280 (define-condition step-result-condition (step-condition)
1281   ((result :initarg :result :reader step-condition-result)))
1282
1283 #!+sb-doc
1284 (setf (fdocumentation 'step-condition-result 'function)
1285       "Return values associated with STEP-VALUES-CONDITION as a list,
1286 or the variable value associated with STEP-VARIABLE-CONDITION.")
1287
1288 (define-condition step-values-condition (step-result-condition)
1289   ()
1290   #!+sb-doc
1291   (:documentation "Condition signalled by code compiled with
1292 single-stepping information after executing a form.
1293 STEP-CONDITION-FORM holds the form, and STEP-CONDITION-RESULT holds
1294 the values returned by the form as a list. No associated restarts."))
1295
1296 (define-condition step-finished-condition (step-condition)
1297   ()
1298   (:report
1299    (lambda (condition stream)
1300      (declare (ignore condition))
1301      (format stream "Returning from STEP")))
1302   #!+sb-doc
1303   (:documentation "Condition signaled when STEP returns."))
1304 \f
1305 ;;; A knob for muffling warnings, mostly for use while loading files.
1306 (defvar *muffled-warnings* 'uninteresting-redefinition
1307   "A type that ought to specify a subtype of WARNING.  Whenever a
1308 warning is signaled, if the warning if of this type and is not
1309 handled by any other handler, it will be muffled.")
1310 \f
1311 ;;; Various STYLE-WARNING signaled in the system.
1312 ;; For the moment, we're only getting into the details for function
1313 ;; redefinitions, but other redefinitions could be done later
1314 ;; (e.g. methods).
1315 (define-condition redefinition-warning (style-warning)
1316   ((name
1317     :initarg :name
1318     :reader redefinition-warning-name)
1319    (new-location
1320     :initarg :new-location
1321     :reader redefinition-warning-new-location)))
1322
1323 (define-condition function-redefinition-warning (redefinition-warning)
1324   ((new-function
1325     :initarg :new-function
1326     :reader function-redefinition-warning-new-function)))
1327
1328 (define-condition redefinition-with-defun (function-redefinition-warning)
1329   ()
1330   (:report (lambda (warning stream)
1331              (format stream "redefining ~/sb-impl::print-symbol-with-prefix/ ~
1332                              in DEFUN"
1333                      (redefinition-warning-name warning)))))
1334
1335 (define-condition redefinition-with-defmacro (function-redefinition-warning)
1336   ()
1337   (:report (lambda (warning stream)
1338              (format stream "redefining ~/sb-impl::print-symbol-with-prefix/ ~
1339                              in DEFMACRO"
1340                      (redefinition-warning-name warning)))))
1341
1342 (define-condition redefinition-with-defgeneric (redefinition-warning)
1343   ()
1344   (:report (lambda (warning stream)
1345              (format stream "redefining ~/sb-impl::print-symbol-with-prefix/ ~
1346                              in DEFGENERIC"
1347                      (redefinition-warning-name warning)))))
1348
1349 (define-condition redefinition-with-defmethod (redefinition-warning)
1350   ((qualifiers :initarg :qualifiers
1351                :reader redefinition-with-defmethod-qualifiers)
1352    (specializers :initarg :specializers
1353                  :reader redefinition-with-defmethod-specializers)
1354    (new-location :initarg :new-location
1355                  :reader redefinition-with-defmethod-new-location)
1356    (old-method :initarg :old-method
1357                :reader redefinition-with-defmethod-old-method))
1358   (:report (lambda (warning stream)
1359              (format stream "redefining ~S~{ ~S~} ~S in DEFMETHOD"
1360                      (redefinition-warning-name warning)
1361                      (redefinition-with-defmethod-qualifiers warning)
1362                      (redefinition-with-defmethod-specializers warning)))))
1363
1364 ;;;; Deciding which redefinitions are "interesting".
1365
1366 (defun function-file-namestring (function)
1367   #!+sb-eval
1368   (when (typep function 'sb!eval:interpreted-function)
1369     (return-from function-file-namestring
1370       (sb!c:definition-source-location-namestring
1371           (sb!eval:interpreted-function-source-location function))))
1372   (let* ((fun (sb!kernel:%fun-fun function))
1373          (code (sb!kernel:fun-code-header fun))
1374          (debug-info (sb!kernel:%code-debug-info code))
1375          (debug-source (when debug-info
1376                          (sb!c::debug-info-source debug-info)))
1377          (namestring (when debug-source
1378                        (sb!c::debug-source-namestring debug-source))))
1379     namestring))
1380
1381 (defun interesting-function-redefinition-warning-p (warning old)
1382   (let ((new (function-redefinition-warning-new-function warning))
1383         (source-location (redefinition-warning-new-location warning)))
1384     (or
1385      ;; Compiled->Interpreted is interesting.
1386      (and (typep old 'compiled-function)
1387           (typep new '(not compiled-function)))
1388      ;; FIN->Regular is interesting.
1389      (and (typep old 'funcallable-instance)
1390           (typep new '(not funcallable-instance)))
1391      ;; Different file or unknown location is interesting.
1392      (let* ((old-namestring (function-file-namestring old))
1393             (new-namestring
1394              (or (function-file-namestring new)
1395                  (when source-location
1396                    (sb!c::definition-source-location-namestring source-location)))))
1397        (and (or (not old-namestring)
1398                 (not new-namestring)
1399                 (not (string= old-namestring new-namestring))))))))
1400
1401 (defun uninteresting-ordinary-function-redefinition-p (warning)
1402   (and
1403    ;; There's garbage in various places when the first DEFUN runs in
1404    ;; cold-init.
1405    sb!kernel::*cold-init-complete-p*
1406    (typep warning 'redefinition-with-defun)
1407    ;; Shared logic.
1408    (let ((name (redefinition-warning-name warning)))
1409      (not (interesting-function-redefinition-warning-p
1410            warning (or (fdefinition name) (macro-function name)))))))
1411
1412 (defun uninteresting-macro-redefinition-p (warning)
1413   (and
1414    (typep warning 'redefinition-with-defmacro)
1415    ;; Shared logic.
1416    (let ((name (redefinition-warning-name warning)))
1417      (not (interesting-function-redefinition-warning-p
1418            warning (or (macro-function name) (fdefinition name)))))))
1419
1420 (defun uninteresting-generic-function-redefinition-p (warning)
1421   (and
1422    (typep warning 'redefinition-with-defgeneric)
1423    ;; Can't use the shared logic above, since GF's don't get a "new"
1424    ;; definition -- rather the FIN-FUNCTION is set.
1425    (let* ((name (redefinition-warning-name warning))
1426           (old (fdefinition name))
1427           (old-location (when (typep old 'generic-function)
1428                           (sb!pcl::definition-source old)))
1429           (old-namestring (when old-location
1430                             (sb!c:definition-source-location-namestring old-location)))
1431           (new-location (redefinition-warning-new-location warning))
1432           (new-namestring (when new-location
1433                            (sb!c:definition-source-location-namestring new-location))))
1434      (and old-namestring
1435           new-namestring
1436           (string= old-namestring new-namestring)))))
1437
1438 (defun uninteresting-method-redefinition-p (warning)
1439   (and
1440    (typep warning 'redefinition-with-defmethod)
1441    ;; Can't use the shared logic above, since GF's don't get a "new"
1442    ;; definition -- rather the FIN-FUNCTION is set.
1443    (let* ((old-method (redefinition-with-defmethod-old-method warning))
1444           (old-location (sb!pcl::definition-source old-method))
1445           (old-namestring (when old-location
1446                             (sb!c:definition-source-location-namestring old-location)))
1447           (new-location (redefinition-warning-new-location warning))
1448           (new-namestring (when new-location
1449                             (sb!c:definition-source-location-namestring new-location))))
1450          (and new-namestring
1451               old-namestring
1452               (string= new-namestring old-namestring)))))
1453
1454 (deftype uninteresting-redefinition ()
1455   '(or (satisfies uninteresting-ordinary-function-redefinition-p)
1456        (satisfies uninteresting-macro-redefinition-p)
1457        (satisfies uninteresting-generic-function-redefinition-p)
1458        (satisfies uninteresting-method-redefinition-p)))
1459
1460 (define-condition redefinition-with-deftransform (redefinition-warning)
1461   ((transform :initarg :transform
1462               :reader redefinition-with-deftransform-transform))
1463   (:report (lambda (warning stream)
1464              (format stream "Overwriting ~S"
1465                      (redefinition-with-deftransform-transform warning)))))
1466 \f
1467 ;;; Various other STYLE-WARNINGS
1468 (define-condition dubious-asterisks-around-variable-name
1469     (style-warning simple-condition)
1470   ()
1471   (:report (lambda (warning stream)
1472              (format stream "~@?, even though the name follows~@
1473 the usual naming convention (names like *FOO*) for special variables"
1474                      (simple-condition-format-control warning)
1475                      (simple-condition-format-arguments warning)))))
1476
1477 (define-condition asterisks-around-lexical-variable-name
1478     (dubious-asterisks-around-variable-name)
1479   ())
1480
1481 (define-condition asterisks-around-constant-variable-name
1482     (dubious-asterisks-around-variable-name)
1483   ())
1484
1485 ;; We call this UNDEFINED-ALIEN-STYLE-WARNING because there are some
1486 ;; subclasses of ERROR above having to do with undefined aliens.
1487 (define-condition undefined-alien-style-warning (style-warning)
1488   ((symbol :initarg :symbol :reader undefined-alien-symbol))
1489   (:report (lambda (warning stream)
1490              (format stream "Undefined alien: ~S"
1491                      (undefined-alien-symbol warning)))))
1492
1493 #!+sb-eval
1494 (define-condition lexical-environment-too-complex (style-warning)
1495   ((form :initarg :form :reader lexical-environment-too-complex-form)
1496    (lexenv :initarg :lexenv :reader lexical-environment-too-complex-lexenv))
1497   (:report (lambda (warning stream)
1498              (format stream
1499                      "~@<Native lexical environment too complex for ~
1500                          SB-EVAL to evaluate ~S, falling back to ~
1501                          SIMPLE-EVAL-IN-LEXENV.  Lexenv: ~S~:@>"
1502                      (lexical-environment-too-complex-form warning)
1503                      (lexical-environment-too-complex-lexenv warning)))))
1504
1505 ;; Although this has -ERROR- in the name, it's just a STYLE-WARNING.
1506 (define-condition character-decoding-error-in-comment (style-warning)
1507   ((stream :initarg :stream :reader decoding-error-in-comment-stream)
1508    (position :initarg :position :reader decoding-error-in-comment-position))
1509   (:report (lambda (warning stream)
1510              (format stream
1511                       "Character decoding error in a ~A-comment at ~
1512                       position ~A reading source stream ~A, ~
1513                       resyncing."
1514                       (decoding-error-in-comment-macro warning)
1515                       (decoding-error-in-comment-position warning)
1516                       (decoding-error-in-comment-stream warning)))))
1517
1518 (define-condition character-decoding-error-in-macro-char-comment
1519     (character-decoding-error-in-comment)
1520   ((char :initform #\; :initarg :char
1521          :reader character-decoding-error-in-macro-char-comment-char)))
1522
1523 (define-condition character-decoding-error-in-dispatch-macro-char-comment
1524     (character-decoding-error-in-comment)
1525   ;; ANSI doesn't give a way for a reader function invoked by a
1526   ;; dispatch macro character to determine which dispatch character
1527   ;; was used, so if a user wants to signal one of these from a custom
1528   ;; comment reader, he'll have to supply the :DISP-CHAR himself.
1529   ((disp-char :initform #\# :initarg :disp-char
1530               :reader character-decoding-error-in-macro-char-comment-disp-char)
1531    (sub-char :initarg :sub-char
1532              :reader character-decoding-error-in-macro-char-comment-sub-char)))
1533
1534 (defun decoding-error-in-comment-macro (warning)
1535   (etypecase warning
1536     (character-decoding-error-in-macro-char-comment
1537      (character-decoding-error-in-macro-char-comment-char warning))
1538     (character-decoding-error-in-dispatch-macro-char-comment
1539      (format
1540       nil "~C~C"
1541       (character-decoding-error-in-macro-char-comment-disp-char warning)
1542       (character-decoding-error-in-macro-char-comment-sub-char warning)))))
1543
1544 (define-condition deprecated-eval-when-situations (style-warning)
1545   ((situations :initarg :situations
1546                :reader deprecated-eval-when-situations-situations))
1547   (:report (lambda (warning stream)
1548              (format stream "using deprecated EVAL-WHEN situation names~{ ~S~}"
1549                      (deprecated-eval-when-situations-situations warning)))))
1550
1551 (define-condition proclamation-mismatch (style-warning)
1552   ((name :initarg :name :reader proclamation-mismatch-name)
1553    (old :initarg :old :reader proclamation-mismatch-old)
1554    (new :initarg :new :reader proclamation-mismatch-new)))
1555
1556 (define-condition type-proclamation-mismatch (proclamation-mismatch)
1557   ()
1558   (:report (lambda (warning stream)
1559              (format stream
1560                      "The new TYPE proclamation~% ~S for ~S does not ~
1561                      match the old TYPE proclamation ~S"
1562                      (proclamation-mismatch-new warning)
1563                      (proclamation-mismatch-name warning)
1564                      (proclamation-mismatch-old warning)))))
1565
1566 (define-condition ftype-proclamation-mismatch (proclamation-mismatch)
1567   ()
1568   (:report (lambda (warning stream)
1569              (format stream
1570                      "The new FTYPE proclamation~% ~S for ~S does not ~
1571                      match the old FTYPE proclamation ~S"
1572                      (proclamation-mismatch-new warning)
1573                      (proclamation-mismatch-name warning)
1574                      (proclamation-mismatch-old warning)))))
1575 \f
1576 ;;;; deprecation conditions
1577
1578 (define-condition deprecation-condition ()
1579   ((name :initarg :name :reader deprecated-name)
1580    (replacements :initarg :replacements :reader deprecated-name-replacements)
1581    (since :initarg :since :reader deprecated-since)
1582    (runtime-error :initarg :runtime-error :reader deprecated-name-runtime-error)))
1583
1584 (def!method print-object ((condition deprecation-condition) stream)
1585   (let ((*package* (find-package :keyword)))
1586     (if *print-escape*
1587         (print-unreadable-object (condition stream :type t)
1588           (apply #'format
1589                  stream "~S is deprecated.~
1590                          ~#[~; Use ~S instead.~; ~
1591                                Use ~S or ~S instead.~:; ~
1592                                Use~@{~#[~; or~] ~S~^,~} instead.~]"
1593                   (deprecated-name condition)
1594                   (deprecated-name-replacements condition)))
1595         (apply #'format
1596                stream "~@<~S has been deprecated as of SBCL ~A.~
1597                        ~#[~; Use ~S instead.~; ~
1598                              Use ~S or ~S instead.~:; ~
1599                              Use~@{~#[~; or~] ~S~^,~:_~} instead.~]~:@>"
1600                 (deprecated-name condition)
1601                 (deprecated-since condition)
1602                 (deprecated-name-replacements condition)))))
1603
1604 (define-condition early-deprecation-warning (style-warning deprecation-condition)
1605   ())
1606
1607 (def!method print-object :after ((warning early-deprecation-warning) stream)
1608   (unless *print-escape*
1609     (let ((*package* (find-package :keyword)))
1610       (format stream "~%~@<~:@_In future SBCL versions ~S will signal a full warning ~
1611                       at compile-time.~:@>"
1612               (deprecated-name warning)))))
1613
1614 (define-condition late-deprecation-warning (warning deprecation-condition)
1615   ())
1616
1617 (def!method print-object :after ((warning late-deprecation-warning) stream)
1618   (unless *print-escape*
1619     (when (deprecated-name-runtime-error warning)
1620       (let ((*package* (find-package :keyword)))
1621         (format stream "~%~@<~:@_In future SBCL versions ~S will signal a runtime error.~:@>"
1622                 (deprecated-name warning))))))
1623
1624 (define-condition final-deprecation-warning (warning deprecation-condition)
1625   ())
1626
1627 (def!method print-object :after ((warning final-deprecation-warning) stream)
1628   (unless *print-escape*
1629     (when (deprecated-name-runtime-error warning)
1630       (let ((*package* (find-package :keyword)))
1631         (format stream "~%~@<~:@_An error will be signaled at runtime for ~S.~:@>"
1632                 (deprecated-name warning))))))
1633
1634 (define-condition deprecation-error (error deprecation-condition)
1635   ())
1636 \f
1637 ;;;; restart definitions
1638
1639 (define-condition abort-failure (control-error) ()
1640   (:report
1641    "An ABORT restart was found that failed to transfer control dynamically."))
1642
1643 (defun abort (&optional condition)
1644   #!+sb-doc
1645   "Transfer control to a restart named ABORT, signalling a CONTROL-ERROR if
1646    none exists."
1647   (invoke-restart (find-restart-or-control-error 'abort condition))
1648   ;; ABORT signals an error in case there was a restart named ABORT
1649   ;; that did not transfer control dynamically. This could happen with
1650   ;; RESTART-BIND.
1651   (error 'abort-failure))
1652
1653 (defun muffle-warning (&optional condition)
1654   #!+sb-doc
1655   "Transfer control to a restart named MUFFLE-WARNING, signalling a
1656    CONTROL-ERROR if none exists."
1657   (invoke-restart (find-restart-or-control-error 'muffle-warning condition)))
1658
1659 (defun try-restart (name condition &rest arguments)
1660   (let ((restart (find-restart name condition)))
1661     (when restart
1662       (apply #'invoke-restart restart arguments))))
1663
1664 (macrolet ((define-nil-returning-restart (name args doc)
1665              #!-sb-doc (declare (ignore doc))
1666              `(defun ,name (,@args &optional condition)
1667                 #!+sb-doc ,doc
1668                 (try-restart ',name condition ,@args))))
1669   (define-nil-returning-restart continue ()
1670     "Transfer control to a restart named CONTINUE, or return NIL if none exists.")
1671   (define-nil-returning-restart store-value (value)
1672     "Transfer control and VALUE to a restart named STORE-VALUE, or
1673 return NIL if none exists.")
1674   (define-nil-returning-restart use-value (value)
1675     "Transfer control and VALUE to a restart named USE-VALUE, or
1676 return NIL if none exists.")
1677   (define-nil-returning-restart print-unreadably ()
1678     "Transfer control to a restart named SB-EXT:PRINT-UNREADABLY, or
1679 return NIL if none exists."))
1680
1681 ;;; single-stepping restarts
1682
1683 (macrolet ((def (name doc)
1684                #!-sb-doc (declare (ignore doc))
1685                `(defun ,name (condition)
1686                  #!+sb-doc ,doc
1687                  (invoke-restart (find-restart-or-control-error ',name condition)))))
1688   (def step-continue
1689       "Transfers control to the STEP-CONTINUE restart associated with
1690 the condition, continuing execution without stepping. Signals a
1691 CONTROL-ERROR if the restart does not exist.")
1692   (def step-next
1693       "Transfers control to the STEP-NEXT restart associated with the
1694 condition, executing the current form without stepping and continuing
1695 stepping with the next form. Signals CONTROL-ERROR is the restart does
1696 not exists.")
1697   (def step-into
1698       "Transfers control to the STEP-INTO restart associated with the
1699 condition, stepping into the current form. Signals a CONTROL-ERROR is
1700 the restart does not exist."))
1701
1702 ;;; Compiler macro magic
1703
1704 (define-condition compiler-macro-keyword-problem ()
1705   ((argument :initarg :argument :reader compiler-macro-keyword-argument))
1706   (:report (lambda (condition stream)
1707              (format stream "~@<Argument ~S in keyword position is not ~
1708                              a self-evaluating symbol, preventing compiler-macro ~
1709                              expansion.~@:>"
1710                      (compiler-macro-keyword-argument condition)))))
1711
1712 (/show0 "condition.lisp end of file")