/[slime]/slime/swank-loader.lisp
ViewVC logotype

Contents of /slime/swank-loader.lisp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.112 - (hide annotations)
Sun Dec 4 14:54:46 2011 UTC (2 years, 4 months ago) by heller
Branch: MAIN
Changes since 1.111: +1 -0 lines
* swank-loader.lisp (*contribs*): Add swank-mrepl.
1 heller 1.81 ;;;; -*- indent-tabs-mode: nil -*-
2 jbielman 1.1 ;;;
3     ;;; swank-loader.lisp --- Compile and load the Slime backend.
4     ;;;
5     ;;; Created 2003, James Bielman <jamesjb@jamesjb.com>
6     ;;;
7     ;;; This code has been placed in the Public Domain. All warranties
8     ;;; are disclaimed.
9     ;;;
10    
11 heller 1.55 ;; If you want customize the source- or fasl-directory you can set
12     ;; swank-loader:*source-directory* resp. swank-loader:*fasl-directory*
13     ;; before loading this files. (you also need to create the
14     ;; swank-loader package.)
15     ;; E.g.:
16     ;;
17 heller 1.57 ;; (make-package :swank-loader)
18 heller 1.55 ;; (defparameter swank-loader::*fasl-directory* "/tmp/fasl/")
19     ;; (load ".../swank-loader.lisp")
20    
21 heller 1.11 (cl:defpackage :swank-loader
22 heller 1.54 (:use :cl)
23 heller 1.82 (:export :init
24 heller 1.87 :dump-image
25 heller 1.55 :*source-directory*
26     :*fasl-directory*))
27 heller 1.4
28 heller 1.52 (cl:in-package :swank-loader)
29 jbielman 1.1
30 heller 1.62 (defvar *source-directory*
31     (make-pathname :name nil :type nil
32 heller 1.57 :defaults (or *load-pathname* *default-pathname-defaults*))
33 heller 1.56 "The directory where to look for the source.")
34    
35 heller 1.83 (defparameter *sysdep-files*
36 heller 1.82 #+cmu '(swank-source-path-parser swank-source-file-cache swank-cmucl)
37     #+scl '(swank-source-path-parser swank-source-file-cache swank-scl)
38     #+sbcl '(swank-source-path-parser swank-source-file-cache
39     swank-sbcl swank-gray)
40 heller 1.91 #+clozure '(metering swank-ccl swank-gray)
41 heller 1.82 #+lispworks '(swank-lispworks swank-gray)
42     #+allegro '(swank-allegro swank-gray)
43     #+clisp '(xref metering swank-clisp swank-gray)
44     #+armedbear '(swank-abcl)
45     #+cormanlisp '(swank-corman swank-gray)
46 trittweiler 1.99 #+ecl '(swank-source-path-parser swank-source-file-cache
47     swank-ecl swank-gray))
48 jbielman 1.1
49 pseibel 1.39 (defparameter *implementation-features*
50 heller 1.91 '(:allegro :lispworks :sbcl :clozure :cmu :clisp :ccl :corman :cormanlisp
51 dcrosher 1.53 :armedbear :gcl :ecl :scl))
52 pseibel 1.39
53     (defparameter *os-features*
54 dcrosher 1.53 '(:macosx :linux :windows :mswindows :win32 :solaris :darwin :sunos :hpux
55     :unix))
56 pseibel 1.39
57     (defparameter *architecture-features*
58 heller 1.106 '(:powerpc :ppc :x86 :x86-64 :x86_64 :amd64 :i686 :i586 :i486 :pc386 :iapx386
59 sboukarev 1.109 :sparc64 :sparc :hppa64 :hppa :arm
60 mevenson 1.105 :pentium3 :pentium4
61     :java-1.4 :java-1.5 :java-1.6 :java-1.7))
62 pseibel 1.39
63 sboukarev 1.103 (defun q (s) (read-from-string s))
64    
65 trittweiler 1.101 #+ecl
66     (defun ecl-version-string ()
67 sboukarev 1.103 (format nil "~A~@[-~A~]"
68     (lisp-implementation-version)
69     (when (find-symbol "LISP-IMPLEMENTATION-VCS-ID" :ext)
70     (let ((vcs-id (funcall (q "ext:lisp-implementation-vcs-id"))))
71     (when (>= (length vcs-id) 8)
72     (subseq vcs-id 0 8))))))
73 trittweiler 1.101
74 heller 1.45 (defun lisp-version-string ()
75 heller 1.91 #+(or clozure cmu) (substitute-if #\_ (lambda (x) (find x " /"))
76     (lisp-implementation-version))
77 trittweiler 1.101 #+(or cormanlisp scl sbcl) (lisp-implementation-version)
78 heller 1.45 #+lispworks (lisp-implementation-version)
79 heller 1.92 #+allegro (format nil "~A~A~A~A"
80 mkoeppe 1.61 excl::*common-lisp-version-number*
81     (if (eq 'h 'H) "A" "M") ; ANSI vs MoDeRn
82 heller 1.92 (if (member :64bit *features*) "-64bit" "")
83     (excl:ics-target-case
84     (:-ics "")
85     (:+ics "-ics")))
86 heller 1.45 #+clisp (let ((s (lisp-implementation-version)))
87     (subseq s 0 (position #\space s)))
88 trittweiler 1.101 #+armedbear (lisp-implementation-version)
89     #+ecl (ecl-version-string) )
90 heller 1.62
91 heller 1.78 (defun unique-dir-name ()
92 pseibel 1.39 "Return a name that can be used as a directory name that is
93     unique to a Lisp implementation, Lisp implementation version,
94     operating system, and hardware architecture."
95     (flet ((first-of (features)
96     (loop for f in features
97 heller 1.45 when (find f *features*) return it))
98     (maybe-warn (value fstring &rest args)
99     (cond (value)
100     (t (apply #'warn fstring args)
101     "unknown"))))
102     (let ((lisp (maybe-warn (first-of *implementation-features*)
103 heller 1.62 "No implementation feature found in ~a."
104 heller 1.45 *implementation-features*))
105     (os (maybe-warn (first-of *os-features*)
106     "No os feature found in ~a." *os-features*))
107     (arch (maybe-warn (first-of *architecture-features*)
108     "No architecture feature found in ~a."
109     *architecture-features*))
110     (version (maybe-warn (lisp-version-string)
111     "Don't know how to get Lisp ~
112     implementation version.")))
113     (format nil "~(~@{~a~^-~}~)" lisp version os arch))))
114 heller 1.17
115 jbielman 1.1 (defun file-newer-p (new-file old-file)
116     "Returns true if NEW-FILE is newer than OLD-FILE."
117     (> (file-write-date new-file) (file-write-date old-file)))
118    
119 heller 1.56 (defun slime-version-string ()
120     "Return a string identifying the SLIME version.
121     Return nil if nothing appropriate is available."
122 heller 1.63 (with-open-file (s (merge-pathnames "ChangeLog" *source-directory*)
123     :if-does-not-exist nil)
124     (and s (symbol-name (read s)))))
125 heller 1.56
126 heller 1.78 (defun default-fasl-dir ()
127 heller 1.110 (merge-pathnames
128     (make-pathname
129     :directory `(:relative ".slime" "fasl"
130     ,@(if (slime-version-string) (list (slime-version-string)))
131     ,(unique-dir-name)))
132     (user-homedir-pathname)))
133 heller 1.54
134 trittweiler 1.100 (defvar *fasl-directory* (default-fasl-dir)
135     "The directory where fasl files should be placed.")
136    
137 heller 1.78 (defun binary-pathname (src-pathname binary-dir)
138     "Return the pathname where SRC-PATHNAME's binary should be compiled."
139     (let ((cfp (compile-file-pathname src-pathname)))
140 heller 1.54 (merge-pathnames (make-pathname :name (pathname-name cfp)
141     :type (pathname-type cfp))
142 heller 1.78 binary-dir)))
143 heller 1.54
144 trittweiler 1.100 (defun handle-swank-load-error (condition context pathname)
145     (fresh-line *error-output*)
146 heller 1.64 (pprint-logical-block (*error-output* () :per-line-prefix ";; ")
147     (format *error-output*
148 trittweiler 1.100 "~%Error while ~A ~A:~% ~A~%Aborting.~%"
149     context pathname condition))
150     (when (equal (directory-namestring pathname)
151     (directory-namestring *fasl-directory*))
152     (ignore-errors (delete-file pathname)))
153 heller 1.62 (abort))
154    
155 heller 1.78 (defun compile-files (files fasl-dir load)
156 heller 1.79 "Compile each file in FILES if the source is newer than its
157 heller 1.80 corresponding binary, or the file preceding it was recompiled.
158     If LOAD is true, load the fasl file."
159 trittweiler 1.100 (let ((needs-recompile nil)
160     (state :unknown))
161 heller 1.78 (dolist (src files)
162     (let ((dest (binary-pathname src fasl-dir)))
163 heller 1.64 (handler-case
164     (progn
165     (when (or needs-recompile
166 heller 1.78 (not (probe-file dest))
167     (file-newer-p src dest))
168 trittweiler 1.100 (ensure-directories-exist dest)
169     ;; need to recompile SRC, so we'll need to recompile
170     ;; everything after this too.
171 heller 1.64 (setq needs-recompile t)
172 trittweiler 1.100 (setq state :compile)
173     (or (compile-file src :output-file dest :print nil :verbose t)
174     ;; An implementation may not necessarily signal a
175     ;; condition itself when COMPILE-FILE fails (e.g. ECL)
176     (error "COMPILE-FILE returned NIL.")))
177 heller 1.66 (when load
178 trittweiler 1.100 (setq state :load)
179 heller 1.78 (load dest :verbose t)))
180 heller 1.64 ;; Fail as early as possible
181     (serious-condition (c)
182 trittweiler 1.100 (ecase state
183     (:compile (handle-swank-load-error c "compiling" src))
184     (:load (handle-swank-load-error c "loading" dest))
185     (:unknown (handle-swank-load-error c "???ing" src)))))))))
186 jbielman 1.1
187 trittweiler 1.99 #+(or cormanlisp)
188 heller 1.78 (defun compile-files (files fasl-dir load)
189 trittweiler 1.99 "Corman Lisp has trouble with compiled files."
190 heller 1.78 (declare (ignore fasl-dir))
191 trittweiler 1.74 (when load
192     (dolist (file files)
193     (load file :verbose t)
194     (force-output))))
195 ewiborg 1.49
196 mbaringer 1.38 (defun load-user-init-file ()
197     "Load the user init file, return NIL if it does not exist."
198     (load (merge-pathnames (user-homedir-pathname)
199     (make-pathname :name ".swank" :type "lisp"))
200     :if-does-not-exist nil))
201    
202 heller 1.78 (defun load-site-init-file (dir)
203 mbaringer 1.38 (load (make-pathname :name "site-init" :type "lisp"
204 heller 1.78 :defaults dir)
205 mbaringer 1.38 :if-does-not-exist nil))
206    
207 heller 1.78 (defun src-files (names src-dir)
208 heller 1.54 (mapcar (lambda (name)
209 heller 1.66 (make-pathname :name (string-downcase name) :type "lisp"
210     :defaults src-dir))
211     names))
212    
213 trittweiler 1.99 (defvar *swank-files*
214     `(swank-backend ,@*sysdep-files* swank-match swank-rpc swank))
215 heller 1.55
216 trittweiler 1.99 (defvar *contribs*
217 heller 1.111 '(swank-util
218     swank-c-p-c swank-arglists swank-fuzzy
219 trittweiler 1.99 swank-fancy-inspector
220     swank-presentations swank-presentation-streams
221     #+(or asdf sbcl ecl) swank-asdf
222     swank-package-fu
223     swank-hyperdoc
224 heller 1.104 #+sbcl swank-sbcl-exts
225 heller 1.112 swank-mrepl
226 trittweiler 1.99 )
227 heller 1.66 "List of names for contrib modules.")
228    
229     (defun append-dir (absolute name)
230     (merge-pathnames
231     (make-pathname :directory `(:relative ,name) :defaults absolute)
232     absolute))
233    
234 heller 1.78 (defun contrib-dir (base-dir)
235     (append-dir base-dir "contrib"))
236 heller 1.66
237 heller 1.78 (defun load-swank (&key (src-dir *source-directory*)
238 trittweiler 1.100 (fasl-dir *fasl-directory*))
239 heller 1.84 (compile-files (src-files *swank-files* src-dir) fasl-dir t)
240     (funcall (q "swank::before-init")
241     (slime-version-string)
242     (list (contrib-dir fasl-dir)
243     (contrib-dir src-dir))))
244 heller 1.78
245     (defun compile-contribs (&key (src-dir (contrib-dir *source-directory*))
246 heller 1.82 (fasl-dir (contrib-dir *fasl-directory*))
247     load)
248     (compile-files (src-files *contribs* src-dir) fasl-dir load))
249 heller 1.84
250 heller 1.82 (defun loadup ()
251     (load-swank)
252     (compile-contribs :load t))
253 heller 1.78
254     (defun setup ()
255 heller 1.84 (load-site-init-file *source-directory*)
256     (load-user-init-file)
257 sboukarev 1.94 (when (#-clisp probe-file
258     #+clisp ext:probe-directory
259     (contrib-dir *source-directory*))
260 heller 1.93 (eval `(pushnew 'compile-contribs ,(q "swank::*after-init-hook*"))))
261 heller 1.84 (funcall (q "swank::init")))
262 heller 1.78
263 heller 1.82 (defun init (&key delete reload load-contribs (setup t))
264 heller 1.90 "Load SWANK and initialize some global variables.
265     If DELETE is true, delete any existing SWANK packages.
266     If RELOAD is true, reload SWANK, even if the SWANK package already exists.
267     If LOAD-CONTRIBS is true, load all contribs
268     If SETUP is true, load user init files and initialize some
269     global variabes in SWANK."
270 heller 1.78 (when (and delete (find-package :swank))
271     (mapc #'delete-package '(:swank :swank-io-package :swank-backend)))
272 heller 1.81 (cond ((or (not (find-package :swank)) reload)
273     (load-swank))
274     (t
275     (warn "Not reloading SWANK. Package already exists.")))
276 heller 1.82 (when load-contribs
277     (compile-contribs :load t))
278     (when setup
279     (setup)))
280 heller 1.88
281     (defun dump-image (filename)
282     (init :setup nil)
283     (funcall (q "swank-backend:save-image") filename))

  ViewVC Help
Powered by ViewVC 1.1.5