changelog shortlog graph tags branches changeset files file revisions raw help

Mercurial > core / annotate lisp/lib/dat/mime.lisp

changeset 698: 96958d3eb5b0
parent: da17bf652e48
author: Richard Westhaver <ellis@rwest.io>
date: Fri, 04 Oct 2024 22:04:59 -0400
permissions: -rw-r--r--
description: fixes
435
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
1
 ;;; mime.lisp --- MIME Database
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
2
 
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
3
 ;; 
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
4
 
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
5
 ;;; Code:
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
6
 (in-package :dat/mime)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
7
 
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
8
 (defun read-mime-match-offset (offset)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
9
   "Mime offsets are encoded as single int or range N:N. Returns an integer of a
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
10
 cons of two ints."
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
11
   (let ((len (length offset)))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
12
     (if (= 1 len)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
13
         (parse-integer offset)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
14
         (multiple-value-bind (int1 pos) (parse-integer offset :junk-allowed t)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
15
           (if (>= pos len)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
16
               int1
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
17
               (cons int1 (parse-integer offset :start (1+ pos))))))))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
18
 
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
19
 (defstruct mime-magic offset value type)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
20
 
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
21
 (defstruct mime-type type name superclasses glob magic)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
22
 
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
23
 (declaim (inline mime-type))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
24
 (defun mime-type (mime-type)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
25
   (mime-type-type mime-type))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
