Fix duplicate entries in cedet's loaddefs.el files.

* emacs-lisp/autoload.el (autoload-file-load-name): Be more clever.
Should make most file-local generated-autoload-file unnecessary.
(print-readably): Silence warnings.
(autoload-find-destination): Take load-name as an arg to make sure
it's the same as the one that will be in the file.
(autoload-generate-file-autoloads): Adjust to above changes.
Try to make the dataflow a bit simpler.
This commit is contained in:
Stefan Monnier 2010-04-18 17:45:44 -04:00
parent 8a37fb25cb
commit f8ea0098d9
2 changed files with 94 additions and 55 deletions

View file

@ -1,5 +1,14 @@
2010-04-18 Stefan Monnier <monnier@iro.umontreal.ca> 2010-04-18 Stefan Monnier <monnier@iro.umontreal.ca>
Fix duplicate entries in cedet's loaddefs.el files.
* emacs-lisp/autoload.el (autoload-file-load-name): Be more clever.
Should make most file-local generated-autoload-file unnecessary.
(print-readably): Silence warnings.
(autoload-find-destination): Take load-name as an arg to make sure
it's the same as the one that will be in the file.
(autoload-generate-file-autoloads): Adjust to above changes.
Try to make the dataflow a bit simpler.
* cvs-status.el (cvs-refontify): Remove unused. * cvs-status.el (cvs-refontify): Remove unused.
2010-04-18 Jay Belanger <jay.p.belanger@gmail.com> 2010-04-18 Jay Belanger <jay.p.belanger@gmail.com>

View file

