XEmacs 21.2.22 "Mercedes".
[chise/xemacs-chise.git.1] / lisp / packages.el
index 974bdd3..2d1eaf3 100644 (file)
@@ -2,8 +2,8 @@
 
 ;; Copyright (C) 1997 Free Software Foundation, Inc.
 
-;; Author: Steven L Baur <steve@altair.xemacs.org>
-;; Maintainer: Steven L Baur <steve@altair.xemacs.org>
+;; Author: Steven L Baur <steve@xemacs.org>
+;; Maintainer: Steven L Baur <steve@xemacs.org>
 ;; Keywords: internal, lisp, dumped
 
 ;; This file is part of XEmacs.
@@ -55,7 +55,7 @@
 ;;; Package versioning
 
 (defvar packages-package-list nil
-  "database of loaded packages and version numbers")
+  "Database of loaded packages and version numbers")
 
 (defvar packages-hierarchy-depth 1
   "Depth of package hierarchies.")
@@ -63,6 +63,9 @@
 (defvar packages-load-path-depth 1
   "Depth of load-path search in package hierarchies.")
 
+(defvar packages-data-path-depth 1
+  "Depth of data-path search in package hierarchies.")
+
 (defvar early-packages nil
   "Packages early in the load path.")
 
 (defvar last-package-load-path nil
   "Load path for packages last in the load path.")
 
