]> code.delx.au - gnu-emacs/blobdiff - lisp/emacs-lisp/autoload.el
Fix previous rmail-output-read-file-name change
[gnu-emacs] / lisp / emacs-lisp / autoload.el
index 5a5d6b88a2d5f17fd9a04a8118aa12c604d2c942..e6e2d1e60e0a7ddf19b49a49be26f20f99fb576c 100644 (file)
@@ -1,6 +1,6 @@
-;; autoload.el --- maintain autoloads in loaddefs.el
+;; autoload.el --- maintain autoloads in loaddefs.el  -*- lexical-binding: t -*-
 
 
-;; Copyright (C) 1991-1997, 2001-2011  Free Software Foundation, Inc.
+;; Copyright (C) 1991-1997, 2001-2012  Free Software Foundation, Inc.
 
 ;; Author: Roland McGrath <roland@gnu.org>
 ;; Keywords: maint
 
 ;; Author: Roland McGrath <roland@gnu.org>
 ;; Keywords: maint
 
 (require 'lisp-mode)                   ;for `doc-string-elt' properties.
 (require 'help-fns)                    ;for help-add-fundoc-usage.
 
 (require 'lisp-mode)                   ;for `doc-string-elt' properties.
 (require 'help-fns)                    ;for help-add-fundoc-usage.
-(eval-when-compile (require 'cl))
+(eval-when-compile (require 'cl-lib))
 
 
-(defvar generated-autoload-file "loaddefs.el"
-   "*File \\[update-file-autoloads] puts autoloads into.
-A `.el' file can set this in its local variables section to make its
-autoloads go somewhere else.  The autoload file is assumed to contain a
-trailer starting with a FormFeed character.")
+(defvar generated-autoload-file nil
+  "File into which to write autoload definitions.
+A Lisp file can set this in its local variables section to make
+its autoloads go somewhere else.
+
+If this is a relative file name, the directory is determined as
+follows:
+ - If a Lisp file defined `generated-autoload-file' as a
+   file-local variable, use its containing directory.
+ - Otherwise use the \"lisp\" subdirectory of `source-directory'.
+
+The autoload file is assumed to contain a trailer starting with a
+FormFeed character.")
 ;;;###autoload
 (put 'generated-autoload-file 'safe-local-variable 'stringp)
 
 ;;;###autoload
 (put 'generated-autoload-file 'safe-local-variable 'stringp)
 
@@ -78,78 +86,100 @@ that text will be copied verbatim to `generated-autoload-file'.")
 
 (defvar autoload-modified-buffers)      ;Dynamically scoped var.
 
 
 (defvar autoload-modified-buffers)      ;Dynamically scoped var.
 
-(defun make-autoload (form file)
+(defun make-autoload (form file &optional expansion)
   "Turn FORM into an autoload or defvar for source file FILE.
 Returns nil if FORM is not a special autoload form (i.e. a function definition
   "Turn FORM into an autoload or defvar for source file FILE.
 Returns nil if FORM is not a special autoload form (i.e. a function definition
-or macro definition or a defcustom)."
+or macro definition or a defcustom).
+If EXPANSION is non-nil, we're processing the macro expansion of an
+expression, in which case we want to handle forms differently."
   (let ((car (car-safe form)) expand)
     (cond
   (let ((car (car-safe form)) expand)
     (cond
+     ((and expansion (eq car 'defalias))
+      (pcase-let*
+          ((`(,_ ,_ ,arg . ,rest) form)
+           ;; `type' is non-nil if it defines a macro.
+           ;; `fun' is the function part of `arg' (defaults to `arg').
+           ((or (and (or `(cons 'macro ,fun) `'(macro . ,fun)) (let type t))
+                (and (let fun arg) (let type nil)))
+            arg)
+           ;; `lam' is the lambda expression in `fun' (or nil if not
+           ;; recognized).
+           (lam (if (memq (car-safe fun) '(quote function)) (cadr fun)))
+           ;; `args' is the list of arguments (or t if not recognized).
+           ;; `body' is the body of `lam' (or t if not recognized).
+           ((or `(lambda ,args . ,body)
+                (and (let args t) (let body t)))
+            lam)
+           ;; Get the `doc' from `body' or `rest'.
+           (doc (cond ((stringp (car-safe body)) (car body))
+                      ((stringp (car-safe rest)) (car rest))))
+           ;; Look for an interactive spec.
+           (interactive (pcase body
+                          ((or `((interactive . ,_) . ,_)
+                               `(,_ (interactive . ,_) . ,_)) t))))
+        ;; Add the usage form at the end where describe-function-1
+        ;; can recover it.
+        (when (listp args) (setq doc (help-add-fundoc-usage doc args)))
+        ;; (message "autoload of %S" (nth 1 form))
+        `(autoload ,(nth 1 form) ,file ,doc ,interactive ,type)))
+
+     ((and expansion (memq car '(progn prog1)))
+      (let ((end (memq :autoload-end form)))
+       (when end             ;Cut-off anything after the :autoload-end marker.
+          (setq form (copy-sequence form))
+          (setcdr (memq :autoload-end form) nil))
+        (let ((exps (delq nil (mapcar (lambda (form)
+                                        (make-autoload form file expansion))
+                                      (cdr form)))))
+          (when exps (cons 'progn exps)))))
+
      ;; For complex cases, try again on the macro-expansion.
      ((and (memq car '(easy-mmode-define-global-mode define-global-minor-mode
      ;; For complex cases, try again on the macro-expansion.
      ((and (memq car '(easy-mmode-define-global-mode define-global-minor-mode
-                      define-globalized-minor-mode
+                       define-globalized-minor-mode defun defmacro
+                       ;; FIXME: we'd want `defmacro*' here as well, so as
+                       ;; to handle its `declare', but when autoload is run
+                       ;; CL is not loaded so macroexpand doesn't know how
+                       ;; to expand it!
                       easy-mmode-define-minor-mode define-minor-mode))
           (setq expand (let ((load-file-name file)) (macroexpand form)))
                       easy-mmode-define-minor-mode define-minor-mode))
           (setq expand (let ((load-file-name file)) (macroexpand form)))
-          (eq (car expand) 'progn)
-          (memq :autoload-end expand))
-      (let ((end (memq :autoload-end expand)))
-       ;; Cut-off anything after the :autoload-end marker.
-       (setcdr end nil)
-       (cons 'progn
-             (mapcar (lambda (form) (make-autoload form file))
-                     (cdr expand)))))
+          (memq (car expand) '(progn prog1 defalias)))
+      (make-autoload expand file 'expansion)) ;Recurse on the expansion.
 
      ;; For special function-like operators, use the `autoload' function.
 
      ;; For special function-like operators, use the `autoload' function.
-     ((memq car '(defun define-skeleton defmacro define-derived-mode
+     ((memq car '(define-skeleton define-derived-mode
                    define-compilation-mode define-generic-mode
                   easy-mmode-define-global-mode define-global-minor-mode
                   define-globalized-minor-mode
                   easy-mmode-define-minor-mode define-minor-mode
                    define-compilation-mode define-generic-mode
                   easy-mmode-define-global-mode define-global-minor-mode
                   define-globalized-minor-mode
                   easy-mmode-define-minor-mode define-minor-mode
-                  defun* defmacro* define-overloadable-function))
+                  cl-defun defun* cl-defmacro defmacro*
+                   define-overloadable-function))
       (let* ((macrop (memq car '(defmacro defmacro*)))
             (name (nth 1 form))
       (let* ((macrop (memq car '(defmacro defmacro*)))
             (name (nth 1 form))
-            (args (case car
-                     ((defun defmacro defun* defmacro*
-                        define-overloadable-function) (nth 2 form))
-                     ((define-skeleton) '(&optional str arg))
-                     ((define-generic-mode define-derived-mode
-                        define-compilation-mode) nil)
-                     (t)))
-            (body (nthcdr (get car 'doc-string-elt) form))
+            (args (pcase car
+                     ((or `defun `defmacro
+                          `defun* `defmacro* `cl-defun `cl-defmacro
+                          `define-overloadable-function) (nth 2 form))
+                     (`define-skeleton '(&optional str arg))
+                     ((or `define-generic-mode `define-derived-mode
+                          `define-compilation-mode) nil)
+                     (_ t)))
+            (body (nthcdr (or (function-get car 'doc-string-elt) 3) form))
             (doc (if (stringp (car body)) (pop body))))
             (doc (if (stringp (car body)) (pop body))))
-       (when (listp args)
-         ;; Add the usage form at the end where describe-function-1
-         ;; can recover it.
-         (setq doc (help-add-fundoc-usage doc args)))
-        (let ((exp
-               ;; `define-generic-mode' quotes the name, so take care of that
-               (list 'autoload (if (listp name) name (list 'quote name))
-                     file doc
-                     (or (and (memq car '(define-skeleton define-derived-mode
-                                           define-generic-mode
-                                           easy-mmode-define-global-mode
-                                           define-global-minor-mode
-                                           define-globalized-minor-mode
-                                           easy-mmode-define-minor-mode
-                                           define-minor-mode)) t)
-                         (eq (car-safe (car body)) 'interactive))
-                     (if macrop (list 'quote 'macro) nil))))
-          (when macrop
-            ;; Special case to autoload some of the macro's declarations.
-            (let ((decls (nth (if (stringp (nth 3 form)) 4 3) form))
-                  (exps '()))
-              (when (eq (car-safe decls) 'declare)
-                ;; FIXME: We'd like to reuse macro-declaration-function,
-                ;; but we can't since it doesn't return anything.
-                (dolist (decl decls)
-                  (case (car-safe decl)
-                    (indent
-                     (push `(put ',name 'lisp-indent-function ',(cadr decl))
-                           exps))
-                    (doc-string
-                     (push `(put ',name 'doc-string-elt ',(cadr decl)) exps))))
-                (when exps
-                  (setq exp `(progn ,exp ,@exps))))))
-          exp)))
+        ;; Add the usage form at the end where describe-function-1
+        ;; can recover it.
+       (when (listp args) (setq doc (help-add-fundoc-usage doc args)))
+        ;; `define-generic-mode' quotes the name, so take care of that
+        `(autoload ,(if (listp name) name (list 'quote name))
+           ,file ,doc
+           ,(or (and (memq car '(define-skeleton define-derived-mode
+                                  define-generic-mode
+                                  easy-mmode-define-global-mode
+                                  define-global-minor-mode
+                                  define-globalized-minor-mode
+                                  easy-mmode-define-minor-mode
+                                  define-minor-mode)) t)
+                (eq (car-safe (car body)) 'interactive))
+           ,(if macrop ''macro nil))))
 
      ;; For defclass forms, use `eieio-defclass-autoload'.
      ((eq car 'defclass)
 
      ;; For defclass forms, use `eieio-defclass-autoload'.
      ((eq car 'defclass)
@@ -182,6 +212,11 @@ or macro definition or a defcustom)."
            (if (member ',file loads) nil
              (put ',groupname 'custom-loads (cons ',file loads))))))
 
            (if (member ',file loads) nil
              (put ',groupname 'custom-loads (cons ',file loads))))))
 
+     ;; When processing a macro expansion, any expression
+     ;; before a :autoload-end should be included.  These are typically (put
+     ;; 'fun 'prop val) and things like that.
+     ((and expansion (consp form)) form)
+
      ;; nil here indicates that this is not a special autoload form.
      (t nil))))
 
      ;; nil here indicates that this is not a special autoload form.
      (t nil))))
 
@@ -190,6 +225,16 @@ or macro definition or a defcustom)."
 ;; the doc-string in FORM.
 ;; Those properties are now set in lisp-mode.el.
 
 ;; the doc-string in FORM.
 ;; Those properties are now set in lisp-mode.el.
 
+(defun autoload-find-generated-file ()
+  "Visit the autoload file for the current buffer, and return its buffer.
+If a buffer is visiting the desired autoload file, return it."
+  (let ((enable-local-variables :safe)
+       (enable-local-eval nil))
+    ;; We used to use `raw-text' to read this file, but this causes
+    ;; problems when the file contains non-ASCII characters.
+    (find-file-noselect
+     (autoload-ensure-default-file (autoload-generated-file)))))
+
 (defun autoload-generated-file ()
   (expand-file-name generated-autoload-file
                     ;; File-local settings of generated-autoload-file should
 (defun autoload-generated-file ()
   (expand-file-name generated-autoload-file
                     ;; File-local settings of generated-autoload-file should
@@ -233,7 +278,7 @@ put the output in."
    ;; Symbols at the toplevel are meaningless.
    ((symbolp form) nil)
    (t
    ;; Symbols at the toplevel are meaningless.
    ((symbolp form) nil)
    (t
-    (let ((doc-string-elt (get (car-safe form) 'doc-string-elt))
+    (let ((doc-string-elt (function-get (car-safe form) 'doc-string-elt))
          (outbuf autoload-print-form-outbuf))
       (if (and doc-string-elt (stringp (nth doc-string-elt form)))
          ;; We need to hack the printing because the
          (outbuf autoload-print-form-outbuf))
       (if (and doc-string-elt (stringp (nth doc-string-elt form)))
          ;; We need to hack the printing because the
@@ -312,7 +357,7 @@ not be relied upon."
   "Insert the section-header line,
 which lists the file name and which functions are in it, etc."
   (insert generate-autoload-section-header)
   "Insert the section-header line,
 which lists the file name and which functions are in it, etc."
   (insert generate-autoload-section-header)
-  (prin1 (list 'autoloads autoloads load-name file time)
+  (prin1 `(autoloads ,autoloads ,load-name ,file ,time)
         outbuf)
   (terpri outbuf)
   ;; Break that line at spaces, to avoid very long lines.
         outbuf)
   (terpri outbuf)
   ;; Break that line at spaces, to avoid very long lines.
@@ -338,7 +383,8 @@ which lists the file name and which functions are in it, etc."
     (emacs-lisp-mode)
     (setq default-directory (file-name-directory file))
     (insert-file-contents file nil)
     (emacs-lisp-mode)
     (setq default-directory (file-name-directory file))
     (insert-file-contents file nil)
-    (let ((enable-local-variables :safe))
+    (let ((enable-local-variables :safe)
+         (enable-local-eval nil))
       (hack-local-variables))
     (current-buffer)))
 
       (hack-local-variables))
     (current-buffer)))
 
@@ -381,7 +427,8 @@ If FILE is being visited in a buffer, the contents of the buffer
 are used.
 Return non-nil in the case where no autoloads were added at point."
   (interactive "fGenerate autoloads for file: ")
 are used.
 Return non-nil in the case where no autoloads were added at point."
   (interactive "fGenerate autoloads for file: ")
-  (autoload-generate-file-autoloads file (current-buffer)))
+  (let ((generated-autoload-file buffer-file-name))
+    (autoload-generate-file-autoloads file (current-buffer))))
 
 (defvar print-readably)
 
 
 (defvar print-readably)
 
@@ -428,7 +475,11 @@ Return non-nil if and only if FILE adds no autoloads to OUTFILE
                    generated-autoload-load-name
                  (autoload-file-load-name absfile)))
           (when (and outfile
                    generated-autoload-load-name
                  (autoload-file-load-name absfile)))
           (when (and outfile
-                     (not (equal outfile (autoload-generated-file))))
+                     (not
+                     (if (memq system-type '(ms-dos windows-nt))
+                         (equal (downcase outfile)
+                                (downcase (autoload-generated-file)))
+                       (equal outfile (autoload-generated-file)))))
             (setq otherbuf t))
           (save-excursion
             (save-restriction
             (setq otherbuf t))
           (save-excursion
             (save-restriction
@@ -459,7 +510,7 @@ Return non-nil if and only if FILE adds no autoloads to OUTFILE
                   (search-forward generate-autoload-cookie)
                   (skip-chars-forward " \t")
                   (if (eolp)
                   (search-forward generate-autoload-cookie)
                   (skip-chars-forward " \t")
                   (if (eolp)
-                      (condition-case err
+                      (condition-case-unless-debug err
                           ;; Read the next form and make an autoload.
                           (let* ((form (prog1 (read (current-buffer))
                                          (or (bolp) (forward-line 1))))
                           ;; Read the next form and make an autoload.
                           (let* ((form (prog1 (read (current-buffer))
                                          (or (bolp) (forward-line 1))))
@@ -494,13 +545,12 @@ Return non-nil if and only if FILE adds no autoloads to OUTFILE
 
           (when output-start
             (let ((secondary-autoloads-file-buf
 
           (when output-start
             (let ((secondary-autoloads-file-buf
-                   (if (local-variable-p 'generated-autoload-file)
-                       (current-buffer))))
+                   (if otherbuf (current-buffer))))
               (with-current-buffer (marker-buffer output-start)
                 (save-excursion
                   ;; Insert the section-header line which lists the file name
                   ;; and which functions are in it, etc.
               (with-current-buffer (marker-buffer output-start)
                 (save-excursion
                   ;; Insert the section-header line which lists the file name
                   ;; and which functions are in it, etc.
-                  (assert (= ostart output-start))
+                  (cl-assert (= ostart output-start))
                   (goto-char output-start)
                   (let ((relfile (file-relative-name absfile)))
                     (autoload-insert-section-header
                   (goto-char output-start)
                   (let ((relfile (file-relative-name absfile)))
                     (autoload-insert-section-header
@@ -542,15 +592,22 @@ Return non-nil if and only if FILE adds no autoloads to OUTFILE
        (save-buffer)))))
 
 ;;;###autoload
        (save-buffer)))))
 
 ;;;###autoload
-(defun update-file-autoloads (file &optional save-after)
-  "Update the autoloads for FILE in `generated-autoload-file'
-\(which FILE might bind in its local variables).
-If SAVE-AFTER is non-nil (which is always, when called interactively),
-save the buffer too.
+(defun update-file-autoloads (file &optional save-after outfile)
+  "Update the autoloads for FILE.
+If prefix arg SAVE-AFTER is non-nil, save the buffer too.
+
+If FILE binds `generated-autoload-file' as a file-local variable,
+autoloads are written into that file.  Otherwise, the autoloads
+file is determined by OUTFILE.  If called interactively, prompt
+for OUTFILE; if called from Lisp with OUTFILE nil, use the
+existing value of `generated-autoload-file'.
 
 Return FILE if there was no autoload cookie in it, else nil."
 
 Return FILE if there was no autoload cookie in it, else nil."
-  (interactive "fUpdate autoloads for file: \np")
-  (let* ((autoload-modified-buffers nil)
+  (interactive (list (read-file-name "Update autoloads for file: ")
+                    current-prefix-arg
+                    (read-file-name "Write autoload definitions to file: ")))
+  (let* ((generated-autoload-file (or outfile generated-autoload-file))
+        (autoload-modified-buffers nil)
          (no-autoloads (autoload-generate-file-autoloads file)))
     (if autoload-modified-buffers
         (if save-after (autoload-save-buffers))
          (no-autoloads (autoload-generate-file-autoloads file)))
     (if autoload-modified-buffers
         (if save-after (autoload-save-buffers))
@@ -568,12 +625,7 @@ removes any prior now out-of-date autoload entries."
     (let* ((buf (current-buffer))
            (existing-buffer (if buffer-file-name buf))
            (found nil))
     (let* ((buf (current-buffer))
            (existing-buffer (if buffer-file-name buf))
            (found nil))
-      (with-current-buffer
-          ;; We used to use `raw-text' to read this file, but this causes
-          ;; problems when the file contains non-ASCII characters.
-         (let ((enable-local-variables :safe))
-           (find-file-noselect
-            (autoload-ensure-default-file (autoload-generated-file))))
+      (with-current-buffer (autoload-find-generated-file)
         ;; This is to make generated-autoload-file have Unix EOLs, so
         ;; that it is portable to all platforms.
         (or (eq 0 (coding-system-eol-type buffer-file-coding-system))
         ;; This is to make generated-autoload-file have Unix EOLs, so
         ;; that it is portable to all platforms.
         (or (eq 0 (coding-system-eol-type buffer-file-coding-system))
@@ -632,20 +684,25 @@ removes any prior now out-of-date autoload entries."
 
 ;;;###autoload
 (defun update-directory-autoloads (&rest dirs)
 
 ;;;###autoload
 (defun update-directory-autoloads (&rest dirs)
-  "\
-Update loaddefs.el with all the current autoloads from DIRS, and no old ones.
-This uses `update-file-autoloads' (which see) to do its work.
-In an interactive call, you must give one argument, the name
-of a single directory.  In a call from Lisp, you can supply multiple
+  "Update autoload definitions for Lisp files in the directories DIRS.
+In an interactive call, you must give one argument, the name of a
+single directory.  In a call from Lisp, you can supply multiple
 directories as separate arguments, but this usage is discouraged.
 
 The function does NOT recursively descend into subdirectories of the
 directories as separate arguments, but this usage is discouraged.
 
 The function does NOT recursively descend into subdirectories of the
-directory or directories specified."
+directory or directories specified.
+
+In an interactive call, prompt for a default output file for the
+autoload definitions, and temporarily bind the variable
+`generated-autoload-file' to this value.  When called from Lisp,
+use the existing value of `generated-autoload-file'.  If any Lisp
+file binds `generated-autoload-file' as a file-local variable,
+write its autoloads into the specified file instead."
   (interactive "DUpdate autoloads from directory: ")
   (let* ((files-re (let ((tmp nil))
   (interactive "DUpdate autoloads from directory: ")
   (let* ((files-re (let ((tmp nil))
-                    (dolist (suf (get-load-suffixes)
-                                 (concat "^[^=.].*" (regexp-opt tmp t) "\\'"))
-                      (unless (string-match "\\.elc" suf) (push suf tmp)))))
+                    (dolist (suf (get-load-suffixes))
+                      (unless (string-match "\\.elc" suf) (push suf tmp)))
+                     (concat "^[^=.].*" (regexp-opt tmp t) "\\'")))
         (files (apply 'nconc
                       (mapcar (lambda (dir)
                                 (directory-files (expand-file-name dir)
         (files (apply 'nconc
                       (mapcar (lambda (dir)
                                 (directory-files (expand-file-name dir)
@@ -656,14 +713,14 @@ directory or directories specified."
          ;; Files with no autoload cookies or whose autoloads go to other
          ;; files because of file-local autoload-generated-file settings.
         (no-autoloads nil)
          ;; Files with no autoload cookies or whose autoloads go to other
          ;; files because of file-local autoload-generated-file settings.
         (no-autoloads nil)
-         (autoload-modified-buffers nil))
+         (autoload-modified-buffers nil)
+        (generated-autoload-file
+         (if (called-interactively-p 'interactive)
+             (read-file-name "Write autoload definitions to file: ")
+           generated-autoload-file)))
 
 
-    (with-current-buffer
-       (let ((enable-local-variables :safe))
-         (find-file-noselect
-          (autoload-ensure-default-file (autoload-generated-file))))
+    (with-current-buffer (autoload-find-generated-file)
       (save-excursion
       (save-excursion
-
        ;; Canonicalize file names and remove the autoload file itself.
        (setq files (delete (file-relative-name buffer-file-name)
                            (mapcar 'file-relative-name files)))
        ;; Canonicalize file names and remove the autoload file itself.
        (setq files (delete (file-relative-name buffer-file-name)
                            (mapcar 'file-relative-name files)))
@@ -734,60 +791,28 @@ directory or directories specified."
 (define-obsolete-function-alias 'update-autoloads-from-directories
     'update-directory-autoloads "22.1")
 
 (define-obsolete-function-alias 'update-autoloads-from-directories
     'update-directory-autoloads "22.1")
 
-(defvar autoload-make-program (or (getenv "MAKE") "make")
-  "Name of the make program in use during the Emacs build process.")
-
 ;;;###autoload
 (defun batch-update-autoloads ()
   "Update loaddefs.el autoloads in batch mode.
 ;;;###autoload
 (defun batch-update-autoloads ()
   "Update loaddefs.el autoloads in batch mode.
-Calls `update-directory-autoloads' on the command line arguments."
+Calls `update-directory-autoloads' on the command line arguments.
+Definitions are written to `generated-autoload-file' (which
+should be non-nil)."
   ;; For use during the Emacs build process only.
   ;; For use during the Emacs build process only.
+  ;; Exclude those files that are preloaded on ALL platforms.
+  ;; These are the ones in loadup.el where "(load" is at the start
+  ;; of the line (crude, but it works).
   (unless autoload-excludes
   (unless autoload-excludes
-    (let* ((ldir (file-name-directory generated-autoload-file))
-          (default-directory
-            (file-name-as-directory
-             (expand-file-name (if (eq system-type 'windows-nt)
-                                   "../lib-src"
-                                 "../src") ldir)))
-          (mfile "Makefile")
-          (tmpfile "echolisp.tmp")
-          lim)
-      ;; Windows uses the 'echolisp' approach because:
-      ;; i) It does not have $lisp as a single simple definition, so
-      ;; it would be harder to parse the Makefile.
-      ;; ii) It can, since it already has $lisp broken up into pieces
-      ;; that the command-line can handle.
-      ;; Non-Windows builds do not use the 'echolisp' approach because
-      ;; no-one knows (?) the maximum safe command-line length on all
-      ;; supported systems.  $lisp is much longer there since it uses
-      ;; absolute paths, and it would seem a shame to split it just for this.
-      (when (file-readable-p mfile)
-       (if (eq system-type 'windows-nt)
-           (when (ignore-errors
-                  (if (file-exists-p tmpfile) (delete-file tmpfile))
-                  ;; FIXME call-process is better, if it works.
-                  (shell-command (format "%s echolisp > %s"
-                                         autoload-make-program tmpfile))
-                  (file-readable-p tmpfile))
-             (with-temp-buffer
-               (insert-file-contents tmpfile)
-               ;; FIXME could be a single while loop.
-               (while (not (eobp))
-                 (setq lim (line-end-position))
-                 (while (re-search-forward "\\([^ ]+\\.el\\)c?\\>" lim t)
-                   (push (expand-file-name (match-string 1))
-                         autoload-excludes))
-                 (forward-line 1))))
-         (with-temp-buffer
-           (insert-file-contents mfile)
-           (when (re-search-forward "^shortlisp= " nil t)
-             (while (and (not lim)
-                         (re-search-forward "\\.\\./lisp/\\([^ ]+\\.el\\)c?\\>"
-                                            nil t))
-               (push (expand-file-name (match-string 1) ldir)
-                     autoload-excludes)
-               (skip-chars-forward " \t")
-               (if (eolp) (setq lim t)))))))))
+    (let ((default-directory (file-name-directory generated-autoload-file))
+         file)
+      (when (file-readable-p "loadup.el")
+       (with-temp-buffer
+         (insert-file-contents "loadup.el")
+         (while (re-search-forward "^(load \"\\([^\"]+\\)\"" nil t)
+           (setq file (match-string 1))
+           (or (string-match "\\.el\\'" file)
+               (setq file (format "%s.el" file)))
+           (or (string-match "\\`site-" file)
+               (push (expand-file-name file) autoload-excludes)))))))
   (let ((args command-line-args-left))
     (setq command-line-args-left nil)
     (apply 'update-directory-autoloads args)))
   (let ((args command-line-args-left))
     (setq command-line-args-left nil)
     (apply 'update-directory-autoloads args)))