@ -328,7 +328,29 @@ which lists the file name and which functions are in it, etc."
"File local variable to prevent scanning this file for autoload cookies.") "File local variable to prevent scanning this file for autoload cookies.")
(defun autoload-file-load-name (file) (defun autoload-file-load-name (file)
(let ((name (file-name-nondirectory file))) "Compute the name that will be used to load FILE."
;; OUTFILE should be the name of the global loaddefs.el file, which
;; is expected to be at the root directory of the files we're
;; scanning for autoloads and will be in the `load-path'.
(let* ((outfile (default-value 'generated-autoload-file))
(name (file-relative-name file (file-name-directory outfile)))
(names '())
(dir (file-name-directory outfile)))
;; If `name' has directory components, only keep the
;; last few that are really needed.
(while name
(setq name (directory-file-name name))
(push (file-name-nondirectory name) names)
(setq name (file-name-directory name)))
(while (not name)
(cond
((null (cdr names)) (setq name (car names)))
((file-exists-p (expand-file-name "subdirs.el" dir))
;; FIXME: here we only check the existence of subdirs.el,
;; without checking its content. This makes it generate wrong load
;; names for cases like lisp/term which is not added to load-path.
(setq dir (expand-file-name (pop names) dir)))
(t (setq name (mapconcat 'identity names "/")))))
(if (string-match "\\.elc?\\(\\.\\|\\'\\)" name) (if (string-match "\\.elc?\\(\\.\\|\\'\\)" name)
(substring name 0 (match-beginning 0)) (substring name 0 (match-beginning 0))
name))) name)))
@ -343,6 +365,8 @@ Return non-nil in the case where no autoloads were added at point."
(interactive "fGenerate autoloads for file: ") (interactive "fGenerate autoloads for file: ")
(autoload-generate-file-autoloads file (current-buffer))) (autoload-generate-file-autoloads file (current-buffer)))
(defvar print-readably)
;; When called from `generate-file-autoloads' we should ignore ;; When called from `generate-file-autoloads' we should ignore
;; `generated-autoload-file' altogether. When called from ;; `generated-autoload-file' altogether. When called from
;; `update-file-autoloads' we don't know `outbuf'. And when called from ;; `update-file-autoloads' we don't know `outbuf'. And when called from
@ -373,9 +397,8 @@ Return non-nil if and only if FILE adds no autoloads to OUTFILE
(visited (get-file-buffer file)) (visited (get-file-buffer file))
(otherbuf nil) (otherbuf nil)
(absfile (expand-file-name file)) (absfile (expand-file-name file))
relfile
;; nil until we found a cookie. ;; nil until we found a cookie.
output-start) output-start ostart)
(with-current-buffer (or visited (with-current-buffer (or visited
;; It is faster to avoid visiting the file. ;; It is faster to avoid visiting the file.
(autoload-find-file file)) (autoload-find-file file))
@ -385,7 +408,10 @@ Return non-nil if and only if FILE adds no autoloads to OUTFILE
(setq load-name (setq load-name
(if (stringp generated-autoload-load-name) (if (stringp generated-autoload-load-name)
generated-autoload-load-name generated-autoload-load-name
(autoload-file-load-name file))) (autoload-file-load-name absfile)))
(when (and outfile
(not (equal outfile (autoload-generated-file))))
(setq otherbuf t))
(save-excursion (save-excursion
(save-restriction (save-restriction
(widen) (widen)
@ -396,26 +422,22 @@ Return non-nil if and only if FILE adds no autoloads to OUTFILE
((looking-at (regexp-quote generate-autoload-cookie)) ((looking-at (regexp-quote generate-autoload-cookie))
;; If not done yet, figure out where to insert this text. ;; If not done yet, figure out where to insert this text.
(unless output-start (unless output-start
(when (and outfile (let ((outbuf
(not (equal outfile (autoload-generated-file)))) (or (if otherbuf
;; A file-local setting of autoload-generated-file says ;; A file-local setting of
;; we should ignore OUTBUF. ;; autoload-generated-file says we
(setq outbuf nil) ;; should ignore OUTBUF.
(setq otherbuf t)) nil
(unless outbuf outbuf)
(setq outbuf (autoload-find-destination absfile)) (autoload-find-destination absfile load-name)
(unless outbuf ;; The file has autoload cookies, but they're
;; The file has autoload cookies, but they're ;; already up-to-date. If OUTFILE is nil, the
;; already up-to-date. If OUTFILE is nil, the ;; entries are in the expected OUTBUF,
;; entries are in the expected OUTBUF, otherwise ;; otherwise they're elsewhere.
;; they're elsewhere. (throw 'done otherbuf))))
(throw 'done outfile))) (with-current-buffer outbuf
(with-current-buffer outbuf (setq output-start (point-marker)
(setq relfile (file-relative-name absfile)) ostart (point)))))
(setq output-start (point)))
;; (message "file=%S, relfile=%S, dest=%S"
;; file relfile (autoload-generated-file))
)
(search-forward generate-autoload-cookie) (search-forward generate-autoload-cookie)
(skip-chars-forward " \t") (skip-chars-forward " \t")
(if (eolp) (if (eolp)
@ -427,7 +449,8 @@ Return non-nil if and only if FILE adds no autoloads to OUTFILE
(if autoload (if autoload
(push (nth 1 form) autoloads-done) (push (nth 1 form) autoloads-done)
(setq autoload form)) (setq autoload form))
(let ((autoload-print-form-outbuf outbuf)) (let ((autoload-print-form-outbuf
(marker-buffer output-start)))
(autoload-print-form autoload))) (autoload-print-form autoload)))
(error (error
(message "Error in %s: %S" file err))) (message "Error in %s: %S" file err)))
@ -442,7 +465,7 @@ Return non-nil if and only if FILE adds no autoloads to OUTFILE
(forward-char 1)) (forward-char 1))
(point)) (point))
(progn (forward-line 1) (point))) (progn (forward-line 1) (point)))
outbuf))) (marker-buffer output-start))))
((looking-at ";") ((looking-at ";")
;; Don't read the comment. ;; Don't read the comment.
(forward-line 1)) (forward-line 1))
@ -454,40 +477,44 @@ Return non-nil if and only if FILE adds no autoloads to OUTFILE
(let ((secondary-autoloads-file-buf (let ((secondary-autoloads-file-buf
(if (local-variable-p 'generated-autoload-file) (if (local-variable-p 'generated-autoload-file)
(current-buffer)))) (current-buffer))))
(with-current-buffer outbuf (with-current-buffer (marker-buffer output-start)
(save-excursion (save-excursion
;; Insert the section-header line which lists the file name ;; Insert the section-header line which lists the file name
;; and which functions are in it, etc. ;; and which functions are in it, etc.
(assert (= ostart output-start))
(goto-char output-start) (goto-char output-start)
(autoload-insert-section-header (let ((relfile (file-relative-name absfile)))
outbuf autoloads-done load-name relfile (autoload-insert-section-header
(if secondary-autoloads-file-buf (marker-buffer output-start)
;; MD5 checksums are much better because they do not autoloads-done load-name relfile
;; change unless the file changes (so they'll be (if secondary-autoloads-file-buf
;; equal on two different systems and will change ;; MD5 checksums are much better because they do not
;; less often than time-stamps, thus leading to fewer ;; change unless the file changes (so they'll be
;; unneeded changes causing spurious conflicts), but ;; equal on two different systems and will change
;; using time-stamps is a very useful optimization, ;; less often than time-stamps, thus leading to fewer
;; so we use time-stamps for the main autoloads file ;; unneeded changes causing spurious conflicts), but
;; (loaddefs.el) where we have special ways to ;; using time-stamps is a very useful optimization,
;; circumvent the "random change problem", and MD5 ;; so we use time-stamps for the main autoloads file
;; checksum in secondary autoload files where we do ;; (loaddefs.el) where we have special ways to
;; not need the time-stamp optimization because it is ;; circumvent the "random change problem", and MD5
;; already provided by the primary autoloads file. ;; checksum in secondary autoload files where we do
(md5 secondary-autoloads-file-buf ;; not need the time-stamp optimization because it is
;; We'd really want to just use ;; already provided by the primary autoloads file.
;; `emacs-internal' instead. (md5 secondary-autoloads-file-buf
nil nil 'emacs-mule-unix) ;; We'd really want to just use
(nth 5 (file-attributes relfile)))) ;; `emacs-internal' instead.
(insert ";;; Generated autoloads from " relfile "\n")) nil nil 'emacs-mule-unix)
(nth 5 (file-attributes relfile))))
(insert ";;; Generated autoloads from " relfile "\n")))
(insert generate-autoload-section-trailer)))) (insert generate-autoload-section-trailer))))
(message "Generating autoloads for %s...done" file)) (message "Generating autoloads for %s...done" file))
(or visited (or visited
;; We created this buffer, so we should kill it. ;; We created this buffer, so we should kill it.
(kill-buffer (current-buffer)))) (kill-buffer (current-buffer))))
;; If the entries were added to some other buffer, then the file (or (not output-start)
;; doesn't add entries to OUTFILE. ;; If the entries were added to some other buffer, then the file
(or (not output-start) otherbuf)))) ;; doesn't add entries to OUTFILE.
otherbuf))))
(defun autoload-save-buffers () (defun autoload-save-buffers ()
(while autoload-modified-buffers (while autoload-modified-buffers
@ -511,15 +538,14 @@ Return FILE if there was no autoload cookie in it, else nil."
(message "Autoload section for %s is up to date." file))) (message "Autoload section for %s is up to date." file)))
(if no-autoloads file))) (if no-autoloads file)))
(defun autoload-find-destination (file) (defun autoload-find-destination (file load-name)
"Find the destination point of the current buffer's autoloads. "Find the destination point of the current buffer's autoloads.
FILE is the file name of the current buffer. FILE is the file name of the current buffer.
Returns a buffer whose point is placed at the requested location. Returns a buffer whose point is placed at the requested location.
Returns nil if the file's autoloads are uptodate, otherwise Returns nil if the file's autoloads are uptodate, otherwise
removes any prior now out-of-date autoload entries." removes any prior now out-of-date autoload entries."
(catch 'up-to-date (catch 'up-to-date
(let* ((load-name (autoload-file-load-name file)) (let* ((buf (current-buffer))
(buf (current-buffer))
(existing-buffer (if buffer-file-name buf)) (existing-buffer (if buffer-file-name buf))
(found nil)) (found nil))
(with-current-buffer (with-current-buffer
@ -532,7 +558,7 @@ removes any prior now out-of-date autoload entries."
(unless (zerop (coding-system-eol-type buffer-file-coding-system)) (unless (zerop (coding-system-eol-type buffer-file-coding-system))
(set-buffer-file-coding-system 'unix)) (set-buffer-file-coding-system 'unix))
(or (> (buffer-size) 0) (or (> (buffer-size) 0)
(error "Autoloads file %s does not exist" buffer-file-name)) (error "Autoloads file %s lacks boilerplate" buffer-file-name))
(or (file-writable-p buffer-file-name) (or (file-writable-p buffer-file-name)
(error "Autoloads file %s is not writable" buffer-file-name)) (error "Autoloads file %s is not writable" buffer-file-name))
(widen) (widen)
@ -652,6 +678,7 @@ directory or directories specified."
(t (t
(autoload-remove-section (match-beginning 0)) (autoload-remove-section (match-beginning 0))
(if (autoload-generate-file-autoloads (if (autoload-generate-file-autoloads
;; Passing `current-buffer' makes it insert at point.
file (current-buffer) buffer-file-name) file (current-buffer) buffer-file-name)
(push file no-autoloads)))) (push file no-autoloads))))
(push file done) (push file done)
@ -660,6 +687,9 @@ directory or directories specified."
(dolist (file files) (dolist (file files)
(cond (cond
((member (expand-file-name file) autoload-excludes) nil) ((member (expand-file-name file) autoload-excludes) nil)
;; Passing nil as second argument forces
;; autoload-generate-file-autoloads to look for the right
;; spot where to insert each autoloads section.
((autoload-generate-file-autoloads file nil buffer-file-name) ((autoload-generate-file-autoloads file nil buffer-file-name)
(push file no-autoloads)))) (push file no-autoloads))))