changelog shortlog graph tags branches changeset files file revisions raw help

Mercurial > core / annotate lisp/std/condition.lisp

changeset 645: 3e6a17fb5712
parent: 8b10eabe89dd
child: 95fd920af398
author: Richard Westhaver <ellis@rwest.io>
date: Wed, 11 Sep 2024 17:24:07 -0400
permissions: -rw-r--r--
description: clap upgrades
563
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
1
 ;;; condition.lisp --- Conditions and other exception handlers
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
2
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
3
 ;;; Code:
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
4
 (in-package :std/condition)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
5
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
6
 (defvar *std-error-message* "An error occured")
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
7
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
8
 (define-condition std-error (error)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
9
   ((message :initarg :message
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
10
             :initform *std-error-message*
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
11
             :reader std-error-message))
645
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
12
   (:documentation "Standard Error")
563
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
13
   (:report (lambda (condition stream)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
14
              (format stream "~X" (std-error-message condition)))))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
15
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
16
 (defun std-error (&rest args)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
17
   (cerror
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
18
    "Ignore and continue"
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
19
    'std-error
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
20
    :message (format nil "~A: ~A" *std-error-message* args)))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
21
 
645
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
22
 (define-condition std-warning (warning)
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
23
   ((message :initarg :message
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
24
             :initform nil
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
25
             :reader std-warning-message))
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
26
   (:documentation "Standard Warning")
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
27
   (:report
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
28
    (lambda (condition stream)
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
29
      (when (std-warning-message condition)
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
30
        (format stream "~X" (std-warning-message condition))))))
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
31
 
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
32
 (defun std-warning (&optional message)
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
33
   (warn 'std-warning :message message))
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
34
   
563
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
35
 (defun car-eql (a cons)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
36
   (eql a (car cons)))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
37
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
38
 (defmacro deferror (name (&rest parent-types) (&rest slot-specs) &rest options)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
39
   "Define an error condition."
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
40
   (let ((fun (member :auto options :test #'car-eql)))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
41
     (when fun (setq options (remove (car fun) options)))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
42
     `(prog1
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
43
          (define-condition ,name ,(or parent-types '(std-error)) ,slot-specs ,@options)
645
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
44
        (when ',fun
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
45
          (if (member 'simple-error ',parent-types)
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
46
              (def-simple-error-reporter ,name)
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
47
              (def-error-reporter ,name))))))
563
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
48
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
49
 (defmacro def-error-reporter (err)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
50
     `(defun ,err (&rest args)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
51
        ,(format nil "Signal an error of type ~A with ARGS." err)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
52
        (cerror
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
53
         "Ignore and continue"
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
54
         ',err
645
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
55
         :message (format nil "~A: ~A" ,*std-error-message* args))))
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
56
 
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
57
 (defmacro def-simple-error-reporter (name)
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
58
   `(progn
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
59
      (defun ,name (fmt &rest args)
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
60
        ,(format nil "Signal an error of type ~A with FMT string and ARGS." name)
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
61
        (cerror
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
62
         "Ignore and continue"
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
63
         ',name
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
64
         :format-control fmt
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
65
         :format-arguments args))))
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
66
 
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
67
 (defmacro defwarning (name (&rest parent-types) (&rest slot-specs) &rest options)
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
68
   "Define an warning condition."
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
69
   (let ((fun (member :auto options :test #'car-eql)))
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
70
     (when fun (setq options (remove (car fun) options)))
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
71
     `(prog1
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
72
          (eval-when (:compile-toplevel :load-toplevel :execute)
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
73
            (define-condition ,name ,(or parent-types '(std-warning)) ,slot-specs ,@options))
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
74
        (when ',fun
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
75
          (if (member 'simple-warning ',parent-types)
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
76
              (def-simple-warning-reporter ,name)
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
77
              (def-warning-reporter ,name))))))
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
78
 
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
79
 (defmacro def-warning-reporter (name)
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
80
   `(defun ,name (&optional message)
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
81
        ,(format nil "Signal a warning of type ~A with optional MESSAGE." name)
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
82
        (warn
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
83
         ',name
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
84
         :message message)))
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
85
 
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
86
 (defmacro def-simple-warning-reporter (name)
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
87
   `(defun ,name (fmt &rest args)
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
88
      ,(format nil "Signal an error of type ~A with FMT string and ARGS." name)
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
89
      (warn
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
90
       ',name
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
91
       :format-control fmt
3e6a17fb5712 clap upgrades
Richard Westhaver <ellis@rwest.io>
parents: 563
diff changeset
92
       :format-arguments args)))
563
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
93
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
94
 (defmacro nyi! (&optional comment)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
95
   `(prog1
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
96
        (error "Not Yet Implemented!")
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
97
      (when ',comment (print ',comment))))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
98
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
99
 (defun required-argument (&optional name)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
100
   "Signals an error for a missing argument of NAME. Intended for
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
101
 use as an initialization form for structure and class-slots, and
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
102
 a default value for required keyword arguments."
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
103
   (error "Required argument ~@[~S ~]missing." name))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
104
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
105
 (define-condition simple-style-warning (simple-warning style-warning)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
106
   ())
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
107
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
108
 (defun simple-style-warning (message &rest args)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
109
   (warn 'simple-style-warning :format-control message :format-arguments args))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
110
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
111
 ;; We don't specify a :report for simple-reader-error to let the
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
112
 ;; underlying implementation report the line and column position for
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
113
 ;; us. Unfortunately this way the message from simple-error is not
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
114
 ;; displayed, unless there's special support for that in the
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
115
 ;; implementation. But even then it's still inspectable from the
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
116
 ;; debugger...
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
117
 (define-condition simple-reader-error
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
118
     (sb-int:simple-reader-error)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
119
   ())
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
120
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
121
 (defun simple-reader-error (stream message &rest args)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
122
   (error 'simple-reader-error
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
123
          :stream stream
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
124
          :format-control message
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
125
          :format-arguments args))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
126
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
127
 (define-condition simple-parse-error (simple-error parse-error)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
128
   ())
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
129
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
130
 (defun simple-parse-error (message &rest args)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
131
   (error 'simple-parse-error
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
132
          :format-control message
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
133
          :format-arguments args))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
134
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
135
 (define-condition simple-program-error (simple-error program-error)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
136
   ())
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
137
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
138
 (defun simple-program-error (message &rest args)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
139
   (error 'simple-program-error
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
140
          :format-control message
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
141
          :format-arguments args))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
142
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
143
 (define-condition circular-dependency (simple-error)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
144
   ((items
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
145
     :initarg :items
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
146
     :initform (error "Must specify items")
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
147
     :reader circular-dependency-items))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
148
   (:report (lambda (condition stream)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
149
              (declare (ignore condition))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
150
              (format stream "Circular dependency detected")))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
151
   (:documentation "A condition which is signalled when a circular dependency is encountered."))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
152
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
153
 (define-condition unknown-argument (error)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
154
   ((name
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
155
     :initarg :name
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
156
     :initform (error "Must specify argument name")
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
157
     :reader unknown-argument-name)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
158
    (kind
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
159
     :initarg :kind
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
160
     :initform (error "Must specify argument kind")
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
161
     :reader unknown-argument-kind))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
162
   (:report (lambda (condition stream)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
163
              (format stream "Unknown argument ~A of kind ~A"
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
164
                      (unknown-argument-name condition)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
165
                      (unknown-argument-kind condition))))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
166
   (:documentation "A condition which is signalled when an unknown argument is encountered."))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
167
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
168
 (defun unknown-argument-p (value)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
169
   (typep value 'unknown-argument))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
170
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
171
 (define-condition missing-argument (simple-error)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
172
   ((item
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
173
     :initarg :item
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
174
     :initform (error "Must specify argument item")
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
175
     :reader missing-argument-item)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
176
    (command
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
177
     :initarg :command
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
178
     :initform (error "Must specify command")
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
179
     :reader missing-argument-command))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
180
   (:report (lambda (condition stream)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
181
              (declare (ignore condition))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
182
              (format stream "Missing argument")))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
183
   (:documentation "A condition which is signalled when an option expects an argument, but none was provided"))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
184
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
185
 (defun missing-argument-p (value)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
186
   (typep value 'missing-argument))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
187
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
188
 (define-condition invalid-argument (simple-error)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
189
   ((item
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
190
     :initarg :item
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
191
     :initform (error "Must specify argument item")
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
192
     :reader invalid-argument-item
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
193
     :documentation "The argument which is identified as invalid")
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
194
    (reason
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
195
     :initarg :reason
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
196
     :initform (error "Must specify reason")
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
197
     :reader invalid-argument-reason
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
198
     :documentation "The reason why this argument is invalid"))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
199
   (:report (lambda (condition stream)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
200
              (format stream "Invalid argument: ~A~%Reason: ~A" (invalid-argument-item condition) (invalid-argument-reason condition))))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
201
   (:documentation "A condition which is signalled when an argument is identified as invalid."))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
202
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
203
 (defmacro ignore-some-conditions ((&rest conditions) &body body)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
204
   "Similar to CL:IGNORE-ERRORS but the (unevaluated) CONDITIONS
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
205
 list determines which specific conditions are to be ignored."
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
206
   `(handler-case
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
207
        (progn ,@body)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
208
      ,@(loop for condition in conditions collect
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
209
              `(,condition (c) (values nil c)))))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
210
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
211
 (defmacro unwind-protect-case ((&optional abort-flag) protected-form &body clauses)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
212
   "Like CL:UNWIND-PROTECT, but you can specify the circumstances that
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
213
 the cleanup CLAUSES are run.
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
214
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
215
   clauses ::= (:NORMAL form*)* | (:ABORT form*)* | (:ALWAYS form*)*
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
216
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
217
 Clauses can be given in any order, and more than one clause can be
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
218
 given for each circumstance. The clauses whose denoted circumstance
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
219
 occured, are executed in the order the clauses appear.
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
220
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
221
 ABORT-FLAG is the name of a variable that will be bound to T in
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
222
 CLAUSES if the PROTECTED-FORM aborted preemptively, and to NIL
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
223
 otherwise.
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
224
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
225
 Examples:
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
226
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
227
   (unwind-protect-case ()
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
228
        (protected-form)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
229
      (:normal (format t \"This is only evaluated if PROTECTED-FORM executed normally.~%\"))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
230
      (:abort  (format t \"This is only evaluated if PROTECTED-FORM aborted preemptively.~%\"))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
231
      (:always (format t \"This is evaluated in either case.~%\")))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
232
 
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
233
   (unwind-protect-case (aborted-p)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
234
        (protected-form)
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
235
      (:always (perform-cleanup-if aborted-p)))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
236
 "
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
237
   (check-type abort-flag (or null symbol))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
238
   (let ((gflag (gensym "FLAG+")))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
239
     `(let ((,gflag t))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
240
        (unwind-protect (multiple-value-prog1 ,protected-form (setf ,gflag nil))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
241
 	 (let ,(and abort-flag `((,abort-flag ,gflag)))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
242
 	   ,@(loop for (cleanup-kind . forms) in clauses
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
243
 		   collect (ecase cleanup-kind
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
244
 			     (:normal `(when (not ,gflag) ,@forms))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
245
 			     (:abort  `(when ,gflag ,@forms))
8b10eabe89dd std/tests, clap tweaks
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
246
 			     (:always `(progn ,@forms)))))))))