changeset 39560:a05ad383618d

(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.
author Gerd Moellmann <gerd@gnu.org>
date Fri, 05 Oct 2001 09:29:11 +0000
parents 5851ee3f83f5
children 0881eab13b7a
files lisp/emacs-lisp/autoload.el
diffstat 1 files changed, 113 insertions(+), 46 deletions(-) [+]
line wrap: on
line diff
--- 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