# HG changeset patch # User Gerd Moellmann # Date 1002274151 0 # Node ID a05ad383618dcd360c0dcb59ee1adcd5609549a2 # Parent 5851ee3f83f5f2ba6a1466c35aebcd5f374d080a (autoload-ensure-default-file, autoload-insert-section-header) (autoload-before-p, autoload-remove-section): New functions. (generate-file-autoloads): Use them. (update-file-autoloads): Use them. Return FILE if there's no cookie. Make sure the autoload file is properly formatted when creating it. (update-autoloads-from-directories): Use them as well. Only update autoloads for files whose timestamp has changed. Add a dummy entry to remember the files which had no autoload cookies. diff -r 5851ee3f83f5 -r a05ad383618d lisp/emacs-lisp/autoload.el --- a/lisp/emacs-lisp/autoload.el Fri Oct 05 09:27:29 2001 +0000 +++ b/lisp/emacs-lisp/autoload.el Fri Oct 05 09:29:11 2001 +0000 @@ -230,6 +230,44 @@ (print-escape-nonascii t)) (print form outbuf))))))) +(defun autoload-ensure-default-file (file) + "Make sure that the autoload file FILE exists and if not create it." + (unless (file-exists-p file) + (write-region + (concat ";;; " (file-name-nondirectory file) + " --- automatically extracted autoloads\n" + ";;\n" + ";;; Code:\n\n" + " \n;; Local Variables:\n" + ";; version-control: never\n" + ";; no-byte-compile: t\n" + ";; no-update-autoloads: t\n" + ";; End:\n" + ";;; " (file-name-nondirectory file) + "ends here\n") + nil file)) + file) + +(defun autoload-insert-section-header (outbuf autoloads load-name file time) + "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 + (if (stringp file) (autoload-trim-file-name file) file) + time) + outbuf) + (terpri outbuf) + ;; Break that line at spaces, to avoid very long lines. + ;; Make each sub-line into a comment. + (with-current-buffer outbuf + (save-excursion + (forward-line -1) + (while (not (eolp)) + (move-to-column 64) + (skip-chars-forward "^ \n") + (or (eolp) + (insert "\n" generate-autoload-section-continuation)))))) + (defun generate-file-autoloads (file) "Insert at point a loaddefs autoload section for FILE. autoloads are generated for defuns and defmacros in FILE @@ -328,22 +366,8 @@ (progn ;; 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-done load-name - (autoload-trim-file-name file) - (nth 5 (file-attributes file))) - outbuf) - (terpri outbuf) - ;; Break that line at spaces, to avoid very long lines. - ;; Make each sub-line into a comment. - (with-current-buffer outbuf - (save-excursion - (forward-line -1) - (while (not (eolp)) - (move-to-column 64) - (skip-chars-forward "^ \n") - (or (eolp) - (insert "\n" generate-autoload-section-continuation))))) + (autoload-insert-section-header outbuf autoloads-done load-name file + (nth 5 (file-attributes file))) (insert ";;; Generated autoloads from " (autoload-trim-file-name file) "\n") (goto-char output-end) @@ -353,14 +377,16 @@ ;;;###autoload (defun update-file-autoloads (file) "Update the autoloads for FILE in `generated-autoload-file' -\(which FILE might bind in its local variables)." +\(which FILE might bind in its local variables). +Return FILE if there was no autoload cookie in it." (interactive "fUpdate autoloads for file: ") (let ((load-name (let ((name (file-name-nondirectory file))) (if (string-match "\\.elc?$" name) (substring name 0 (match-beginning 0)) name))) (found nil) - (existing-buffer (get-file-buffer file))) + (existing-buffer (get-file-buffer file)) + (no-autoloads nil)) (save-excursion ;; We want to get a value for generated-autoload-file from ;; the local variables section if it's there. @@ -370,9 +396,10 @@ ;; but still decode EOLs. (let ((coding-system-for-read 'raw-text)) (set-buffer (find-file-noselect - (expand-file-name generated-autoload-file - (expand-file-name "lisp" - source-directory)))) + (autoload-ensure-default-file + (expand-file-name generated-autoload-file + (expand-file-name "lisp" + source-directory))))) ;; This is to make generated-autoload-file have Unix EOLs, so ;; that it is portable to all platforms. (setq buffer-file-coding-system 'raw-text-unix)) @@ -397,10 +424,7 @@ (if (and (or (null existing-buffer) (not (buffer-modified-p existing-buffer))) (listp last-time) (= (length last-time) 2) - (or (> (car last-time) (car file-time)) - (and (= (car last-time) (car file-time)) - (>= (nth 1 last-time) - (nth 1 file-time))))) + (not (autoload-before-p last-time file-time))) (progn (if (interactive-p) (message "\ @@ -450,13 +474,26 @@ nil (if (interactive-p) (message "%s has no autoloads" file)) + (setq no-autoloads t) t) (or existing-buffer (kill-buffer (current-buffer)))))))) (generate-file-autoloads file)))) (and (interactive-p) (buffer-modified-p) - (save-buffer))))) + (save-buffer)) + + (if no-autoloads file)))) + +(defun autoload-before-p (time1 time2) + (or (< (car time1) (car time2)) + (and (= (car time1) (car time2)) + (< (nth 1 time1) (nth 1 time2))))) + +(defun autoload-remove-section (begin) + (goto-char begin) + (search-forward generate-autoload-section-trailer) + (delete-region begin (point))) ;;;###autoload (defun update-autoloads-from-directories (&rest dirs) @@ -464,37 +501,67 @@ Update loaddefs.el with all the current autoloads from DIRS, and no old ones. This uses `update-file-autoloads' (which see) do its work." (interactive "DUpdate autoloads from directory: ") - (let ((files (apply 'nconc - (mapcar (function (lambda (dir) - (directory-files (expand-file-name dir) - t - "^[^=.].*\\.el$"))) - dirs))) - autoloads-file - top-dir) - (setq autoloads-file + (let* ((files (apply 'nconc + (mapcar (lambda (dir) + (directory-files (expand-file-name dir) + ;; FIXME: add .gz etc... + t "^[^=.].*\\.el\\'")) + dirs))) + (this-time (current-time)) + (no-autoloads nil) ;files with no autoload cookies. + (autoloads-file (expand-file-name generated-autoload-file - (expand-file-name "lisp" - source-directory))) - (setq top-dir (file-name-directory autoloads-file)) - (save-excursion - (set-buffer (find-file-noselect autoloads-file)) + (expand-file-name "lisp" source-directory))) + (top-dir (file-name-directory autoloads-file))) + + (with-current-buffer + (find-file-noselect (autoload-ensure-default-file autoloads-file)) (save-excursion + + ;; Canonicalize file names and remove the autoload file itself. + (setq files (delete (autoload-trim-file-name buffer-file-name) + (mapcar 'autoload-trim-file-name files))) + (goto-char (point-min)) (while (search-forward generate-autoload-section-header nil t) (let* ((form (autoload-read-section-header)) (file (nth 3 form))) - (cond ((not (stringp file))) + (cond ((and (consp file) (stringp (car file))) + ;; This is a list of files that have no autoload cookies. + ;; There shouldn't be more than one such entry. + ;; Remove the obsolete section. + (autoload-remove-section (match-beginning 0)) + (let ((last-time (nth 4 form))) + (dolist (file file) + (let ((file-time (nth 5 (file-attributes file)))) + (when (and file-time + (not (autoload-before-p last-time + file-time))) + ;; file unchanged + (push file no-autoloads) + (setq files (delete file files))))))) + ((not (stringp file))) ((not (file-exists-p (expand-file-name file top-dir))) ;; Remove the obsolete section. - (let ((begin (match-beginning 0))) - (search-forward generate-autoload-section-trailer) - (delete-region begin (point)))) + (autoload-remove-section (match-beginning 0))) + ((equal (nth 4 form) (nth 5 (file-attributes file))) + ;; File hasn't changed. + nil) (t (update-file-autoloads file))) (setq files (delete file files))))) - ;; Elements remaining in FILES have no existing autoload sections. - (mapcar 'update-file-autoloads files) + ;; Elements remaining in FILES have no existing autoload sections yet. + (setq no-autoloads + (append no-autoloads + (delq nil (mapcar 'update-file-autoloads files)))) + (when no-autoloads + ;; Add the `no-autoloads' section. + (goto-char (point-max)) + (search-backward "\f" nil t) + (autoload-insert-section-header + (current-buffer) nil nil no-autoloads this-time) + (insert generate-autoload-section-trailer)) + (save-buffer)))) ;;;###autoload