From: Alan Mackenzie <acm@muc.de>
To: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: Glenn Morris <rgm@gnu.org>, Chong Yidong <cyd@stupidchicken.com>,
emacs-devel@gnu.org
Subject: Re: Refactoring of emacs-lisp/autoload.el
Date: Mon, 1 Sep 2008 21:55:14 +0000 [thread overview]
Message-ID: <20080901215514.GA12241@muc.de> (raw)
In-Reply-To: <jwvd4kb5vuf.fsf-monnier+emacs@gnu.org>
Hello, Stefan!
On Thu, Aug 14, 2008 at 01:52:24PM -0400, Stefan Monnier wrote:
> >> Yes, that sounds fine.
> > What I'll be doing is sorting the "no-autoloads" list so that it's in the
> > same order as the file entries. I can then loop through all the files,
> > testing in turn whether the file was a "no-autoload" or had its own
> > section, and take the appropriate action. That will mean never having to
> > search loaddefs.el for an entry, and not having to use `member' in the
> > "no-autoloads" list, since I will be stepping through both from start to
> > finish.
> Sounds fine. Tho using member hasn't been a problem until now (even
> with its O(n^2) behavior), so I wouldn't waste any time trying to avoid it.
I've done all of what I suggested to autoloads.el; the patch is here
(although as yet without a ChangeLog entry). Additionally, I have
introduced a new file local variable (`autoload-format-revision') to
facilitate the conversion of an "old" loaddefs.el file to a new. This
update happens transparently to the hacker.
I've fixed what might be a bug in the future: in the old version, two
files with the same base name could not both have entries in
loaddefs.el. In the new one, they can. (There are 3 files called
"subdirs.el" in the no-autoloads list.). This change makes the presence
of the "bare name" in a header (this one:
There's a slight awkwardness in this new version. Two files
(ps-print.el and emulation/tpu-edt.el) are both sources and destinations
for autoloads. They both get changed _after_ their entries are written
to loaddefs.el. This makes no difference to the functionality of
loaddefs.el.
;;;### (autoloads (list-one-abbrev-table) "abbrevlist" "abbrevlist.el"
;;;;;; (18494 62405))
;;; Generated autoloads from abbrevlist.el
^^^^^^^^^^^^
||||||||||||
), redundant. I haven't changed this part of the format, though.
The new version is quite a bit faster than the old for most uses. It is
quite a bit slower (~2 seconds, factor 2) for the null case (where
nothing needs updating). I haven't managed to work out why this is the
case. It might not be too important.
Here are some comparitive timings, done under fair conditions, on my 1.2
GHz Athlon. All were generated by the command % time make autoloads. I
am puzzled as to why my new version is slower in the null case. It is
considerably faster doing a complete build (factor ~1.6) and doing a
substantial update (~100 files, same factor).
1/- From scratch:
OLD NEW
real 1m11.570s 0m38.075s
user 0m55.251s 0m22.167s
sys 0m15.867s 0m15.438s
2/- A null invocation (immediately after 1/-)
real 0m2.039s 0m4.204s <-----------
user 0m1.561s 0m3.393s
sys 0m0.428s 0m0.575s
3/- Second null invocation (immediately after 2/-)
real 0m2.297s 0m3.643s <-----------
user 0m1.538s 0m2.968s
sys 0m0.726s 0m0.663s
4/- After updating .../emacs/lisp (108 .el files changed)
real 0m15.211s 0m9.114s
user 0m10.094s 0m6.168s
sys 0m4.981s 0m2.871s
So, here's the patch (which is actually bigger than the source file).
Should I install it?
Index: autoload.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/emacs-lisp/autoload.el,v
retrieving revision 1.142
diff -c -r1.142 autoload.el
*** autoload.el 10 Jun 2008 09:02:38 -0000 1.142
--- autoload.el 1 Sep 2008 21:18:00 -0000
***************
*** 42,47 ****
--- 42,54 ----
;;;###autoload
(put 'generated-autoload-file 'safe-local-variable 'stringp)
+ (defvar autoload-format-revision nil
+ "If this file-local variable is missing, we have an \"old-style\" file.
+ This is used exclusively in the local variables section of
+ loaddefs.el and similar files. If it is absent from such a file,
+ the file's format needs to be updated by % make autoloads, etc.")
+ (put 'autoload-format-revision 'safe-local-variable 'numberp)
+
;; This feels like it should be a defconst, but MH-E sets it to
;; ";;;###mh-autoload" for the autoloads that are to go into mh-loaddefs.el.
(defvar generate-autoload-cookie ";;;###autoload"
***************
*** 69,74 ****
--- 76,387 ----
(defvar autoload-modified-buffers) ;Dynamically scoped var.
+ ;; Forms which have doc-strings which should be printed specially.
+ ;; A doc-string-elt property of ELT says that (nth ELT FORM) is
+ ;; the doc-string in FORM.
+ ;; Those properties are now set in lisp-mode.el.
+ (defvar no-update-autoloads nil
+ "File local variable to prevent scanning this file for autoload cookies.")
+
+ (defun autoload-file-load-name (file)
+ (let ((name (file-name-nondirectory file)))
+ (if (string-match "\\.elc?\\(\\.\\|\\'\\)" name)
+ (substring name 0 (match-beginning 0))
+ name)))
+
+ (defun autoload-file-name< (f1 f2)
+ "Is file name F1 \"less than\" file name F2?
+
+ F1 and F2 are file names, either both absolute or both relative
+ to the same place.
+
+ Comparison is done by string<, primarily on the \"bare name\",
+ and secondarily on the directory."
+ (let ((bare1 (file-name-sans-extension (file-name-nondirectory f1)))
+ (bare2 (file-name-sans-extension (file-name-nondirectory f2))))
+ (or (string< bare1 bare2)
+ (and (string= bare1 bare2)
+ (string< (or (file-name-directory f1) "")
+ (or (file-name-directory f2) ""))))))
+
+ \f
+ (defun autoload-read-section-header ()
+ "Read the section header, if any, at the current position.
+ Point should be at the ^L at the start of a section.
+ Return the header, or nil."
+ ;; Since continuation lines have been marked as comments,
+ ;; we must copy the text of the form and remove those comment
+ ;; markers before we call `read'."
+ (save-excursion
+ (save-match-data
+ (when (looking-at generate-autoload-section-header)
+ (goto-char (match-end 0))
+ (let ((beginning (point))
+ string)
+ (forward-line 1)
+ (while (looking-at generate-autoload-section-continuation)
+ (forward-line 1))
+ (setq string (buffer-substring beginning (point)))
+ (with-current-buffer (get-buffer-create " *autoload*")
+ (erase-buffer)
+ (insert string)
+ (goto-char (point-min))
+ (while (search-forward generate-autoload-section-continuation nil t)
+ (replace-match " "))
+ (goto-char (point-min))
+ (read (current-buffer))))))))
+
+ (defun autoload-rubric (file &optional type)
+ "Return a string giving the appropriate autoload rubric for FILE.
+ TYPE (default \"autoloads\") is a string stating the type of
+ information contained in FILE."
+ (let ((basename (file-name-nondirectory file)))
+ (concat ";;; " basename
+ " --- automatically extracted " (or type "autoloads") "\n"
+ ";;\n"
+ ";;; Code:\n\n"
+ "\f\n"
+ "(provide '" (file-name-sans-extension basename) ")\n"
+ ";; Local Variables:\n"
+ ";; version-control: never\n"
+ ";; no-byte-compile: t\n"
+ ";; no-update-autoloads: t\n"
+ ";; coding: utf-8\n"
+ ";; autoload-format-revision: 1\n" ; New, 2008-08.
+ ";; End:\n"
+ ";;; " basename
+ " ends here\n")))
+
+ (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 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 autoload-forward-section (outbuf)
+ "Point in OUTBUF is at the ^L of a section. Move forward to the next.
+ Throw an error if there is no next section."
+ (with-current-buffer outbuf
+ (forward-char)
+ (unless (search-forward "\f" nil t)
+ (error "autoload-forward-section has failed"))
+ (backward-char)))
+
+ (defun autoload-delete-current-section (outbuf)
+ "Delete the current section from OUTBUF (e.g. loaddefs.el).
+ Point is at the ^L at the start of the section."
+ (with-current-buffer outbuf
+ (let ((begin (point)))
+ (search-forward generate-autoload-section-trailer)
+ (delete-region begin (point)))))
+
+ (defun autoload-delete-upto-and-get-section-header-for (name outbuf)
+ "Get the section header from OUTBUF for NAME, deleting others.
+
+ OUTBUF is the buffer for, e.g. loaddefs.el.
+ NAME is the full name for the pertinent source file.
+
+ Point must be at the ^L at the start of a section.
+
+ If there are any sections in OUTBUF for files alphabetically
+ earlier than FILE and these files no longer exist, delete the
+ sections from OUTBUF.
+
+ Return the header for NAME, or nil if it doesn't exist."
+ (with-current-buffer outbuf
+ (let* ((relname (file-relative-name name))
+ (header (autoload-read-section-header))
+ (header-relname (and header (nth 3 header))))
+ (while (and header-relname (autoload-file-name< header-relname relname))
+ (if (file-exists-p (nth 3 header))
+ (autoload-forward-section outbuf)
+ (autoload-delete-current-section outbuf))
+ (setq header (autoload-read-section-header)
+ header-relname (nth 3 header)))
+ (and (string= relname header-relname)
+ header))))
+
+ (defun autoload-ensure-unix-eols ()
+ "Set the buffer file coding system to use unix EOLs, if needed."
+ (unless (let ((eol-type (coding-system-eol-type buffer-file-coding-system)))
+ (cond ((and (numberp eol-type) (zerop eol-type)))
+ ((vectorp eol-type)
+ (set-buffer-file-coding-system (aref eol-type 0)))
+ (t (set-buffer-file-coding-system 'unix))))))
+
+ (defun autoload-insert-format-revision (outbuf)
+ "Insert a local definition of `autoload-format-revision' into OUTBUF.
+ This is needed only when an old style loaddefs.el is converted to
+ a new style one, and done only when there is an existing Local
+ Variables section."
+ (with-current-buffer outbuf
+ (save-excursion
+ (widen)
+ (goto-char (point-max))
+ (when (search-backward "\n;; End:" (- (point) 200) t)
+ (insert "\n;; autoload-format-revision: 1")))))
+
+ (defun autoload-init-out-buffer (out-file)
+ "Prepare a buffer \(e.g. loaddefs.el) for outputting autoload cookies.
+ OUT-FILE is the file name of this buffer.
+
+ The return value is the buffer.
+
+ \"Prepare\" means:
+ 1. If OUT-FILE doesn't yet exist and there isn't a buffer for
+ it, create its buffer and initialize it with boilerplate;
+ 2. move to the first file entry in the buffer (or where it
+ would be); this is at a ^L;
+ 3. Make sure the buffer's coding system is set for UNIX eols."
+ (let ((outbuf
+ (or (get-file-buffer out-file)
+ (and (file-exists-p out-file)
+ (find-file-noselect out-file))
+ (find-file-noselect out-file))))
+
+ (with-current-buffer outbuf
+ (if (= (buffer-size outbuf) 0)
+ (progn (or (file-writable-p out-file)
+ (error "Autoloads file %s is not writable" out-file))
+ (insert (autoload-rubric out-file))
+ (set (make-local-variable 'autoload-format-revision) 1)
+ (search-backward "\f"))
+ (goto-char 0)
+ (search-forward "\f")
+ (backward-char))
+ (autoload-ensure-unix-eols))
+ outbuf))
+
+ \f
+ (defun autoload-replace-or-write-no-list (no-autoloads outbuf this-time)
+ "Write the \"no autoloads\" section to the right place in OUTBUF.
+ This includes deleting any existing \"no autoloads\" section.
+
+ NO-AUTOLOADS is the \(already sorted) list of files without autoloads.
+ OUTBUF is the buffer for the main autoload file, usually loaddefs.el.
+ THIS-TIME is the time the current updating operation started."
+ (with-current-buffer outbuf
+ (widen)
+ (goto-char (point-max))
+ (or (search-backward "\f" nil t)
+ (error
+ "autoload-replace-or-write-no-list: uninitialized buffer %s" outbuf))
+ (let (header)
+ (save-excursion
+ (if (and (search-backward "\f" nil t)
+ (looking-at generate-autoload-section-header)
+ (setq header (autoload-read-section-header))
+ (null (nth 1 header))
+ (null (nth 2 header))
+ (listp (nth 3 header)))
+ (autoload-delete-current-section outbuf))))
+
+ (autoload-insert-section-header
+ (current-buffer) nil nil no-autoloads this-time)
+ (insert generate-autoload-section-trailer)))
+
+ (defun autoload-extract-no-list (outbuf)
+ "Get the list of files without autoloads from OUTBUF.
+ Return nil if there is no such list.
+ OUTBUF is a buffer in loaddefs.el format."
+ (with-current-buffer outbuf
+ (save-excursion
+ (widen)
+ (goto-char (point-max))
+ (and (search-backward "\f" nil t 2)
+ (looking-at generate-autoload-section-header)
+ (let ((header (autoload-read-section-header)))
+ (and (listp (nth 3 header))
+ (nth 3 header)))))))
+
+ (defun autoload-get-no-list-timestamp (outbuf)
+ "Get the timestamp of the no-autoloads list in OUTBUF.
+ Return nil is there isn't a no-autoloads list"
+ (with-current-buffer outbuf
+ (save-excursion
+ (widen)
+ (goto-char (point-max))
+ (and (search-backward "\f" nil t 2)
+ (looking-at generate-autoload-section-header)
+ (let ((header (autoload-read-section-header)))
+ (nth 4 header))))))
+
+ ;; The next two are defined in CL, not the Emacs core.
+ (defmacro caddr (arg) `(car (cdr (cdr ,arg))))
+ (defmacro cdddr (arg) `(cdr (cdr (cdr ,arg))))
+
+ (defun autoload-pull-from-no-list-upto (name no-list)
+ "Step over or delete entries from NO-LIST while they're <= NAME.
+ An entry is deleted (by setcdr'ing (cdr NO-LIST)) if the file it
+ points at no longer exists. Otherwise it is stepped over (by
+ changing PTR).
+
+ The current directory must be that of the output file \(usually
+ loaddefs.el) from which NO-LIST was read.
+
+ Return NAME, if it was found, or nil.
+
+ NAME is a filename, possibly with directory bits.
+
+ NO-LIST is a list whose cdr is the first element of the list of
+ pertinent filename entries."
+ (let* ((targ-relname (file-relative-name name))
+ relname)
+ (while (and (setq relname (caddr no-list))
+ (autoload-file-name< relname targ-relname))
+ (if (file-exists-p relname)
+ (setcdr no-list (cddr no-list)) ; step over
+ (setcdr (cdr no-list) (cdddr no-list)))) ; delete element from list
+
+ (and relname
+ (string= relname targ-relname)
+ name)))
+
+ (defun autoload-remove-cur-no-list-entry (no-list)
+ "Remove the current entry from the NO-LIST list.
+ NO-LIST is a list whose caddr is the current entry. The return
+ value is undefined."
+ (setcdr (cdr no-list) (cdddr no-list)))
+
+ (defun autoload-step-over-cur-no-list-entry (no-list)
+ "Step over the current entry in the NO-LIST list.
+ NO-LIST is a list whose caddr is the current entry. The return
+ value is undefined."
+ (setcdr no-list (cddr no-list)))
+
+ (defun autoload-insert-no-list-entry (file no-list def-out-buffer)
+ "Insert an entry for FILE into the NO-LIST list, and step past it.
+ FILE is an absolute file name.
+ NO-LIST is a list whose caddr is the current entry.
+ DEF-OUT-BUFFER is the default output buffer, usually
+ \"loaddefs.el\"; we use this to get a relative filename for FILE.
+ The return value is undefined."
+ (let ((relname
+ (file-relative-name
+ file
+ (file-name-directory (buffer-file-name def-out-buffer)))))
+ (setcdr (cdr no-list) (cons relname (cddr no-list))) ; insert new entry.
+ (setcdr no-list (cddr no-list)))) ; step over it.
+
+ (defun autoload-sort-no-autoload-list (no-list)
+ "Sort the no autoload list NO-LIST into the canonical order.
+ This is needed only when converting an older format file to the
+ new format."
+ (setcdr no-list (sort (cdr no-list) 'autoload-file-name<)))
+
+ \f
(defun make-autoload (form file)
"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
***************
*** 148,203 ****
;; nil here indicates that this is not a special autoload form.
(t nil))))
! ;; Forms which have doc-strings which should be printed specially.
! ;; A doc-string-elt property of ELT says that (nth ELT FORM) is
! ;; the doc-string in FORM.
! ;; Those properties are now set in lisp-mode.el.
!
! (defun autoload-generated-file ()
! (expand-file-name generated-autoload-file
! ;; File-local settings of generated-autoload-file should
! ;; be interpreted relative to the file's location,
! ;; of course.
! (if (not (local-variable-p 'generated-autoload-file))
! (expand-file-name "lisp" source-directory))))
!
!
! (defun autoload-read-section-header ()
! "Read a section header form.
! Since continuation lines have been marked as comments,
! we must copy the text of the form and remove those comment
! markers before we call `read'."
! (save-match-data
! (let ((beginning (point))
! string)
! (forward-line 1)
! (while (looking-at generate-autoload-section-continuation)
! (forward-line 1))
! (setq string (buffer-substring beginning (point)))
! (with-current-buffer (get-buffer-create " *autoload*")
! (erase-buffer)
! (insert string)
! (goto-char (point-min))
! (while (search-forward generate-autoload-section-continuation nil t)
! (replace-match " "))
! (goto-char (point-min))
! (read (current-buffer))))))
!
! (defvar autoload-print-form-outbuf nil
! "Buffer which gets the output of `autoload-print-form'.")
!
! (defun autoload-print-form (form)
"Print FORM such that `make-docfile' will find the docstrings.
! The variable `autoload-print-form-outbuf' specifies the buffer to
! put the output in."
(cond
;; If the form is a sequence, recurse.
! ((eq (car form) 'progn) (mapcar 'autoload-print-form (cdr form)))
;; Symbols at the toplevel are meaningless.
((symbolp form) nil)
(t
! (let ((doc-string-elt (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
;; doc-string must be printed specially for
--- 461,477 ----
;; nil here indicates that this is not a special autoload form.
(t nil))))
! (defun autoload-print-form (form outbuf)
"Print FORM such that `make-docfile' will find the docstrings.
! OUTBUF specifies the buffer to put the output in."
(cond
;; If the form is a sequence, recurse.
! ((eq (car form) 'progn)
! (mapcar (lambda (f) (autoload-print-form f outbuf)) (cdr form)))
;; Symbols at the toplevel are meaningless.
((symbolp form) nil)
(t
! (let ((doc-string-elt (get (car-safe form) 'doc-string-elt)))
(if (and doc-string-elt (stringp (nth doc-string-elt form)))
;; We need to hack the printing because the
;; doc-string must be printed specially for
***************
*** 235,283 ****
(print-escape-nonascii t))
(print form outbuf)))))))
! (defun autoload-rubric (file &optional type)
! "Return a string giving the appropriate autoload rubric for FILE.
! TYPE (default \"autoloads\") is a string stating the type of
! information contained in FILE."
! (let ((basename (file-name-nondirectory file)))
! (concat ";;; " basename
! " --- automatically extracted " (or type "autoloads") "\n"
! ";;\n"
! ";;; Code:\n\n"
! "\f\n"
! "(provide '" (file-name-sans-extension basename) ")\n"
! ";; Local Variables:\n"
! ";; version-control: never\n"
! ";; no-byte-compile: t\n"
! ";; no-update-autoloads: t\n"
! ";; coding: utf-8\n"
! ";; End:\n"
! ";;; " basename
! " ends here\n")))
! (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 (autoload-rubric file) 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 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 autoload-find-file (file)
"Fetch file and put it in a temp buffer. Return the buffer."
--- 509,653 ----
(print-escape-nonascii t))
(print form outbuf)))))))
! (defun autoload-extract-cookie (outbuf file)
! "Extract the autoload cookie at point, and write it into OUTBUF.
! Point is just after the autoload cookie \(usually \";;;###autoload\")
! on entry, and is left just after the autoload form on exit.
!
! OUTBUF is the buffer (typically, loaddefs.el) into which we
! insert the new cookie at the buffer's current position.
!
! FILE is the absolute name of the elisp source file containing the
! cookie.
!
! Return the name defined (a symbol), or nil if there wasn't one."
! (let ((load-name (autoload-file-load-name file))
! cookie-name)
! (skip-chars-forward " \t")
! (if (eolp)
! (condition-case err
! ;; Read the next form and make an autoload.
! (let* ((form (prog1 (read (current-buffer))
! (or (bolp) (forward-line 1))))
! (autoload (make-autoload form load-name)))
! (if autoload
! (setq cookie-name (nth 1 form))
! (setq autoload form))
! (autoload-print-form autoload outbuf))
! (error
! (message "Error in %s: %S" file err)))
!
! ;; Copy the rest of the line to the output.
! (princ (buffer-substring
! (progn
! ;; Back up over whitespace, to preserve it.
! (skip-chars-backward " \f\t")
! (if (= (char-after (1+ (point))) ? )
! ;; Eat one space.
! (forward-char 1))
! (point))
! (progn (forward-line 1) (point)))
! outbuf))
! cookie-name))
!
! (defun autoload-parse-source-buffer (inbuf file)
! "Extract the autoload specs, if any, from the buffer INBUF,
! writing them to the buffer whose file name is in the the variable
! `generated-autoload-file' \(which may have a file-local binding in
! INBUF). The buffer isn't saved in this function.
!
! FILE is the absolute name of the elisp source file loaded in the
! current buffer.
!
! The current directory is the \"starting directory\" for the
! autoload generation, typically .../emacs/lisp/.
!
! If the buffer for `generated-autoload-file' is actually written
! to, return this buffer. Otherwise, return nil."
! (let (autoloads-done ; list of autoload SYMBOLS written to output buffer.
! (load-name (autoload-file-load-name file))
! (relfile (file-relative-name file)) ; relative to starting directory.
! relfile-out ; ditto, relative to `generated-autoload-file'.
! cookie
! (cookie-regexp (concat "^" (regexp-quote generate-autoload-cookie)))
! outbuf
! output-started ; Position in outbuf of first cookie generated from
! ; current input file, or nil.
! (print-length nil) ; don't truncate a list when printing.
! (print-level nil) ; don't limit nesting of lists when printing.
! ;; (print-readably t) ; This does something in XEmacs. Removed 2008-08.
! (float-output-format nil)) ; Use a default format for printing floats.
!
! (with-current-buffer inbuf
! (unless no-update-autoloads
! (message "Generating autoloads for %s..." relfile)
! (save-excursion
! (save-restriction
! (widen)
! (goto-char (point-min))
! (while (search-forward-regexp cookie-regexp nil t)
! ;; Get the output buffer only when the first cookie has been found.
! (unless outbuf
! (setq outbuf
! (or (get-file-buffer generated-autoload-file)
! (autoload-init-out-buffer generated-autoload-file))
! output-started (with-current-buffer outbuf (point)))
! ;; Update OUTBUF to new format, if needed.
! (unless (local-variable-p 'autoload-format-revision outbuf)
! (autoload-insert-format-revision outbuf)
! (set (make-local-variable 'autoload-format-revision) 1)))
! (if (setq cookie (autoload-extract-cookie outbuf file))
! (push cookie autoloads-done)))
!
! ;; Write the section header for FILE into OUTBUF. This contains a
! ;; summary list of functions at the beginning of the section in
! ;; the output file.
! (when outbuf
! (let ((date-or-checksum
! (if (local-variable-p 'generated-autoload-file)
! ;; MD5 checksums are much better because they do not
! ;; change unless the file changes (so they'll be equal
! ;; on two different systems and will change less often
! ;; than time-stamps, thus leading to fewer unneeded
! ;; changes causing spurious conflicts), but using
! ;; time-stamps is a very useful optimization, so we
! ;; use time-stamps for the main autoloads file
! ;; (loaddefs.el) where we have special ways to
! ;; circumvent the "random change problem", and MD5
! ;; checksum in secondary autoload files where we do
! ;; not need the time-stamp optimization because it is
! ;; already provided by the primary autoloads file.
! (md5 (current-buffer) nil nil 'emacs-mule-unix)
! (nth 5 (file-attributes file))))) ; timestamp.
! (with-current-buffer outbuf
! (setq relfile-out (file-relative-name file))
! (save-excursion
! ;; Insert the section-header line which lists the file name
! ;; and which functions are in it, etc.
! (goto-char output-started)
! (autoload-insert-section-header
! outbuf autoloads-done load-name relfile-out
! date-or-checksum)
! (insert ";;; Generated autoloads from " relfile-out "\n"))
! (insert generate-autoload-section-trailer))))))
! (message "Generating autoloads for %s...done" relfile)
! outbuf))))
! \f
! (defun autoload-touched-p (file timestamp-md5 &optional buffer)
! "Has FILE a later timestamp than or different md5 sum from TIMESTAMP-MD5?
! FILE is the absolute name of the file.
! TIMESTAMP-MD5 is the timestamp or MD5 sum of the file in its
! exisiting entry, or NIL.
! BUFFER, if supplied, is FILE's buffer. It is ignored for a
! timestamp and must be supplied for an MD5 sum."
! (cond
! ((consp timestamp-md5)
! (time-less-p timestamp-md5 (nth 5 (file-attributes file))))
! ((stringp timestamp-md5)
! (not (string-equal timestamp-md5 (md5 buffer nil nil 'emacs-mule-unix))))
! (t t))) ; null timestamp-md5, file is new.
(defun autoload-find-file (file)
"Fetch file and put it in a temp buffer. Return the buffer."
***************
*** 295,466 ****
(hack-local-variables))
(current-buffer)))
! (defvar no-update-autoloads nil
! "File local variable to prevent scanning this file for autoload cookies.")
!
! (defun autoload-file-load-name (file)
! (let ((name (file-name-nondirectory file)))
! (if (string-match "\\.elc?\\(\\.\\|\\'\\)" name)
! (substring name 0 (match-beginning 0))
! name)))
! (defun generate-file-autoloads (file)
! "Insert at point a loaddefs autoload section for FILE.
! Autoloads are generated for defuns and defmacros in FILE
! marked by `generate-autoload-cookie' (which see).
! 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: ")
! (autoload-generate-file-autoloads file (current-buffer)))
!
! ;; When called from `generate-file-autoloads' we should ignore
! ;; `generated-autoload-file' altogether. When called from
! ;; `update-file-autoloads' we don't know `outbuf'. And when called from
! ;; `update-directory-autoloads' it's in between: we know the default
! ;; `outbuf' but we should obey any file-local setting of
! ;; `generated-autoload-file'.
! (defun autoload-generate-file-autoloads (file &optional outbuf outfile)
! "Insert an autoload section for FILE in the appropriate buffer.
! Autoloads are generated for defuns and defmacros in FILE
! marked by `generate-autoload-cookie' (which see).
! If FILE is being visited in a buffer, the contents of the buffer are used.
! OUTBUF is the buffer in which the autoload statements should be inserted.
! If OUTBUF is nil, it will be determined by `autoload-generated-file'.
!
! If provided, OUTFILE is expected to be the file name of OUTBUF.
! If OUTFILE is non-nil and FILE specifies a `generated-autoload-file'
! different from OUTFILE, then OUTBUF is ignored.
!
! Return non-nil if and only if FILE adds no autoloads to OUTFILE
! \(or OUTBUF if OUTFILE is nil)."
! (catch 'done
! (let ((autoloads-done '())
! (load-name (autoload-file-load-name file))
! (print-length nil)
! (print-level nil)
! (print-readably t) ; This does something in Lucid Emacs.
! (float-output-format nil)
! (visited (get-file-buffer file))
! (otherbuf nil)
! (absfile (expand-file-name file))
! relfile
! ;; nil until we found a cookie.
! output-start)
!
! (with-current-buffer (or visited
! ;; It is faster to avoid visiting the file.
! (autoload-find-file file))
! ;; Obey the no-update-autoloads file local variable.
! (unless no-update-autoloads
! (message "Generating autoloads for %s..." file)
! (save-excursion
! (save-restriction
! (widen)
! (goto-char (point-min))
! (while (not (eobp))
! (skip-chars-forward " \t\n\f")
! (cond
! ((looking-at (regexp-quote generate-autoload-cookie))
! ;; If not done yet, figure out where to insert this text.
! (unless output-start
! (when (and outfile
! (not (equal outfile (autoload-generated-file))))
! ;; A file-local setting of autoload-generated-file says
! ;; we should ignore OUTBUF.
! (setq outbuf nil)
! (setq otherbuf t))
! (unless outbuf
! (setq outbuf (autoload-find-destination absfile))
! (unless outbuf
! ;; The file has autoload cookies, but they're
! ;; already up-to-date. If OUTFILE is nil, the
! ;; entries are in the expected OUTBUF, otherwise
! ;; they're elsewhere.
! (throw 'done outfile)))
! (with-current-buffer outbuf
! (setq relfile (file-relative-name absfile))
! (setq output-start (point)))
! ;; (message "file=%S, relfile=%S, dest=%S"
! ;; file relfile (autoload-generated-file))
! )
! (search-forward generate-autoload-cookie)
! (skip-chars-forward " \t")
! (if (eolp)
! (condition-case err
! ;; Read the next form and make an autoload.
! (let* ((form (prog1 (read (current-buffer))
! (or (bolp) (forward-line 1))))
! (autoload (make-autoload form load-name)))
! (if autoload
! (push (nth 1 form) autoloads-done)
! (setq autoload form))
! (let ((autoload-print-form-outbuf outbuf))
! (autoload-print-form autoload)))
! (error
! (message "Error in %s: %S" file err)))
!
! ;; Copy the rest of the line to the output.
! (princ (buffer-substring
! (progn
! ;; Back up over whitespace, to preserve it.
! (skip-chars-backward " \f\t")
! (if (= (char-after (1+ (point))) ? )
! ;; Eat one space.
! (forward-char 1))
! (point))
! (progn (forward-line 1) (point)))
! outbuf)))
! ((looking-at ";")
! ;; Don't read the comment.
! (forward-line 1))
! (t
! (forward-sexp 1)
! (forward-line 1))))))
!
! (when output-start
! (let ((secondary-autoloads-file-buf
! (if (local-variable-p 'generated-autoload-file)
! (current-buffer))))
! (with-current-buffer outbuf
! (save-excursion
! ;; Insert the section-header line which lists the file name
! ;; and which functions are in it, etc.
! (goto-char output-start)
! (autoload-insert-section-header
! outbuf autoloads-done load-name relfile
! (if secondary-autoloads-file-buf
! ;; MD5 checksums are much better because they do not
! ;; change unless the file changes (so they'll be
! ;; equal on two different systems and will change
! ;; less often than time-stamps, thus leading to fewer
! ;; unneeded changes causing spurious conflicts), but
! ;; using time-stamps is a very useful optimization,
! ;; so we use time-stamps for the main autoloads file
! ;; (loaddefs.el) where we have special ways to
! ;; circumvent the "random change problem", and MD5
! ;; checksum in secondary autoload files where we do
! ;; not need the time-stamp optimization because it is
! ;; already provided by the primary autoloads file.
! (md5 secondary-autoloads-file-buf
! ;; We'd really want to just use
! ;; `emacs-internal' instead.
! nil nil 'emacs-mule-unix)
! (nth 5 (file-attributes relfile))))
! (insert ";;; Generated autoloads from " relfile "\n"))
! (insert generate-autoload-section-trailer))))
! (message "Generating autoloads for %s...done" file))
! (or visited
! ;; We created this buffer, so we should kill it.
! (kill-buffer (current-buffer))))
! ;; If the entries were added to some other buffer, then the file
! ;; doesn't add entries to OUTFILE.
! (or (not output-start) otherbuf))))
! \f
! (defun autoload-save-buffers ()
! (while autoload-modified-buffers
! (with-current-buffer (pop autoload-modified-buffers)
! (save-buffer))))
;;;###autoload
(defun update-file-autoloads (file &optional save-after)
--- 665,767 ----
(hack-local-variables))
(current-buffer)))
! (defun autoload-maybe-parse-foreign-file (file inbuf)
! "Extract the autoloads from FILE, should FILE have changed,
! writing them into the buffer for `generated-autoload-file' \(a
! filename), WHICH HAS A BUFFER LOCAL VALUE in FILE.
!
! If the `generated-autoload-file' buffer is written to, return it.
! Otherwise return nil.
!
! FILE is the absolute file name of the elisp source file, and its
! buffer is INBUF."
! (with-current-buffer inbuf ; pick up buffer local `generated-...'.
! (let* ((outbuf (or (get-file-buffer generated-autoload-file)
! (autoload-init-out-buffer generated-autoload-file)))
! (header
! (autoload-delete-upto-and-get-section-header-for file outbuf)))
! (cond
! ((and header (autoload-touched-p file (nth 4 header) inbuf)) ; md5 check
! (autoload-delete-current-section outbuf)
! (autoload-parse-source-buffer inbuf file))
! ((null header)
! (autoload-parse-source-buffer inbuf file))
! (t nil)))))
!
! (defun autoload-maybe-parse-source-file (file no-list n-a-timestamp
! def-out-buffer)
! "Extract the autoloads from FILE, should FILE have changed,
! writing them into the buffer for `generated-autoload-file' \(a
! filename), which may have a buffer local value in FILE. If there
! were any autoloads, the output buffer, otherwise return nil.
!
! FILE is the absolute filename of an elisp source file.
!
! NO-LIST is a list whose cddr is the current element in a list of
! source files which, up till now, have contained no autoloads.
! This function may pop elements from this inner list by setcdr its
! structure and may step \(cdr no-list) to the next element.
!
! N-A-TIMESTAMP is the timestamp (NEVER an MD5 sum) of the existing
! no-autoloads list, or NIL.
!
! DEF-OUT-BUFFER is the default output buffer, usually \"loaddefs.el\".
!
! At the time of call, the current buffer is undefined.
!
! An essential side effect of this function is to remove entries
! from the alphabetically ordered \"loaddefs.el\" and NO-LIST for
! files which no longer exist, and to insert an entry into NO-LIST
! for FILE if it lacks autoloads."
! (let (inbuf visited file-header outbuf)
! (cond
! ;; Case 1. FILE is in the "no autoload" list. All files with their own
! ;; `generated-autoload-file' are also on this list.
! ((with-current-buffer def-out-buffer
! (autoload-pull-from-no-list-upto file no-list))
! (when (autoload-touched-p file n-a-timestamp)
! (setq visited (get-file-buffer file) ; is FILE already loaded?
! inbuf (or visited (autoload-find-file file)))
! (if (local-variable-p 'generated-autoload-file inbuf)
! (setq outbuf (autoload-maybe-parse-foreign-file file inbuf))
! (if (setq outbuf (autoload-parse-source-buffer inbuf file))
! (autoload-remove-cur-no-list-entry no-list)
! (autoload-step-over-cur-no-list-entry no-list)))))
!
! ;; Case 2. FILE has a section in the main loaddefs.el file, and hasn't
! ;; been changed since.
! ((and
! (setq file-header
! (autoload-delete-upto-and-get-section-header-for
! file def-out-buffer))
! (not (autoload-touched-p file (nth 4 file-header))))
! (autoload-forward-section def-out-buffer))
!
! ;; Case 3. File has a section in the main loaddefs.el buffer yet has
! ;; been changed.
! ;; We must load the file, so as to check `generated-autoload-file', which
! ;; may have changed. We could probably optimise this away, if we were
! ;; willing to rely only on a timestamp.
! ((setq file-header (autoload-delete-upto-and-get-section-header-for
! file def-out-buffer))
! (setq visited (get-file-buffer file) ; is FILE already loaded?
! inbuf (or visited (autoload-find-file file)))
! (autoload-delete-current-section def-out-buffer)
! (if (local-variable-p 'generated-autoload-file inbuf)
! (setq outbuf (autoload-maybe-parse-foreign-file file inbuf))
! (setq outbuf (autoload-parse-source-buffer inbuf file))))
!
! ;; Case 4. FILE is new. Scan it.
! (t
! (setq visited (get-file-buffer file) ; is FILE already loaded?
! inbuf (or visited (autoload-find-file file)))
! (with-current-buffer inbuf
! (unless (and (setq outbuf (autoload-parse-source-buffer inbuf file))
! (not (local-variable-p 'generated-autoload-file inbuf)))
! (autoload-insert-no-list-entry file no-list def-out-buffer)))))
! (if (and inbuf (not visited)) (kill-buffer inbuf))
! outbuf))
;;;###autoload
(defun update-file-autoloads (file &optional save-after)
***************
*** 471,561 ****
Return FILE if there was no autoload cookie in it, else nil."
(interactive "fUpdate autoloads for file: \np")
! (let* ((autoload-modified-buffers nil)
! (no-autoloads (autoload-generate-file-autoloads file)))
! (if autoload-modified-buffers
! (if save-after (autoload-save-buffers))
(if (interactive-p)
! (message "Autoload section for %s is up to date." file)))
! (if no-autoloads file)))
! (defun autoload-find-destination (file)
! "Find the destination point of the current buffer's autoloads.
! FILE is the file name of the current buffer.
! Returns a buffer whose point is placed at the requested location.
! Returns nil if the file's autoloads are uptodate, otherwise
! removes any prior now out-of-date autoload entries."
! (catch 'up-to-date
! (let* ((load-name (autoload-file-load-name file))
! (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.
! (find-file-noselect
! (autoload-ensure-default-file (autoload-generated-file)))
! ;; This is to make generated-autoload-file have Unix EOLs, so
! ;; that it is portable to all platforms.
! (unless (zerop (coding-system-eol-type buffer-file-coding-system))
! (set-buffer-file-coding-system 'unix))
! (or (> (buffer-size) 0)
! (error "Autoloads file %s does not exist" buffer-file-name))
! (or (file-writable-p buffer-file-name)
! (error "Autoloads file %s is not writable" buffer-file-name))
! (widen)
! (goto-char (point-min))
! ;; Look for the section for LOAD-NAME.
! (while (and (not found)
! (search-forward generate-autoload-section-header nil t))
! (let ((form (autoload-read-section-header)))
! (cond ((string= (nth 2 form) load-name)
! ;; We found the section for this file.
! ;; Check if it is up to date.
! (let ((begin (match-beginning 0))
! (last-time (nth 4 form))
! (file-time (nth 5 (file-attributes file))))
! (if (and (or (null existing-buffer)
! (not (buffer-modified-p existing-buffer)))
! (or
! ;; last-time is the time-stamp (specifying
! ;; the last time we looked at the file) and
! ;; the file hasn't been changed since.
! (and (listp last-time) (= (length last-time) 2)
! (not (time-less-p last-time file-time)))
! ;; last-time is an MD5 checksum instead.
! (and (stringp last-time)
! (equal last-time
! (md5 buf nil nil 'emacs-mule)))))
! (throw 'up-to-date nil)
! (autoload-remove-section begin)
! (setq found t))))
! ((string< load-name (nth 2 form))
! ;; We've come to a section alphabetically later than
! ;; LOAD-NAME. We assume the file is in order and so
! ;; there must be no section for LOAD-NAME. We will
! ;; insert one before the section here.
! (goto-char (match-beginning 0))
! (setq found t)))))
! (or found
! (progn
! ;; No later sections in the file. Put before the last page.
! (goto-char (point-max))
! (search-backward "\f" nil t)))
! (unless (memq (current-buffer) autoload-modified-buffers)
! (push (current-buffer) autoload-modified-buffers))
! (current-buffer)))))
!
! (defun autoload-remove-section (begin)
! (goto-char begin)
! (search-forward generate-autoload-section-trailer)
! (delete-region begin (point)))
;;;###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
directories as separate arguments, but this usage is discouraged.
--- 772,831 ----
Return FILE if there was no autoload cookie in it, else nil."
(interactive "fUpdate autoloads for file: \np")
! (let* ((generated-autoload-file (expand-file-name generated-autoload-file))
! ;; The above is needed to "anchor" g-a-f to the current directory;
! ;; otherwise it might be expanded relative to FILE's directory.
! (ffile (expand-file-name file))
! (def-out-buffer (autoload-init-out-buffer generated-autoload-file))
! (old-no-autoloads (autoload-extract-no-list def-out-buffer))
! (no-autoloads (cons "dummy" (copy-tree old-no-autoloads))) ; gets modified
! (cur-no-autoloads (cons nil no-autoloads)) ; "cur ptr" into no-autoloads.
! (no-autoload-timestamp (autoload-get-no-list-timestamp def-out-buffer))
! autoload-modified-buffer)
!
! ;; Upgrade an old loaddefs.el to the new format.
! (unless (local-variable-p 'autoload-format-revision def-out-buffer)
! (autoload-insert-format-revision def-out-buffer)
! (set (make-local-variable 'autoload-format-revision) 1)
! (autoload-sort-no-autoload-list no-autoloads))
!
! (setq autoload-modified-buffer
! (autoload-maybe-parse-source-file
! ffile
! cur-no-autoloads
! no-autoload-timestamp
! def-out-buffer))
!
! (if autoload-modified-buffer
! (if save-after
! (with-current-buffer autoload-modified-buffer (save-buffer)))
(if (interactive-p)
! (message "Autoload section for %s is up to date." file))
! file)))
! (defun autoload-init-file-list (dirs)
! "From DIRS, a list of directories, extract all pertinent files.
!
! Return them as absolute filenames, sorted by alphabetic ordering
! of their basenames without extension, as a list."
! (let* ((files-re (let ((tmp nil))
! (dolist (suf (get-load-suffixes)
! (concat "^[^=.].*" (regexp-opt tmp t) "\\'"))
! (unless (string-match "\\.elc" suf) (push suf tmp)))))
! (files
! (sort
! (apply 'nconc
! (mapcar (lambda (dir)
! (directory-files (expand-file-name dir)
! t files-re t)) ; _unsorted_ list.
! dirs))
! 'autoload-file-name<)))
! files))
;;;###autoload
(defun update-directory-autoloads (&rest dirs)
"\
Update loaddefs.el with all the current autoloads from DIRS, and no old ones.
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.
***************
*** 563,646 ****
The function does NOT recursively descend into subdirectories of the
directory or directories specified."
(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)))))
! (files (apply 'nconc
! (mapcar (lambda (dir)
! (directory-files (expand-file-name dir)
! t files-re))
! dirs)))
! (done ())
! (this-time (current-time))
! ;; 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))
!
! (with-current-buffer
! (find-file-noselect
! (autoload-ensure-default-file (autoload-generated-file)))
! (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)))
!
! (goto-char (point-min))
! (while (search-forward generate-autoload-section-header nil t)
! (let* ((form (autoload-read-section-header))
! (file (nth 3 form)))
! (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 (time-less-p last-time file-time)))
! ;; file unchanged
! (push file no-autoloads)
! (setq files (delete file files)))))))
! ((not (stringp file)))
! ((or (not (file-exists-p file))
! ;; Remove duplicates as well, just in case.
! (member file done))
! ;; Remove the obsolete section.
! (autoload-remove-section (match-beginning 0)))
! ((not (time-less-p (nth 4 form)
! (nth 5 (file-attributes file))))
! ;; File hasn't changed.
! nil)
! (t
! (autoload-remove-section (match-beginning 0))
! (if (autoload-generate-file-autoloads
! file (current-buffer) buffer-file-name)
! (push file no-autoloads))))
! (push file done)
! (setq files (delete file files)))))
! ;; Elements remaining in FILES have no existing autoload sections yet.
! (dolist (file files)
! (if (autoload-generate-file-autoloads file nil buffer-file-name)
! (push file no-autoloads)))
!
! (when no-autoloads
! ;; Sort them for better readability.
! (setq no-autoloads (sort no-autoloads 'string<))
! ;; 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)
! ;; In case autoload entries were added to other files because of
! ;; file-local autoload-generated-file settings.
! (autoload-save-buffers))))
(define-obsolete-function-alias 'update-autoloads-from-directories
'update-directory-autoloads "22.1")
--- 833,881 ----
The function does NOT recursively descend into subdirectories of the
directory or directories specified."
(interactive "DUpdate autoloads from directory: ")
! (let* ((files (autoload-init-file-list dirs)) ; absolute file names.
! (generated-autoload-file (expand-file-name generated-autoload-file))
! (def-out-buffer (autoload-init-out-buffer generated-autoload-file))
! (def-gen-dir (file-name-directory generated-autoload-file))
!
! (old-no-autoloads (autoload-extract-no-list def-out-buffer))
! (no-autoloads (cons "dummy" (copy-tree old-no-autoloads))) ; gets modified
! (cur-no-autoloads (cons nil no-autoloads)) ; "cur ptr" into no-autoloads.
! (no-autoload-timestamp (autoload-get-no-list-timestamp def-out-buffer))
!
! file
! autoload-buffer
! autoload-modified-buffers
! (this-time (current-time)))
!
! ;; Upgrade an old loaddefs.el to the new format.
! (unless (local-variable-p 'autoload-format-revision def-out-buffer)
! (autoload-insert-format-revision def-out-buffer)
! (set (make-local-variable 'autoload-format-revision) 1)
! (autoload-sort-no-autoload-list no-autoloads))
!
! (while files
! (setq file (car files) files (cdr files))
! (setq autoload-buffer
! (autoload-maybe-parse-source-file
! file
! cur-no-autoloads ; cur-no-autoloads gets setcdr'd.
! no-autoload-timestamp
! def-out-buffer))
! (when autoload-buffer
! (or (memq autoload-buffer autoload-modified-buffers)
! (push autoload-buffer autoload-modified-buffers))))
!
! ;; Has the no-autoloads list changed?
! (unless (equal old-no-autoloads (cdr no-autoloads))
! (autoload-replace-or-write-no-list (cdr no-autoloads)
! def-out-buffer this-time)
! (or (memq def-out-buffer autoload-modified-buffers)
! (push def-out-buffer autoload-modified-buffers)))
!
! (while autoload-modified-buffers
! (with-current-buffer (pop autoload-modified-buffers)
! (save-buffer)))))
(define-obsolete-function-alias 'update-autoloads-from-directories
'update-directory-autoloads "22.1")
> Stefan
--
Alan Mackenzie (Nuremberg, Germany).
prev parent reply other threads:[~2008-09-01 21:55 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-08-12 16:23 Refactoring of emacs-lisp/autoload.el Alan Mackenzie
2008-08-12 20:09 ` Stefan Monnier
2008-08-12 20:58 ` Glenn Morris
2008-08-13 14:13 ` Alan Mackenzie
2008-08-13 16:11 ` Glenn Morris
2008-08-13 14:11 ` Alan Mackenzie
2008-08-13 20:31 ` Stefan Monnier
2008-08-14 13:17 ` Alan Mackenzie
2008-08-14 17:52 ` Stefan Monnier
2008-09-01 21:55 ` Alan Mackenzie [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080901215514.GA12241@muc.de \
--to=acm@muc.de \
--cc=cyd@stupidchicken.com \
--cc=emacs-devel@gnu.org \
--cc=monnier@iro.umontreal.ca \
--cc=rgm@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.