26
 
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
27
 (defun load-mime-info (&optional (path #p"/usr/share/mime/packages/freedesktop.org.xml"))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
28
   (let ((types (xmlrep-find-child-tags "mime-type"
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
29
                                        (xml-parse (with-open-file (file path)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
30
                                                     (with-output-to-string (st)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
31
                                                       (loop for l = (read-line file nil)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
32
                                                             while l
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
33
                                                             do (std:println l st)))))))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
34
         (mime-types))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
35
     ;; assumes all children have a single attribute - TYPE
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
36
     (dolist (mime types mime-types)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
37
       (let ((type (xmlrep-attrib-value "type" mime)))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
38
         (push (make-mime-type :type type
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
39
                               :name (car (split-sequence #\/ type :count 1 :from-end t))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
40
                               :superclasses
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
41
                               (mapcar (lambda (x) (xmlrep-attrib-value "type" x))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
42
                                       (xmlrep-find-child-tags "sub-class-of" mime))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
43
                               :glob
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
44
                               (mapcar (lambda (x) (xmlrep-attrib-value "pattern" x))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
45
                                       (xmlrep-find-child-tags "glob" mime))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
46
                               :magic
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
47
                               (loop for magic in (xmlrep-find-child-tags "magic" mime)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
48
                                     while magic
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
49
                                     collect (loop for match in (xmlrep-find-child-tags "match" magic)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
50
                                                   collect (make-mime-magic
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
51
                                                            :offset (read-mime-match-offset
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
52
                                                                     (xmlrep-attrib-value "offset" match))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
53
                                                            :value (xmlrep-attrib-value "value" match)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
54
                                                            :type (xmlrep-attrib-value "type" match)))))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
55
             mime-types)))))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
56
 
514
da17bf652e48 tests and light feature annotations to support darwin (no uring, no mime types)
Richard Westhaver <ellis@rwest.io>
parents: 435
diff changeset
57
 (defvar *mime-types* #+linux (load-mime-info))
435
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
58
 
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
59
 (defvar *mime-database*
514
da17bf652e48 tests and light feature annotations to support darwin (no uring, no mime types)
Richard Westhaver <ellis@rwest.io>
parents: 435
diff changeset
60
   #+linux
435
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
61
   (let ((tbl (make-hash-table :size (length *mime-types*) :test 'equal)))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
62
     (dolist (mime *mime-types* tbl)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
63
       (setf (gethash (mime-type mime) tbl) mime))))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
64
 
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
65
 (defvar *mime-db*
514
da17bf652e48 tests and light feature annotations to support darwin (no uring, no mime types)
Richard Westhaver <ellis@rwest.io>
parents: 435
diff changeset
66
   #+linux
435
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
67
   (let ((tbl (make-hash-table :test 'equal))) ;; at least as large as *MIME-DATABASE*
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
68
     (dolist (mime *mime-types* tbl)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
69
       (when-let ((patterns (mime-type-glob mime)))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
70
         (dolist (p patterns)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
71
           (when (wild-pathname-p p) ;; drop '.*'
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
72
             (setf p (subseq p 2)))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
73
           (setf (gethash p tbl) (mime-type mime)))))))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
74
 
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
75
 (defun get-mime (value)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
76
   "Return the name of a MIME-TYPE from *MIME-DB*. The resulting value is a string
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
77
 which can be passed to MIME* to get the actual object from *MIME-DATABASE*."
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
78
   (gethash value *mime-db*))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
79
 
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
80
 (defun get-mime* (value)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
81
   "Return a MIME-TYPE from *MIME-DATABASE*."
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
82
   (gethash value *mime-database*))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
83
 
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
84
 ;; from TRIVIAL-MIMES
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
85
 (defun mime-probe (pathname)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
86
   "Attempts to get the mime-type through a call to the FILE shell utility.
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
87
 If the file does not exist or the platform is not unix, NIL is returned."
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
88
   #+unix
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
89
   (when (probe-file pathname)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
90
     (let ((output (uiop:run-program (list "file" #+darwin "-bI" #-darwin "-bi"
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
91
                                                  (uiop:native-namestring pathname))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
92
                                     :output :string)))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
93
       (with-output-to-string (mime)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
94
         (loop for c across output
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
95
               for char = (char-downcase c)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
96
               ;; Allowed characters as per RFC6383
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
97
               while (find char "abcdefghijklmnopqrstuvwxyz0123456789!#$&-^_.+/")
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
98
               do (write-char char mime)))))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
99
   #-unix
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
100
   NIL)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
101
 
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
102
 (defun mime-lookup (path)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
103
   (get-mime (pathname-type path)))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
104
 
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
105
 (defun mime (path &optional (default "application/octet-stream"))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
106
   (or (mime-lookup path)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
107
       (mime-probe path)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
108
       default))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
109
 
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
110
 ;; TODO 2024-06-11: from TRIVIAL-MIMES
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
111
 (defun mime-equal (m1 m2)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
112
   (or (equal "*" m1)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
113
       (equal "*" m2)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
114
       (equal "*/*" m1)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
115
       (equal "*/*" m2)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
116
       (destructuring-bind (type1 subtype1 &rest parameters1)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
117
           (uiop:split-string m1 :separator '(#\/ #\;))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
118
         (declare (ignorable parameters1))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
119
         (destructuring-bind (type2 subtype2 &rest parameters2)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
120
             (uiop:split-string m2 :separator '(#\/ #\;))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
121
           (declare (ignorable parameters2))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
122
           (cond
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
123
             ((or (equal "*" subtype1)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
124
                  (equal "*" subtype2)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
125
                  (equal "" subtype1)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
126
                  (equal "" subtype2))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
127
              (string-equal type1 type2))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
128
             ((string-equal type1 type2)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
129
              (string-equal subtype1 subtype2))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
130
             (t nil))))))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
131
 
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
132
 (defmacro mime-case (file &body cases)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
133
   "A case-like macro that works with MIME type of FILE.
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
134
 
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
135
 Otherwise clause is the last clause that starts with T or OTHERWISE,.
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
136
 
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
137
 Example:
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
138
 \(mime-case #p\"~/CHANGES.txt\"
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
139
   ((\"application/json\" \"application/*\") \"Something opaque...\")
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
140
   (\"text/plain\" \"That's a plaintext file :D\")
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
141
   (t \"I don't know this type!\"))"
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
142
   (let ((mime (gensym "mime")))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
143
     `(let ((,mime (mime ,file)))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
144
        (cond
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
145
          ,@(loop for ((mimes . body) . rest) on cases
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
146
                  when (member mimes '(T OTHERWISE))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
147
                    collect `(t ,@body) into clauses
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
148
                    and do (if rest
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
149
                               (warn "Clauses after T and OTHERWISE are not reachable.")
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
150
                               (return clauses))
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
151
                  collect `((member ,mime (list ,@(uiop:ensure-list mimes)) :test #'mime-equal)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
152
                            ,@body)
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
153
                    into clauses
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
154
                  finally (return clauses))))))