Mercurial > hg > xemacs-beta
comparison lisp/setup-paths.el @ 265:8efd647ea9ca r20-5b31
Import from CVS: tag r20-5b31
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:25:37 +0200 |
parents | |
children | 966663fcf606 |
comparison
equal
deleted
inserted
replaced
264:682d2a9d41a5 | 265:8efd647ea9ca |
---|---|
1 ;;; setup-paths.el --- setup various XEmacs paths | |
2 | |
3 ;; Copyright (C) 1985-1986, 1990, 1992-1997 Free Software Foundation, Inc. | |
4 ;; Copyright (c) 1993, 1994 Sun Microsystems, Inc. | |
5 ;; Copyright (C) 1995 Board of Trustees, University of Illinois | |
6 | |
7 ;; Author: Mike Sperber <sperber@informatik.uni-tuebingen.de> | |
8 ;; Maintainer: XEmacs Development Team | |
9 ;; Keywords: internal, dumped | |
10 | |
11 ;; This file is part of XEmacs. | |
12 | |
13 ;; XEmacs is free software; you can redistribute it and/or modify it | |
14 ;; under the terms of the GNU General Public License as published by | |
15 ;; the Free Software Foundation; either version 2, or (at your option) | |
16 ;; any later version. | |
17 | |
18 ;; XEmacs is distributed in the hope that it will be useful, but | |
19 ;; WITHOUT ANY WARRANTY; without even the implied warranty of | |
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
21 ;; General Public License for more details. | |
22 | |
23 ;; You should have received a copy of the GNU General Public License | |
24 ;; along with XEmacs; see the file COPYING. If not, write to the | |
25 ;; Free Software Foundation, 59 Temple Place - Suite 330, | |
26 ;; Boston, MA 02111-1307, USA. | |
27 | |
28 ;;; Synched up with: Not in FSF. | |
29 | |
30 ;;; Commentary: | |
31 | |
32 ;; This file is dumped with XEmacs. | |
33 | |
34 ;; This file contains the machinery necessary to find the various | |
35 ;; paths into the XEmacs hierarchy. | |
36 | |
37 (defvar paths-version-control-bases '("RCS" "CVS" "SCCS") | |
38 "File bases associated with version control.") | |
39 | |
40 (defun paths-find-recursive-path (directories &optional exclude) | |
41 "Return a list of the directory hierarchy underneath DIRECTORIES. | |
42 The returned list is sorted by pre-order and lexicographically." | |
43 (let ((path '())) | |
44 (while directories | |
45 (let ((directory (file-name-as-directory | |
46 (expand-file-name | |
47 (car directories))))) | |
48 (if (file-directory-p directory) | |
49 (let ((raw-dirs (directory-files directory nil "^[^-.]" nil 'dirs-only)) | |
50 (reverse-dirs '())) | |
51 | |
52 (while raw-dirs | |
53 (if (null (member (car raw-dirs) exclude)) | |
54 (setq reverse-dirs | |
55 (cons (expand-file-name (car raw-dirs) directory) | |
56 reverse-dirs))) | |
57 (setq raw-dirs (cdr raw-dirs))) | |
58 | |
59 (let ((sub-path | |
60 (paths-find-recursive-path (reverse reverse-dirs) exclude))) | |
61 (setq path (nconc path | |
62 (list directory) | |
63 sub-path)))))) | |
64 (setq directories (cdr directories))) | |
65 path)) | |
66 | |
67 (defun paths-find-recursive-load-path (directories) | |
68 "Construct a recursive load path underneath DIRECTORIES." | |
69 (paths-find-recursive-path directories paths-version-control-bases)) | |
70 | |
71 (defun paths-emacs-root-p (directory) | |
72 "Check if DIRECTORY is a plausible installation root for XEmacs." | |
73 (or | |
74 ;; installed | |
75 (and (boundp 'emacs-version) | |
76 (file-directory-p | |
77 (concat directory "lib/xemacs-" (construct-emacs-version)))) | |
78 ;; in-place | |
79 (and | |
80 (file-directory-p (concat directory "lib-src")) | |
81 (file-directory-p (concat directory "lisp")) | |
82 (file-directory-p (concat directory "src"))))) | |
83 | |
84 (defun paths-find-emacs-root | |
85 (invocation-directory invocation-name) | |
86 "Find the run-time root of XEmacs." | |
87 (let ((maybe-root-1 (file-name-as-directory | |
88 (expand-file-name ".." invocation-directory))) | |
89 (maybe-root-2 (file-name-as-directory | |
90 (expand-file-name "../.." invocation-directory)))) | |
91 (cond | |
92 ((paths-emacs-root-p maybe-root-1) | |
93 maybe-root-1) | |
94 ((paths-emacs-root-p maybe-root-2) | |
95 maybe-root-2) | |
96 (t | |
97 (let ((maybe-symlink (file-symlink-p (concat invocation-directory | |
98 invocation-name)))) | |
99 (if maybe-symlink | |
100 (let ((directory (file-name-directory maybe-symlink))) | |
101 (paths-find-emacs-root directory invocation-name)) | |
102 nil)))))) | |
103 | |
104 (defun paths-construct-emacs-directory (root suffix base) | |
105 "Construct a directory name within the XEmacs hierarchy." | |
106 (file-name-as-directory | |
107 (expand-file-name | |
108 (concat | |
109 (file-name-as-directory root) | |
110 suffix | |
111 base)))) | |
112 | |
113 (defun paths-find-emacs-directory (roots suffix base &optional envvar default) | |
114 "Find a directory in the XEmacs hierarchy. | |
115 ROOTS must be a list of installation roots. | |
116 SUFFIX is the subdirectory from there. | |
117 BASE is the base to look for. | |
118 ENVVAR is the name of the environment variable that might also | |
119 specify the directory. | |
120 DEFAULT is a fall-back value." | |
121 (let ((envvar-value (and envvar (getenv envvar)))) | |
122 (if (and envvar-value | |
123 (file-directory-p envvar-value)) | |
124 (file-name-as-directory envvar-value) | |
125 (catch 'gotcha | |
126 (while roots | |
127 (let* ((root (car roots)) | |
128 (path (paths-construct-emacs-directory root suffix base))) | |
129 ;; installed | |
130 (if (file-directory-p path) | |
131 (throw 'gotcha path) | |
132 (let ((path (paths-construct-emacs-directory root "" base))) | |
133 ;; in-place | |
134 (if (file-directory-p path) | |
135 (throw 'gotcha path))))) | |
136 (setq roots (cdr roots))) | |
137 (if (and default | |
138 (file-directory-p default)) | |
139 (file-name-as-directory default) | |
140 nil))))) | |
141 | |
142 (defun paths-find-site-directory (roots base &optional envvar default) | |
143 "Find a site-specific directory in the XEmacs hierarchy." | |
144 (paths-find-emacs-directory roots "lib/xemacs/" base envvar default)) | |
145 | |
146 (defun paths-find-version-directory (roots base &optional envvar default) | |
147 "Find a version-specific directory in the XEmacs hierarchy." | |
148 (paths-find-emacs-directory roots | |
149 (concat "lib/xemacs-" (construct-emacs-version) "/") | |
150 base | |
151 envvar default)) | |
152 | |
153 (defun paths-find-architecture-directory (roots base &optional envvar default) | |
154 "Find an architecture-specific directory in the XEmacs hierarchy." | |
155 (or | |
156 ;; from more to less specific | |
157 (paths-find-version-directory roots | |
158 (concat base system-configuration) | |
159 envvar default) | |
160 (paths-find-version-directory roots | |
161 system-configuration | |
162 envvar default) | |
163 (paths-find-version-directory roots | |
164 base | |
165 envvar default))) | |
166 | |
167 (defvar paths-path-emacs-version nil | |
168 "Emacs version as it appears in paths.") | |
169 | |
170 (defun construct-emacs-version () | |
171 "Construct the raw version number of XEmacs in the form XX.XX." | |
172 ;; emacs-version isn't available early, but we really don't care then | |
173 (if (null (boundp 'emacs-version)) | |
174 "" | |
175 (or paths-path-emacs-version ; cache | |
176 (progn | |
177 (string-match "\\`[^0-9]*\\([0-9]+\\.[0-9]+\\)" emacs-version) | |
178 (let ((version (substring emacs-version | |
179 (match-beginning 1) (match-end 1)))) | |
180 (if (string-match "(beta *\\([0-9]+\\))" emacs-version) | |
181 (setq version (concat version | |
182 "-b" | |
183 (substring emacs-version | |
184 (match-beginning 1) (match-end 1))))) | |
185 (setq paths-path-emacs-version version) | |
186 version))))) | |
187 | |
188 (defun paths-find-emacs-path (roots suffix base &optional envvar default) | |
189 "Find a path in the XEmacs hierarchy. | |
190 ROOTS must be a list of installation roots. | |
191 SUFFIX is the subdirectory from there. | |
192 BASE is the base to look for. | |
193 ENVVAR is the name of the environment variable that might also | |
194 specify the path. | |
195 DEFAULT is a fall-back value." | |
196 (let ((envvar-value (and envvar (getenv envvar)))) | |
197 (if (and (fboundp 'parse-colon-path) envvar-value) | |
198 (parse-colon-path envvar-value) | |
199 (let ((directory (paths-find-emacs-directory roots base suffix))) | |
200 (if (and directory (file-directory-p directory)) | |
201 (list directory) | |
202 (paths-directories-which-exist default)))))) | |
203 | |
204 (defun paths-directories-which-exist (directories) | |
205 "Return the directories among DIRECTORIES." | |
206 (let ((reverse-directories '())) | |
207 (while directories | |
208 (if (file-directory-p (car directories)) | |
209 (setq reverse-directories | |
210 (cons (car directories) | |
211 reverse-directories))) | |
212 (setq directories (cdr directories))) | |
213 (reverse reverse-directories))) | |
214 | |
215 (defun paths-find-site-path (roots base &optional envvar default) | |
216 "Find a path underneath the site hierarchy." | |
217 (paths-find-emacs-path roots "lib/xemacs/" base envvar default)) | |
218 | |
219 (defun paths-find-version-path (roots base &optional envvar default) | |
220 "Find a path underneath the site hierarchy." | |
221 (paths-find-emacs-path roots | |
222 (concat "lib/xemacs-" (construct-emacs-version) "/") | |
223 base | |
224 envvar default)) | |
225 | |
226 ; Packages are special ... | |
227 | |
228 (defun paths-find-package-path (roots) | |
229 "Construct the package path underneath installation roots ROOTS." | |
230 (let ((envvar-value (getenv "EMACSPACKAGEPATH"))) | |
231 (if (and (fboundp 'parse-colon-path) envvar-value) | |
232 (parse-colon-path envvar-value) | |
233 (let ((base-directory (paths-find-site-directory roots "packages"))) | |
234 (if base-directory | |
235 (let ((mule-directory (and (featurep 'mule) | |
236 (paths-find-site-directory roots | |
237 "mule-packages")))) | |
238 (append '("~/.xemacs/") | |
239 '(nil) | |
240 (and mule-directory | |
241 (list mule-directory)) | |
242 (list base-directory))) | |
243 configure-package-path))))) | |
244 | |
245 (defvar paths-package-special-bases '("etc" "info" "lisp" "lib-src" "bin") | |
246 "Special subdirectories of packages.") | |
247 | |
248 (defun paths-find-packages-in-directories (directories) | |
249 "Find all packages underneath directories in DIRECTORIES." | |
250 (paths-find-recursive-path directories | |
251 (append paths-version-control-bases | |
252 paths-package-special-bases))) | |
253 | |
254 (defun paths-split-path (path) | |
255 "Split PATH at NIL, return pair with two components. | |
256 The second component is shared with PATH." | |
257 (let ((reverse-early '())) | |
258 (while (and path (null (null (car path)))) | |
259 (setq reverse-early (cons (car path) reverse-early)) | |
260 (setq path (cdr path))) | |
261 (if (null path) | |
262 (cons nil path) | |
263 (cons (reverse reverse-early) (cdr path))))) | |
264 | |
265 (defun paths-find-packages (package-path) | |
266 "Search for all packages in PACKAGE-PATH. | |
267 PACKAGE-PATH may distinguish (by NIL-separation) between early | |
268 and late packages. | |
269 This returns (CONS EARLY-PACKAGES LATE-PACKAGES)." | |
270 (let* ((stuff (paths-split-path package-path)) | |
271 (early (car stuff)) | |
272 (late (cdr stuff))) | |
273 (cons (paths-find-packages-in-directories early) | |
274 (paths-find-packages-in-directories late)))) | |
275 | |
276 (defun paths-find-package-library-path (packages suffixes) | |
277 "Construct a path into a component of the packages hierarchy. | |
278 PACKAGES is a list of package directories. | |
279 SUFFIXES is a list of names of package subdirectories to look for." | |
280 (let ((directories | |
281 (apply | |
282 #'append | |
283 (mapcar #'(lambda (package) | |
284 (mapcar #'(lambda (suffix) | |
285 (concat package suffix)) | |
286 suffixes)) | |
287 packages)))) | |
288 (paths-directories-which-exist directories))) | |
289 | |
290 (defun paths-find-package-load-path (packages) | |
291 "Construct the load-path component for packages. | |
292 PACKAGES is a list of package directories." | |
293 (paths-find-recursive-load-path | |
294 (paths-find-package-library-path packages '("lisp/")))) | |
295 | |
296 (defun paths-find-package-exec-path (packages) | |
297 (paths-find-package-library-path packages | |
298 (list (concat "bin/" system-configuration "/") | |
299 "lib-src/"))) | |
300 | |
301 (defun paths-find-package-info-path (packages) | |
302 (paths-find-package-library-path packages '("info/"))) | |
303 | |
304 (defun paths-find-package-data-path (packages) | |
305 (paths-find-package-library-path packages '("etc/"))) | |
306 | |
307 (defun paths-find-emacs-roots (invocation-directory | |
308 invocation-name) | |
309 "Find all plausible installation roots for XEmacs." | |
310 (let ((invocation-root | |
311 (paths-find-emacs-root invocation-directory invocation-name)) | |
312 (installation-root | |
313 (if (and configure-prefix-directory | |
314 (file-directory-p configure-prefix-directory)) | |
315 configure-prefix-directory))) | |
316 (append (and invocation-root | |
317 (list invocation-root)) | |
318 (and installation-root | |
319 (list installation-root))))) | |
320 | |
321 (defun paths-find-load-path (roots early-package-load-path late-package-load-path) | |
322 "Construct the load path." | |
323 (let ((envvar-value (getenv "EMACSLOADPATH"))) | |
324 (if (and (fboundp 'parse-colon-path) envvar-value) | |
325 (parse-colon-path envvar-value) | |
326 (let* ((site-lisp-directory | |
327 (and allow-site-lisp | |
328 (paths-find-site-directory roots "site-lisp" | |
329 nil | |
330 configure-site-directory))) | |
331 (site-lisp-load-path | |
332 (and site-lisp-directory | |
333 (paths-find-recursive-load-path (list site-lisp-directory)))) | |
334 (lisp-directory | |
335 (paths-find-version-directory roots "lisp" | |
336 nil | |
337 configure-lisp-directory)) | |
338 (lisp-load-path | |
339 (paths-find-recursive-load-path (list lisp-directory)))) | |
340 (nconc early-package-load-path | |
341 site-lisp-load-path | |
342 late-package-load-path | |
343 lisp-load-path))))) | |
344 | |
345 (defun paths-find-info-path (roots early-packages late-packages) | |
346 "Construct the info path." | |
347 (append | |
348 (paths-find-package-info-path early-packages) | |
349 (paths-find-package-info-path late-packages) | |
350 (let ((info-directory | |
351 (paths-find-version-directory roots "info" | |
352 nil | |
353 (append | |
354 (and configure-info-directory | |
355 (list configure-info-directory)) | |
356 configure-info-path)))) | |
357 (and info-directory | |
358 (list info-directory))) | |
359 (let ((info-path-envval (getenv "INFOPATH"))) | |
360 (if (and (fboundp 'parse-colon-path) info-path-envval) | |
361 (parse-colon-path info-path-envval))))) | |
362 | |
363 (defun paths-find-doc-directory (roots) | |
364 "Find the documentation directory." | |
365 (paths-find-architecture-directory roots "lib-src")) | |
366 | |
367 (defun paths-find-lock-directory (roots) | |
368 "Find the lock directory." | |
369 (paths-find-site-path roots "lock" "EMACSLOCKDIR" configure-lock-directory)) | |
370 | |
371 (defun paths-find-superlock-file (lock-directory) | |
372 "Find the superlock file." | |
373 (cond | |
374 ((null lock-directory) | |
375 nil) | |
376 ((and configure-superlock-file | |
377 (file-directory-p (file-name-directory configure-superlock-file))) | |
378 configure-superlock-file) | |
379 (t | |
380 (expand-file-name "!!!SuperLock!!!" lock-directory)))) | |
381 | |
382 (defun paths-find-exec-directory (roots) | |
383 "Find the binary directory." | |
384 (paths-find-architecture-directory roots "lib-src")) | |
385 | |
386 (defun paths-find-exec-path (roots exec-directory early-packages late-packages) | |
387 "Find the binary path." | |
388 (append | |
389 (let ((path-envval (getenv "PATH"))) | |
390 (and (fboundp 'parse-colon-path) path-envval | |
391 (parse-colon-path path-envval))) | |
392 (paths-find-package-exec-path early-packages) | |
393 (paths-find-package-exec-path late-packages) | |
394 (let ((emacspath-envval (getenv "EMACSPATH"))) | |
395 (if (and (fboundp 'parse-colon-path) emacspath-envval) | |
396 (parse-colon-path path-envval) | |
397 (paths-directories-which-exist configure-exec-path))) | |
398 (and exec-directory | |
399 (list exec-directory)))) | |
400 | |
401 (defun paths-find-data-directory (roots) | |
402 "Find the data directory." | |
403 (paths-find-version-directory roots "etc" "EMACSDATA" configure-data-directory)) | |
404 | |
405 (defun paths-find-data-directory-list (data-directory early-packages late-packages) | |
406 "Find the data path." | |
407 (append | |
408 (paths-find-package-data-path early-packages) | |
409 (paths-find-package-data-path late-packages) | |
410 (list data-directory))) | |
411 | |
412 (defun paths-setup-paths () | |
413 "Setup all the various paths. | |
414 Call this as often as you like!" | |
415 ;; XEmacs -- Steven Baur says invocation directory is nil if you | |
416 ;; try to use XEmacs as a login shell. | |
417 (or invocation-directory (setq invocation-directory default-directory)) | |
418 (if (fboundp 'abbreviate-file-name) | |
419 ;; No abbreviate-file-name in temacs | |
420 (setq invocation-directory | |
421 ;; don't let /tmp_mnt/... get into the load-path or exec-path. | |
422 (abbreviate-file-name invocation-directory))) | |
423 | |
424 (let ((roots (paths-find-emacs-roots invocation-directory invocation-name))) | |
425 | |
426 (setq package-path (paths-find-package-path roots)) | |
427 | |
428 (let ((stuff (paths-find-packages package-path))) | |
429 (setq early-packages (car stuff)) | |
430 (setq late-packages (cdr stuff))) | |
431 | |
432 (setq early-package-load-path (paths-find-package-load-path early-packages)) | |
433 (setq late-package-load-path (paths-find-package-load-path late-packages)) | |
434 | |
435 (setq load-path (paths-find-load-path roots | |
436 early-package-load-path | |
437 late-package-load-path)) | |
438 | |
439 (setq info-path (paths-find-info-path roots early-packages late-packages)) | |
440 | |
441 (if (boundp 'lock-directory) | |
442 (progn | |
443 (setq lock-directory (paths-find-lock-directory roots)) | |
444 (setq superlock-file (paths-find-superlock-file lock-directory)))) | |
445 | |
446 (setq exec-directory (paths-find-exec-directory roots)) | |
447 | |
448 (setq exec-path (paths-find-exec-path roots exec-directory | |
449 early-packages late-packages)) | |
450 | |
451 (setq doc-directory (paths-find-doc-directory roots)) | |
452 | |
453 (setq data-directory (paths-find-data-directory roots)) | |
454 | |
455 (setq data-directory-list (paths-find-data-directory-list data-directory | |
456 early-packages | |
457 late-packages)))) | |
458 | |
459 (defun paths-setup-paths-warning () | |
460 (let ((lock (if (boundp 'lock-directory) lock-directory 't)) | |
461 warnings message guess) | |
462 (if (and (stringp lock) (null (file-directory-p lock))) | |
463 (setq lock nil)) | |
464 (cond | |
465 ((null (and exec-directory data-directory doc-directory load-path lock)) | |
466 (save-excursion | |
467 (set-buffer (get-buffer-create " *warning-tmp*")) | |
468 (erase-buffer) | |
469 (buffer-disable-undo (current-buffer)) | |
470 (if (null lock) (push "lock-directory" warnings)) | |
471 (if (null exec-directory) (push "exec-directory" warnings)) | |
472 (if (null data-directory) (push "data-directory" warnings)) | |
473 (if (null doc-directory) (push "doc-directory" warnings)) | |
474 (if (null load-path) (push "load-path" warnings)) | |
475 (cond ((cdr (cdr warnings)) | |
476 (setq message (apply 'format "%s, %s, and %s" warnings))) | |
477 ((cdr warnings) | |
478 (setq message (apply 'format "%s and %s" warnings))) | |
479 (t (setq message (format "variable %s" (car warnings))))) | |
480 (insert "couldn't find an obvious default for " message | |
481 ", and there were no defaults specified in paths.h when " | |
482 "XEmacs was built. Perhaps some directories don't exist, " | |
483 "or the XEmacs executable, " (concat invocation-directory | |
484 invocation-name) | |
485 " is in a strange place?") | |
486 | |
487 (if (fboundp 'fill-region) | |
488 ;; Might not be bound in the cold load environment... | |
489 (let ((fill-column 76)) | |
490 (fill-region (point-min) (point-max)))) | |
491 (goto-char (point-min)) | |
492 (princ "\nWARNING:\n" 'external-debugging-output) | |
493 (princ (buffer-string) 'external-debugging-output) | |
494 (erase-buffer) | |
495 t))))) | |
496 | |
497 (defun paths-load-package-lisps (package-load-path base) | |
498 "Load all Lisp files of a certain name along a load path. | |
499 BASE is the base name of the files." | |
500 (mapc #'(lambda (dir) | |
501 (let ((file-name (expand-file-name base dir))) | |
502 (if (file-exists-p file-name) | |
503 (condition-case error | |
504 (load file-name) | |
505 (error | |
506 (warn (format "Autoload error in: %s:\n\t%s" | |
507 file-name | |
508 (with-output-to-string | |
509 (display-error error nil))))))))) | |
510 package-load-path)) | |
511 | |
512 (defun paths-load-package-auto-autoloads (package-load-path) | |
513 "Load auto-autoload files along a load path." | |
514 (paths-load-package-lisps package-load-path | |
515 (file-name-sans-extension autoload-file-name))) | |
516 | |
517 (defun paths-load-package-dumped-lisps (package-load-path) | |
518 "Load dumped-lisp.el files along a load path." | |
519 (mapc #'(lambda (dir) | |
520 (let ((file-name (expand-file-name "dumped-lisp.el" dir))) | |
521 (if (file-exists-p file-name) | |
522 (let (package-lisp | |
523 ;; 20.4 packages could set this | |
524 preloaded-file-list) | |
525 (load file-name) | |
526 ;; dumped-lisp.el could have set this ... | |
527 (if package-lisp | |
528 (mapc #'(lambda (base) | |
529 (load (expand-file-name base dir))) | |
530 package-lisp)))))) | |
531 package-load-path)) | |
532 | |
533 ;;; setup-paths.el ends here |