0.pre7.98:
[sbcl.git] / src / cold / set-up-cold-packages.lisp
1 ;;;; This software is part of the SBCL system. See the README file for
2 ;;;; more information.
3 ;;;;
4 ;;;; This software is derived from the CMU CL system, which was
5 ;;;; written at Carnegie Mellon University and released into the
6 ;;;; public domain. The software is in the public domain and is
7 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
8 ;;;; files for more information.
9
10 (in-package "SB-COLD")
11
12 ;;; an entry in the table which describes the non-standard part (i.e. not
13 ;;; CL/CL-USER/KEYWORD) of the package structure of the SBCL system
14 ;;;
15 ;;; We make no attempt to be fully general; our table doesn't need to be
16 ;;; able to express features which we don't happen to use.
17 (export '(package-data
18           package-data-name
19           package-data-nicknames
20           package-data-export
21           package-data-reexport
22           package-data-import-from
23           package-data-use))
24 (defstruct package-data
25   ;; a string designator for the package name
26   (name (error "missing PACKAGE-DATA-NAME datum"))
27   ;; a doc string
28   (doc (error "missing PACKAGE-DOC datum"))
29   ;; a list of string designators for package nicknames
30   nicknames
31   ;; a tree containing names for exported symbols which'll be set up at package
32   ;; creation time, and NILs, which are ignored. (This is a tree in order to
33   ;; allow constructs like '("ENOSPC" #!+LINUX ("EDQUOT" "EISNAM" "ENAVAIL"
34   ;; "EREMOTEIO")) to be used in initialization. NIL entries in the tree are
35   ;; ignored for the same reason of notational convenience.)
36   export
37   ;; a list of string designators for exported symbols which don't necessarily
38   ;; originate in this package (so their EXPORT operations should be handled
39   ;; after USE operations have been done, so that duplicates aren't created)
40   reexport
41   ;; a list of sublists describing imports. Each sublist has the format as an
42   ;; IMPORT-FROM list in DEFPACKAGE: the first element is the name of the
43   ;; package to import from, and the remaining elements are the names of
44   ;; symbols to import.
45   import-from
46   ;; a tree of string designators for package names of other packages
47   ;; which this package uses
48   use)
49
50 (let ((package-data-list (read-from-file "package-data-list.lisp-expr")))
51
52     ;; Build all packages that we need, and initialize them as far as we
53     ;; can without referring to any other packages.
54     (dolist (package-data package-data-list)
55       (let* ((package (make-package
56                        (package-data-name package-data)
57                        :nicknames (package-data-nicknames package-data)
58                        :use nil)))
59         #-clisp ; As of "2.27 (released 2001-07-17) (built 3215971334)"
60                 ; CLISP didn't support DOCUMENTATION on PACKAGE values.
61         (progn
62           #!+sb-doc (setf (documentation package t)
63                           (package-data-doc package-data)))
64         ;; Walk the tree of exported names, exporting each name.
65         (labels ((recurse (tree)
66                    (etypecase tree
67                      ;; FIXME: The comments above say the structure is a tree,
68                      ;; but here we're sleazily treating it as though
69                      ;; dotted lists never occur. Replace this LIST case
70                      ;; with separate NULL and CONS cases to fix this.
71                      (list (mapc #'recurse tree))
72                      (string (export (intern tree package) package)))))
73           (recurse (package-data-export package-data)))))
74
75     ;; Now that all packages exist, we can set up package-package
76     ;; references.
77     (dolist (package-data package-data-list)
78       (use-package (package-data-use package-data)
79                    (package-data-name package-data))
80       (dolist (sublist (package-data-import-from package-data))
81         (let* ((from-package (first sublist))
82                (symbol-names (rest sublist))
83                (symbols (mapcar (lambda (name)
84                                   ;; old way, broke for importing symbols
85                                   ;; like SB!C::DEBUG-SOURCE-FORM into
86                                   ;; SB!DI -- WHN 19990714
87                                   #+nil
88                                   (let ((s (find-symbol name from-package)))
89                                     (unless s
90                                       (error "can't find ~S in ~S"
91                                              name
92                                              from-package))
93                                     s)
94                                   ;; new way, works for SB!DI stuff
95                                   ;; -- WHN 19990714
96                                   (intern name from-package))
97                                 symbol-names)))
98           (import symbols (package-data-name package-data)))))
99
100     ;; Now that all package-package references exist, we can handle
101     ;; REEXPORT operations. (We have to wait until now because they
102     ;; interact with USE operations.) KLUDGE: This code doesn't detect
103     ;; dependencies and do exports in proper order to work around them, so
104     ;; it could break randomly (with build-time errors, not with silent
105     ;; errors or runtime errors) if multiple levels of re-exportation are
106     ;; used, e.g. package A exports X, package B uses A and reexports X,
107     ;; and package C uses B and reexports X. That doesn't seem to be an
108     ;; issue in the current code, and it's hard to see why anyone would
109     ;; want to do it, and it should be straightforward (though tedious) to
110     ;; extend the code here to deal with that if it ever becomes necessary.
111     (dolist (package-data package-data-list)
112       (let ((package (find-package (package-data-name package-data))))
113         (dolist (symbol-name (package-data-reexport package-data))
114           (multiple-value-bind (symbol status)
115               (find-symbol symbol-name package)
116             (unless status
117               (error "No symbol named ~S is accessible in ~S."
118                      symbol-name
119                      package))
120             (when (eq (symbol-package symbol) package)
121               (error "~S is not inherited/imported, but native to ~S."
122                      symbol-name
123                      package))
124             (export symbol package))))))