-(defvar package-locations
-  (list
-   (list (paths-construct-path '("~" ".xemacs"))
-                             'early #'(lambda () t))
-   (list "site-packages"     'late  #'(lambda () t))
-   (list "infodock-packages" 'late  #'(lambda () (featurep 'infodock)))
-   (list "mule-packages"     'late  #'(lambda () (featurep 'mule)))
-   (list "xemacs-packages"   'late  #'(lambda () t))
-   (list "packages"          'late  #'(lambda () t)))
-  "Locations of the various package directories.
+(defun packages-compute-package-locations (user-init-directory)
+  "Compute locations of the various package directories.
 This is a list each of whose elements describes one directory.
 A directory description is a three-element list.
 The first element is either an absolute path or a subdirectory
@@ -99,7 +94,16 @@ The second component is one of the symbols EARLY, LATE, LAST,
 depending on the load-path segment the hierarchy is supposed to
 show up in.
 The third component is a thunk which, if it returns NIL, causes
-the directory to be ignored.")
+the directory to be ignored."
+  (list
+   (list (paths-construct-path (list user-init-directory "mule-packages"))
+        'early #'(lambda () (featurep 'mule)))
+   (list (paths-construct-path (list user-init-directory "xemacs-packages"))
+        'early #'(lambda () t))
+   (list "site-packages"     'late  #'(lambda () t))
+   (list "infodock-packages" 'late  #'(lambda () (featurep 'infodock)))
+   (list "mule-packages"     'late  #'(lambda () (featurep 'mule)))
+   (list "xemacs-packages"   'late  #'(lambda () t))))
 
 (defun package-get-key-1 (info key)
   "Locate keyword `key' in list."
@@ -119,9 +123,8 @@ the directory to be ignored.")
   (let ((info (if (and attributes (floatp (car attributes)))
                  (list :version (car attributes))
                attributes)))
-    (remassq name packages-package-list)
     (setq packages-package-list
-         (cons (cons name info) packages-package-list))))
+         (cons (cons name info) (remassq name packages-package-list)))))
 
 (defun package-require (name version)
   (let ((pkg (assq name packages-package-list)))
@@ -133,6 +136,18 @@ the directory to be ignored.")
                  version name (cdr pkg)))
          (t t))))
 
+(defun package-delete-name (name)
+  (let (pkg)
+    ;; Delete ALL versions of package.
+    ;; This is pretty memory-intensive, as we use copy-alist when deleting
+    ;; package entries, to prevent side-effects in functions that call this
+    ;; one.
+    (while (setq pkg (assq name packages-package-list))
+      (setq packages-package-list (delete pkg (copy-alist
+                                              packages-package-list)))
+      )
+    ))
+
 ;;; Build time stuff
 
 (defvar autoload-file-name "auto-autoloads.el"
@@ -158,8 +173,7 @@ in dumped-lisp.el and is not itself listed.")
     "dumped-lisp.el"
     "dumped-pkg-lisp.el"
     "version.el"
-    "very-early-lisp.el"
-    "Installation.el")
+    "very-early-lisp.el")
   "Lisp packages that should not be byte compiled.")
 
 
@@ -188,14 +202,13 @@ is used instead of `load-path'."
                          (member 'crypt-find-file-hook find-file-hooks)))
                 ;; Compression involved.
                 (if nosuffix
-                    ":.gz:.Z"
-                  ".elc:.elc.gz:elc.Z:.el:.el.gz:.el.Z::.gz:.Z"))
+                    '("" ".gz" ".Z")
+                  '(".elc" ".elc.gz" "elc.Z" ".el" ".el.gz" ".el.Z" "" ".gz" ".Z")))
                (t
                 ;; No compression.
                 (if nosuffix
                     ""
-                  ".elc:.el:")))
-         4)))
+                  '(".elc" ".el" "")))))))
     (and interactive-call
         (if result
             (message "Library is file %s" result)
@@ -220,14 +233,10 @@ is used instead of `load-path'."
       (setq path (cdr path)))
     autoloads))
 
-(defun packages-list-autoloads ()
+(defun packages-list-autoloads (source-directory)
   "List autoload files in (what will be) the normal lisp search path.
 This function is used during build to find where the global symbol files so
 they can be perused for their useful information."
-  ;; Source directory may not be initialized yet.
-  ;; (print (prin1-to-string load-path))
-  (if (null source-directory)
-      (setq source-directory (car load-path)))
   (let ((files (directory-files (file-name-as-directory source-directory)
                                t ".*"))
        file autolist)
@@ -294,6 +303,23 @@ is run.  Don't call it or you'll be sorry."
 ;; Data-directory is really a list now.  Provide something to search it for
 ;; directories.
 
+(defun locate-data-directory-list (name &optional dir-list)
+  "Locate the matching list of directories in a search path DIR-LIST.
+If no DIR-LIST is supplied, it defaults to `data-directory-list'."
+  (unless dir-list
+    (setq dir-list data-directory-list))
+  (let (found found-dir found-dir-list)
+    (while dir-list
+      (setq found (file-name-as-directory (concat (car dir-list) name))
+           found-dir (file-directory-p found))
+      (and found-dir
+          (setq found-dir-list (cons found found-dir-list)))
+      (setq dir-list (cdr dir-list)))
+    (nreverse found-dir-list)))
+
+;; Data-directory is really a list now.  Provide something to search it for
+;; a directory.
+
 (defun locate-data-directory (name &optional dir-list)
   "Locate a directory in a search path DIR-LIST (a list of directories).
 If no DIR-LIST is supplied, it defaults to `data-directory-list'."
@@ -315,9 +341,7 @@ If no DIR-LIST is supplied, it defaults to `data-directory-list'."
   "Locate a file in a search path DIR-LIST (a list of directories).
 If no DIR-LIST is supplied, it defaults to `data-directory-list'.
 This function is basically a wrapper over `locate-file'."
-  (unless dir-list
-    (setq dir-list data-directory-list))
-  (locate-file name dir-list))
+  (locate-file name (or dir-list data-directory-list)))
 
 ;; Path setup
 
@@ -331,7 +355,7 @@ This function is basically a wrapper over `locate-file'."
      (and version-directory (list version-directory))
      (and site-directory (list site-directory)))))
 
-(defvar packages-special-base-regexp "^\\(etc\\|info\\|lisp\\|lib-src\\|bin\\)$"
+(defvar packages-special-base-regexp "^\\(etc\\|info\\|lisp\\|lib-src\\|bin\\|pkginfo\\)$"
   "Special subdirectories of packages.")
 
 (defvar packages-no-package-hierarchy-regexp
@@ -405,7 +429,7 @@ DEFAULT is a default list of packages."
          (setq package-locations (cdr package-locations)))
        packages)))
 
-(defun packages-find-packages (roots)
+(defun packages-find-packages (roots package-locations)
   "Find the packages."
   (let ((envvar-value (getenv "EMACSPACKAGEPATH")))
     (if envvar-value
@@ -428,7 +452,7 @@ PACKAGES is a list of package directories.
 SUFFIXES is a list of names of package subdirectories to look for."
   (let ((directories
         (apply
-         #'append
+         #'nconc
          (mapcar #'(lambda (package)
                      (mapcar #'(lambda (suffix)
                                  (file-name-as-directory (concat package suffix)))
@@ -445,23 +469,32 @@ PACKAGES is a list of package directories."
    packages-load-path-depth))
 
 (defun packages-find-package-exec-path (packages)
+  "Construct the exec-path component for packages.
+PACKAGES is a list of package directories."
   (packages-find-package-library-path packages
                                      (list (paths-construct-path
                                             (list "bin" system-configuration))
                                            "lib-src")))
 
 (defun packages-find-package-info-path (packages)
+  "Construct the info-path component for packages.
+PACKAGES is a list of package directories."
   (packages-find-package-library-path packages '("info")))
 
 (defun packages-find-package-data-path (packages)
-  (packages-find-package-library-path packages '("etc")))
+  "Construct the data-path component for packages.
+PACKAGES is a list of package directories."
+  (paths-find-recursive-load-path
+   (packages-find-package-library-path packages
+                                      '("etc"))
+   packages-data-path-depth))
 
 ;; Loading package initialization files
 
 (defun packages-load-package-lisps (package-load-path base)
   "Load all Lisp files of a certain name along a load path.
 BASE is the base name of the files."
-  (mapc #'(lambda (dir)
+  (mapcar #'(lambda (dir)
            (let ((file-name (expand-file-name base dir)))
              (condition-case error
                  (load file-name t t)
@@ -480,7 +513,7 @@ BASE is the base name of the files."
 (defun packages-handle-package-dumped-lisps (handle package-load-path)
   "Load dumped-lisp.el files along a load path.
 Call HANDLE on each file off definitions of PACKAGE-LISP there."
-  (mapc #'(lambda (dir)
+  (mapcar #'(lambda (dir)
            (let ((file-name (expand-file-name "dumped-lisp.el" dir)))
              (if (file-exists-p file-name)
                  (let (package-lisp
@@ -489,7 +522,7 @@ Call HANDLE on each file off definitions of PACKAGE-LISP there."
                    (load file-name)
                    ;; dumped-lisp.el could have set this ...
                    (if package-lisp
-                       (mapc #'(lambda (base)
+                       (mapcar #'(lambda (base)
                                  (funcall handle base))
                              package-lisp))))))
        package-load-path))