chiark / gitweb /
Fix to load shared libraries from default locations in CMUCL and CLISP
[clg] / tools / autoexport.lisp
CommitLineData
560af5c5 1(defpackage "AUTOEXPORT"
2 (:use "COMMON-LISP")
3 (:export "LIST-AUTOEXPORTED-SYMBOLS" "LIST-AUTOEXPORTED-SYMBOLS-IN-FILE"
f3808390 4 "DEFEXPORT" "EXPORT-FROM-FILE" "EXPORT-FROM-FILES" "INTERNAL"
5 "WITH-EXPORT-HANDLERS" "EXPORT-HANDLER-MAKUNBOUND"
db7a1e77 6 "EXPORT-DEFCLASS-FORM" "EXPORT-FROM-SYSTEM"))
560af5c5 7
8(in-package "AUTOEXPORT")
9
10(declaim (special *internal*))
11
12(defvar *export-handlers* (make-hash-table))
13(defvar *noexport-prefix* #\%)
14
15(defmacro defexport (operator lambda-list &body body)
16 `(setf
17 (gethash ',operator *export-handlers*)
18 #'(lambda ,lambda-list
19 ,@body)))
20
21(defmacro internal (&rest symbols)
22 (declare (ignore symbols))
23 nil)
24
f3808390 25(defun export-handler-makunbound (handler)
26 (remhash handler *export-handlers*))
27
560af5c5 28(defun list-autoexported-symbols (form)
29 (let ((handler (gethash (first form) *export-handlers*)))
30 (when handler
31 (let ((export (apply handler (cdr form))))
32 (delete-if
33 #'(lambda (symbol)
34 (char= (char (string symbol) 0) *noexport-prefix*))
35 (if (atom export)
36 (list export)
37 export))))))
38
39(defun export-fname (fname)
40 (if (atom fname)
41 fname
42 (second fname)))
43
44(defun list-autoexported-symbols-in-file (file)
45 (let ((*internal* nil))
46 (declare (special *internal*))
47 (with-open-file (in file)
48 (labels ((read-file (in)
49 (let ((form (read in nil nil)))
50 (when form
51 (delete-if
52 #'(lambda (symbol)
53 (member symbol *internal*))
54 (delete-duplicates
55 (nconc
56 (list-autoexported-symbols form)
57 (read-file in))))))))
58 (read-file in)))))
59
f3808390 60(defmacro export-from-file (file &optional package)
61 (if package
62 `(export ',(list-autoexported-symbols-in-file file) ,package)
63 `(export ',(list-autoexported-symbols-in-file file))))
64
65(defmacro export-from-files (files &optional package)
66 `(progn
67 ,@(loop for file in files collect `(export-from-file ,file ,package))))
68
db7a1e77 69(defmacro export-from-system (&optional package)
70 (let ((depends-on (cdar (asdf:component-depends-on asdf:*operation* asdf:*component*))))
71 `(progn
72 ,@(loop
73 for component in depends-on
74 as pathname = (asdf:component-pathname
75 (asdf:find-component asdf:*system* component))
76 collect `(export-from-file ,pathname ,package)))))
77
f3808390 78(defun copy-hash-table (hash-table)
79 (let ((new-hash-table (make-hash-table
80 :test (hash-table-test hash-table)
81 :size (hash-table-size hash-table))))
82 (maphash
83 #'(lambda (key value)
84 (setf (gethash key new-hash-table) value))
85 hash-table)
86 new-hash-table))
87
88(defmacro with-export-handlers (&body body)
89 `(let ((*export-handlers* (copy-hash-table *export-handlers*)))
90 ,@body))
91
560af5c5 92
93;;;; Exporting standard forms
94
95(defexport defun (fname &rest rest)
96 (declare (ignore rest))
97 (export-fname fname))
98
99(defexport defvar (name &rest rest)
100 (declare (ignore rest))
101 name)
102
103(defexport defconstant (name &rest rest)
104 (declare (ignore rest))
105 name)
106
107(defexport defparameter (name &rest rest)
108 (declare (ignore rest))
109 name)
110
111(defexport defmacro (name &rest rest)
112 (declare (ignore rest))
113 name)
114
115(defexport deftype (name &rest rest)
116 (declare (ignore rest))
117 name)
118
f3808390 119(defun export-defclass-form (class slotdefs &optional (export-slots-p t))
560af5c5 120 (cons
121 class
aee2ecd4 122 (apply #'nconc
123 (map 'list
560af5c5 124 #'(lambda (slotdef)
125 (if (symbolp slotdef)
126 (list slotdef)
127 (destructuring-bind
128 (name &key reader writer accessor &allow-other-keys) slotdef
f3808390 129 (delete nil (list (when export-slots-p name) reader (export-fname writer) accessor)))))
560af5c5 130 slotdefs))))
131
aee2ecd4 132(defexport defclass (class superclasses &optional slotdefs &rest options)
133 (declare (ignore superclasses options))
134 (export-defclass-form class slotdefs))
135
136(defexport define-condition (class superclasses &optional slotdefs &rest options)
137 (declare (ignore superclasses options))
138 (export-defclass-form class slotdefs))
139
560af5c5 140(defexport defgeneric (fname &rest args)
141 (declare (ignore args))
142 (export-fname fname))
143
f3808390 144;; (defexport defmethod (name &rest rest)
145;; (declare (ignore rest))
146;; name)
573086fb 147
560af5c5 148(defexport progn (&rest body)
149 (apply #'nconc (map 'list #'list-autoexported-symbols body)))
150
151(defexport eval-when (case &rest body)
152 (declare (ignore case))
153 (apply #'nconc (map 'list #'list-autoexported-symbols body)))
154
155(defexport internal (&rest symbols)
156 (setq *internal* (nconc *internal* symbols))
157 nil)
158