comparison lisp/emacs-lisp/autoload.el @ 90979:988f1edc9674

Merge from emacs--devo--0 Patches applied: * emacs--devo--0 (patch 803-805) - Update from CVS Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-227
author Miles Bader <miles@gnu.org>
date Mon, 09 Jul 2007 08:00:55 +0000
parents 03ec96a627ba 6416cbdef0fa
children a66921565bcb
comparison
equal deleted inserted replaced
90978:f866074aedc4 90979:988f1edc9674
39 (defvar generated-autoload-file "loaddefs.el" 39 (defvar generated-autoload-file "loaddefs.el"
40 "*File \\[update-file-autoloads] puts autoloads into. 40 "*File \\[update-file-autoloads] puts autoloads into.
41 A `.el' file can set this in its local variables section to make its 41 A `.el' file can set this in its local variables section to make its
42 autoloads go somewhere else. The autoload file is assumed to contain a 42 autoloads go somewhere else. The autoload file is assumed to contain a
43 trailer starting with a FormFeed character.") 43 trailer starting with a FormFeed character.")
44 44 (put 'generated-autoload-file 'safe-local-variable 'stringp)
45 (defconst generate-autoload-cookie ";;;###autoload" 45
46 ;; This feels like it should be a defconst, but MH-E sets it to
47 ;; ";;;###mh-autoload" for the autoloads that are to go into mh-loaddefs.el.
48 (defvar generate-autoload-cookie ";;;###autoload"
46 "Magic comment indicating the following form should be autoloaded. 49 "Magic comment indicating the following form should be autoloaded.
47 Used by \\[update-file-autoloads]. This string should be 50 Used by \\[update-file-autoloads]. This string should be
48 meaningless to Lisp (e.g., a comment). 51 meaningless to Lisp (e.g., a comment).
49 52
50 This string is used: 53 This string is used:
51 54
52 ;;;###autoload 55 \;;;###autoload
53 \(defun function-to-be-autoloaded () ...) 56 \(defun function-to-be-autoloaded () ...)
54 57
55 If this string appears alone on a line, the following form will be 58 If this string appears alone on a line, the following form will be
56 read and an autoload made for it. If there is further text on the line, 59 read and an autoload made for it. If there is further text on the line,
57 that text will be copied verbatim to `generated-autoload-file'.") 60 that text will be copied verbatim to `generated-autoload-file'.")
62 (defconst generate-autoload-section-trailer "\n;;;***\n" 65 (defconst generate-autoload-section-trailer "\n;;;***\n"
63 "String which indicates the end of the section of autoloads for a file.") 66 "String which indicates the end of the section of autoloads for a file.")
64 67
65 (defconst generate-autoload-section-continuation ";;;;;; " 68 (defconst generate-autoload-section-continuation ";;;;;; "
66 "String to add on each continuation of the section header form.") 69 "String to add on each continuation of the section header form.")
70
71 (defvar autoload-modified-buffers) ;Dynamically scoped var.
67 72
68 (defun make-autoload (form file) 73 (defun make-autoload (form file)
69 "Turn FORM into an autoload or defvar for source file FILE. 74 "Turn FORM into an autoload or defvar for source file FILE.
70 Returns nil if FORM is not a special autoload form (i.e. a function definition 75 Returns nil if FORM is not a special autoload form (i.e. a function definition
71 or macro definition or a defcustom)." 76 or macro definition or a defcustom)."
147 ;; Forms which have doc-strings which should be printed specially. 152 ;; Forms which have doc-strings which should be printed specially.
148 ;; A doc-string-elt property of ELT says that (nth ELT FORM) is 153 ;; A doc-string-elt property of ELT says that (nth ELT FORM) is
149 ;; the doc-string in FORM. 154 ;; the doc-string in FORM.
150 ;; Those properties are now set in lisp-mode.el. 155 ;; Those properties are now set in lisp-mode.el.
151 156
152 157 (defun autoload-generated-file ()
153 (defun autoload-trim-file-name (file) 158 (expand-file-name generated-autoload-file
154 ;; Returns a relative file path for FILE 159 ;; File-local settings of generated-autoload-file should
155 ;; starting from the directory that loaddefs.el is in. 160 ;; be interpreted relative to the file's location,
156 ;; That is normally a directory in load-path, 161 ;; of course.
157 ;; which means Emacs will be able to find FILE when it looks. 162 (if (not (local-variable-p 'generated-autoload-file))
158 ;; Any extra directory names here would prevent finding the file. 163 (expand-file-name "lisp" source-directory))))
159 (setq file (expand-file-name file)) 164
160 (file-relative-name file
161 (file-name-directory generated-autoload-file)))
162 165
163 (defun autoload-read-section-header () 166 (defun autoload-read-section-header ()
164 "Read a section header form. 167 "Read a section header form.
165 Since continuation lines have been marked as comments, 168 Since continuation lines have been marked as comments,
166 we must copy the text of the form and remove those comment 169 we must copy the text of the form and remove those comment
251 254
252 (defun autoload-insert-section-header (outbuf autoloads load-name file time) 255 (defun autoload-insert-section-header (outbuf autoloads load-name file time)
253 "Insert the section-header line, 256 "Insert the section-header line,
254 which lists the file name and which functions are in it, etc." 257 which lists the file name and which functions are in it, etc."
255 (insert generate-autoload-section-header) 258 (insert generate-autoload-section-header)
256 (prin1 (list 'autoloads autoloads load-name 259 (prin1 (list 'autoloads autoloads load-name file time)
257 (if (stringp file) (autoload-trim-file-name file) file)
258 time)
259 outbuf) 260 outbuf)
260 (terpri outbuf) 261 (terpri outbuf)
261 ;; Break that line at spaces, to avoid very long lines. 262 ;; Break that line at spaces, to avoid very long lines.
262 ;; Make each sub-line into a comment. 263 ;; Make each sub-line into a comment.
263 (with-current-buffer outbuf 264 (with-current-buffer outbuf
270 (insert "\n" generate-autoload-section-continuation)))))) 271 (insert "\n" generate-autoload-section-continuation))))))
271 272
272 (defun autoload-find-file (file) 273 (defun autoload-find-file (file)
273 "Fetch file and put it in a temp buffer. Return the buffer." 274 "Fetch file and put it in a temp buffer. Return the buffer."
274 ;; It is faster to avoid visiting the file. 275 ;; It is faster to avoid visiting the file.
276 (setq file (expand-file-name file))
275 (with-current-buffer (get-buffer-create " *autoload-file*") 277 (with-current-buffer (get-buffer-create " *autoload-file*")
276 (kill-all-local-variables) 278 (kill-all-local-variables)
277 (erase-buffer) 279 (erase-buffer)
278 (setq buffer-undo-list t 280 (setq buffer-undo-list t
279 buffer-read-only nil) 281 buffer-read-only nil)
280 (emacs-lisp-mode) 282 (emacs-lisp-mode)
283 (setq default-directory (file-name-directory file))
281 (insert-file-contents file nil) 284 (insert-file-contents file nil)
282 (let ((enable-local-variables :safe)) 285 (let ((enable-local-variables :safe))
283 (hack-local-variables)) 286 (hack-local-variables))
284 (current-buffer))) 287 (current-buffer)))
285 288
286 (defvar no-update-autoloads nil 289 (defvar no-update-autoloads nil
287 "File local variable to prevent scanning this file for autoload cookies.") 290 "File local variable to prevent scanning this file for autoload cookies.")
291
292 (defun autoload-file-load-name (file)
293 (let ((name (file-name-nondirectory file)))
294 (if (string-match "\\.elc?\\(\\.\\|\\'\\)" name)
295 (substring name 0 (match-beginning 0))
296 name)))
288 297
289 (defun generate-file-autoloads (file) 298 (defun generate-file-autoloads (file)
290 "Insert at point a loaddefs autoload section for FILE. 299 "Insert at point a loaddefs autoload section for FILE.
291 Autoloads are generated for defuns and defmacros in FILE 300 Autoloads are generated for defuns and defmacros in FILE
292 marked by `generate-autoload-cookie' (which see). 301 marked by `generate-autoload-cookie' (which see).
293 If FILE is being visited in a buffer, the contents of the buffer 302 If FILE is being visited in a buffer, the contents of the buffer
294 are used. 303 are used.
295 Return non-nil in the case where no autoloads were added at point." 304 Return non-nil in the case where no autoloads were added at point."
296 (interactive "fGenerate autoloads for file: ") 305 (interactive "fGenerate autoloads for file: ")
297 (let ((outbuf (current-buffer)) 306 (autoload-generate-file-autoloads file (current-buffer)))
298 (autoloads-done '()) 307
299 (load-name (let ((name (file-name-nondirectory file))) 308 ;; When called from `generate-file-autoloads' we should ignore
300 (if (string-match "\\.elc?\\(\\.\\|$\\)" name) 309 ;; `generated-autoload-file' altogether. When called from
301 (substring name 0 (match-beginning 0)) 310 ;; `update-file-autoloads' we don't know `outbuf'. And when called from
302 name))) 311 ;; `update-directory-autoloads' it's in between: we know the default
303 (print-length nil) 312 ;; `outbuf' but we should obey any file-local setting of
304 (print-readably t) ; This does something in Lucid Emacs. 313 ;; `generated-autoload-file'.
305 (float-output-format nil) 314 (defun autoload-generate-file-autoloads (file &optional outbuf outfile)
306 (done-any nil) 315 "Insert an autoload section for FILE in the appropriate buffer.
307 (visited (get-file-buffer file)) 316 Autoloads are generated for defuns and defmacros in FILE
308 output-start) 317 marked by `generate-autoload-cookie' (which see).
309 318 If FILE is being visited in a buffer, the contents of the buffer are used.
310 ;; If the autoload section we create here uses an absolute 319 OUTBUF is the buffer in which the autoload statements should be inserted.
311 ;; file name for FILE in its header, and then Emacs is installed 320 If OUTBUF is nil, it will be determined by `autoload-generated-file'.
312 ;; under a different path on another system, 321
313 ;; `update-autoloads-here' won't be able to find the files to be 322 If provided, OUTFILE is expected to be the file name of OUTBUF.
314 ;; autoloaded. So, if FILE is in the same directory or a 323 If OUTFILE is non-nil and FILE specifies a `generated-autoload-file'
315 ;; subdirectory of the current buffer's directory, we'll make it 324 different from OUTFILE, then OUTBUF is ignored.
316 ;; relative to the current buffer's directory. 325
317 (setq file (expand-file-name file)) 326 Return non-nil iff FILE adds no autoloads to OUTFILE
318 (let* ((source-truename (file-truename file)) 327 \(or OUTBUF if OUTFILE is nil)."
319 (dir-truename (file-name-as-directory 328 (catch 'done
320 (file-truename default-directory))) 329 (let ((autoloads-done '())
321 (len (length dir-truename))) 330 (load-name (autoload-file-load-name file))
322 (if (and (< len (length source-truename)) 331 (print-length nil)
323 (string= dir-truename (substring source-truename 0 len))) 332 (print-readably t) ; This does something in Lucid Emacs.
324 (setq file (substring source-truename len)))) 333 (float-output-format nil)
325 334 (visited (get-file-buffer file))
326 (with-current-buffer (or visited 335 (otherbuf nil)
327 ;; It is faster to avoid visiting the file. 336 (absfile (expand-file-name file))
328 (autoload-find-file file)) 337 relfile
329 ;; Obey the no-update-autoloads file local variable. 338 ;; nil until we found a cookie.
330 (unless no-update-autoloads 339 output-start)
331 (message "Generating autoloads for %s..." file) 340
332 (setq output-start (with-current-buffer outbuf (point))) 341 (with-current-buffer (or visited
333 (save-excursion 342 ;; It is faster to avoid visiting the file.
334 (save-restriction 343 (autoload-find-file file))
335 (widen) 344 ;; Obey the no-update-autoloads file local variable.
336 (goto-char (point-min)) 345 (unless no-update-autoloads
337 (while (not (eobp)) 346 (message "Generating autoloads for %s..." file)
338 (skip-chars-forward " \t\n\f") 347 (save-excursion
339 (cond 348 (save-restriction
340 ((looking-at (regexp-quote generate-autoload-cookie)) 349 (widen)
341 (search-forward generate-autoload-cookie) 350 (goto-char (point-min))
342 (skip-chars-forward " \t") 351 (while (not (eobp))
343 (setq done-any t) 352 (skip-chars-forward " \t\n\f")
344 (if (eolp) 353 (cond
345 ;; Read the next form and make an autoload. 354 ((looking-at (regexp-quote generate-autoload-cookie))
346 (let* ((form (prog1 (read (current-buffer)) 355 ;; If not done yet, figure out where to insert this text.
347 (or (bolp) (forward-line 1)))) 356 (unless output-start
348 (autoload (make-autoload form load-name))) 357 (when (and outfile
349 (if autoload 358 (not (equal outfile (autoload-generated-file))))
350 (push (nth 1 form) autoloads-done) 359 ;; A file-local setting of autoload-generated-file says
351 (setq autoload form)) 360 ;; we should ignore OUTBUF.
352 (let ((autoload-print-form-outbuf outbuf)) 361 (setq outbuf nil)
353 (autoload-print-form autoload))) 362 (setq otherbuf t))
354 363 (unless outbuf
355 ;; Copy the rest of the line to the output. 364 (setq outbuf (autoload-find-destination absfile))
356 (princ (buffer-substring 365 (unless outbuf
357 (progn 366 ;; The file has autoload cookies, but they're
358 ;; Back up over whitespace, to preserve it. 367 ;; already up-to-date. If OUTFILE is nil, the
359 (skip-chars-backward " \f\t") 368 ;; entries are in the expected OUTBUF, otherwise
360 (if (= (char-after (1+ (point))) ? ) 369 ;; they're elsewhere.
361 ;; Eat one space. 370 (throw 'done outfile)))
362 (forward-char 1)) 371 (with-current-buffer outbuf
363 (point)) 372 (setq relfile (file-relative-name absfile))
364 (progn (forward-line 1) (point))) 373 (setq output-start (point)))
365 outbuf))) 374 ;; (message "file=%S, relfile=%S, dest=%S"
366 ((looking-at ";") 375 ;; file relfile (autoload-generated-file))
367 ;; Don't read the comment. 376 )
368 (forward-line 1)) 377 (search-forward generate-autoload-cookie)
369 (t 378 (skip-chars-forward " \t")
370 (forward-sexp 1) 379 (if (eolp)
371 (forward-line 1)))))) 380 (condition-case err
372 381 ;; Read the next form and make an autoload.
373 (when done-any 382 (let* ((form (prog1 (read (current-buffer))
374 (with-current-buffer outbuf 383 (or (bolp) (forward-line 1))))
375 (save-excursion 384 (autoload (make-autoload form load-name)))
376 ;; Insert the section-header line which lists the file name 385 (if autoload
377 ;; and which functions are in it, etc. 386 (push (nth 1 form) autoloads-done)
378 (goto-char output-start) 387 (setq autoload form))
379 (autoload-insert-section-header 388 (let ((autoload-print-form-outbuf outbuf))
380 outbuf autoloads-done load-name file 389 (autoload-print-form autoload)))
381 (nth 5 (file-attributes file))) 390 (error
382 (insert ";;; Generated autoloads from " 391 (message "Error in %s: %S" file err)))
383 (autoload-trim-file-name file) "\n")) 392
384 (insert generate-autoload-section-trailer))) 393 ;; Copy the rest of the line to the output.
385 (message "Generating autoloads for %s...done" file)) 394 (princ (buffer-substring
386 (or visited 395 (progn
387 ;; We created this buffer, so we should kill it. 396 ;; Back up over whitespace, to preserve it.
388 (kill-buffer (current-buffer)))) 397 (skip-chars-backward " \f\t")
389 (not done-any))) 398 (if (= (char-after (1+ (point))) ? )
399 ;; Eat one space.
400 (forward-char 1))
401 (point))
402 (progn (forward-line 1) (point)))
403 outbuf)))
404 ((looking-at ";")
405 ;; Don't read the comment.
406 (forward-line 1))
407 (t
408 (forward-sexp 1)
409 (forward-line 1))))))
410
411 (when output-start
412 (let ((secondary-autoloads-file-buf
413 (if (local-variable-p 'generated-autoload-file)
414 (current-buffer))))
415 (with-current-buffer outbuf
416 (save-excursion
417 ;; Insert the section-header line which lists the file name
418 ;; and which functions are in it, etc.
419 (goto-char output-start)
420 (autoload-insert-section-header
421 outbuf autoloads-done load-name relfile
422 (if secondary-autoloads-file-buf
423 ;; MD5 checksums are much better because they do not
424 ;; change unless the file changes (so they'll be
425 ;; equal on two different systems and will change
426 ;; less often than time-stamps, thus leading to fewer
427 ;; unneeded changes causing spurious conflicts), but
428 ;; using time-stamps is a very useful optimization,
429 ;; so we use time-stamps for the main autoloads file
430 ;; (loaddefs.el) where we have special ways to
431 ;; circumvent the "random change problem", and MD5
432 ;; checksum in secondary autoload files where we do
433 ;; not need the time-stamp optimization because it is
434 ;; already provided by the primary autoloads file.
435 (md5 secondary-autoloads-file-buf nil nil 'emacs-mule)
436 (nth 5 (file-attributes relfile))))
437 (insert ";;; Generated autoloads from " relfile "\n"))
438 (insert generate-autoload-section-trailer))))
439 (message "Generating autoloads for %s...done" file))
440 (or visited
441 ;; We created this buffer, so we should kill it.
442 (kill-buffer (current-buffer))))
443 ;; If the entries were added to some other buffer, then the file
444 ;; doesn't add entries to OUTFILE.
445 (or (not output-start) otherbuf))))
390 446
447 (defun autoload-save-buffers ()
448 (while autoload-modified-buffers
449 (with-current-buffer (pop autoload-modified-buffers)
450 (save-buffer))))
451
391 ;;;###autoload 452 ;;;###autoload
392 (defun update-file-autoloads (file &optional save-after) 453 (defun update-file-autoloads (file &optional save-after)
393 "Update the autoloads for FILE in `generated-autoload-file' 454 "Update the autoloads for FILE in `generated-autoload-file'
394 \(which FILE might bind in its local variables). 455 \(which FILE might bind in its local variables).
395 If SAVE-AFTER is non-nil (which is always, when called interactively), 456 If SAVE-AFTER is non-nil (which is always, when called interactively),
396 save the buffer too. 457 save the buffer too.
397 458
398 Return FILE if there was no autoload cookie in it, else nil." 459 Return FILE if there was no autoload cookie in it, else nil."
399 (interactive "fUpdate autoloads for file: \np") 460 (interactive "fUpdate autoloads for file: \np")
400 (let ((load-name (let ((name (file-name-nondirectory file))) 461 (let* ((autoload-modified-buffers nil)
401 (if (string-match "\\.elc?\\(\\.\\|$\\)" name) 462 (no-autoloads (autoload-generate-file-autoloads file)))
402 (substring name 0 (match-beginning 0)) 463 (if autoload-modified-buffers
403 name))) 464 (if save-after (autoload-save-buffers))
404 (found nil) 465 (if (interactive-p)
405 (existing-buffer (get-file-buffer file)) 466 (message "Autoload section for %s is up to date." file)))
406 (no-autoloads nil)) 467 (if no-autoloads file)))
407 (save-excursion 468
408 ;; We want to get a value for generated-autoload-file from 469 (defun autoload-find-destination (file)
409 ;; the local variables section if it's there. 470 "Find the destination point of the current buffer's autoloads.
410 (if existing-buffer 471 FILE is the file name of the current buffer.
411 (set-buffer existing-buffer)) 472 Returns a buffer whose point is placed at the requested location.
412 ;; We must read/write the file without any code conversion, 473 Returns nil if the file's autoloads are uptodate, otherwise
413 ;; but still decode EOLs. 474 removes any prior now out-of-date autoload entries."
414 (let ((coding-system-for-read 'raw-text)) 475 (catch 'up-to-date
415 (set-buffer (find-file-noselect 476 (let* ((load-name (autoload-file-load-name file))
416 (autoload-ensure-default-file 477 (buf (current-buffer))
417 (expand-file-name generated-autoload-file 478 (existing-buffer (if buffer-file-name buf))
418 (expand-file-name "lisp" 479 (found nil))
419 source-directory))))) 480 (with-current-buffer
420 ;; This is to make generated-autoload-file have Unix EOLs, so 481 ;; We must read/write the file without any code conversion,
421 ;; that it is portable to all platforms. 482 ;; but still decode EOLs.
422 (setq buffer-file-coding-system 'raw-text-unix)) 483 (let ((coding-system-for-read 'raw-text))
423 (or (> (buffer-size) 0) 484 (find-file-noselect
424 (error "Autoloads file %s does not exist" buffer-file-name)) 485 (autoload-ensure-default-file (autoload-generated-file))))
425 (or (file-writable-p buffer-file-name) 486 ;; This is to make generated-autoload-file have Unix EOLs, so
426 (error "Autoloads file %s is not writable" buffer-file-name)) 487 ;; that it is portable to all platforms.
427 (save-excursion 488 (setq buffer-file-coding-system 'raw-text-unix)
428 (save-restriction 489 (or (> (buffer-size) 0)
429 (widen) 490 (error "Autoloads file %s does not exist" buffer-file-name))
430 (goto-char (point-min)) 491 (or (file-writable-p buffer-file-name)
431 ;; Look for the section for LOAD-NAME. 492 (error "Autoloads file %s is not writable" buffer-file-name))
432 (while (and (not found) 493 (widen)
433 (search-forward generate-autoload-section-header nil t)) 494 (goto-char (point-min))
434 (let ((form (autoload-read-section-header))) 495 ;; Look for the section for LOAD-NAME.
435 (cond ((string= (nth 2 form) load-name) 496 (while (and (not found)
436 ;; We found the section for this file. 497 (search-forward generate-autoload-section-header nil t))
437 ;; Check if it is up to date. 498 (let ((form (autoload-read-section-header)))
438 (let ((begin (match-beginning 0)) 499 (cond ((string= (nth 2 form) load-name)
439 (last-time (nth 4 form)) 500 ;; We found the section for this file.
440 (file-time (nth 5 (file-attributes file)))) 501 ;; Check if it is up to date.
441 (if (and (or (null existing-buffer) 502 (let ((begin (match-beginning 0))
442 (not (buffer-modified-p existing-buffer))) 503 (last-time (nth 4 form))
443 (listp last-time) (= (length last-time) 2) 504 (file-time (nth 5 (file-attributes file))))
444 (not (time-less-p last-time file-time))) 505 (if (and (or (null existing-buffer)
445 (progn 506 (not (buffer-modified-p existing-buffer)))
446 (if (interactive-p) 507 (or
447 (message "\ 508 ;; last-time is the time-stamp (specifying
448 Autoload section for %s is up to date." 509 ;; the last time we looked at the file) and
449 file)) 510 ;; the file hasn't been changed since.
450 (setq found 'up-to-date)) 511 (and (listp last-time) (= (length last-time) 2)
451 (search-forward generate-autoload-section-trailer) 512 (not (time-less-p last-time file-time)))
452 (delete-region begin (point)) 513 ;; last-time is an MD5 checksum instead.
453 (setq found t)))) 514 (and (stringp last-time)
454 ((string< load-name (nth 2 form)) 515 (equal last-time
455 ;; We've come to a section alphabetically later than 516 (md5 buf nil nil 'emacs-mule)))))
456 ;; LOAD-NAME. We assume the file is in order and so 517 (throw 'up-to-date nil)
457 ;; there must be no section for LOAD-NAME. We will 518 (autoload-remove-section begin)
458 ;; insert one before the section here. 519 (setq found t))))
459 (goto-char (match-beginning 0)) 520 ((string< load-name (nth 2 form))
460 (setq found 'new))))) 521 ;; We've come to a section alphabetically later than
461 (or found 522 ;; LOAD-NAME. We assume the file is in order and so
462 (progn 523 ;; there must be no section for LOAD-NAME. We will
463 (setq found 'new) 524 ;; insert one before the section here.
464 ;; No later sections in the file. Put before the last page. 525 (goto-char (match-beginning 0))
465 (goto-char (point-max)) 526 (setq found t)))))
466 (search-backward "\f" nil t))) 527 (or found
467 (or (eq found 'up-to-date) 528 (progn
468 (setq no-autoloads (generate-file-autoloads file))))) 529 ;; No later sections in the file. Put before the last page.
469 (and save-after 530 (goto-char (point-max))
470 (buffer-modified-p) 531 (search-backward "\f" nil t)))
471 (save-buffer)) 532 (unless (memq (current-buffer) autoload-modified-buffers)
472 533 (push (current-buffer) autoload-modified-buffers))
473 (if no-autoloads file)))) 534 (current-buffer)))))
474 535
475 (defun autoload-remove-section (begin) 536 (defun autoload-remove-section (begin)
476 (goto-char begin) 537 (goto-char begin)
477 (search-forward generate-autoload-section-trailer) 538 (search-forward generate-autoload-section-trailer)
478 (delete-region begin (point))) 539 (delete-region begin (point)))
497 (mapcar (lambda (dir) 558 (mapcar (lambda (dir)
498 (directory-files (expand-file-name dir) 559 (directory-files (expand-file-name dir)
499 t files-re)) 560 t files-re))
500 dirs))) 561 dirs)))
501 (this-time (current-time)) 562 (this-time (current-time))
502 (no-autoloads nil) ;files with no autoload cookies. 563 ;; Files with no autoload cookies or whose autoloads go to other
503 (autoloads-file 564 ;; files because of file-local autoload-generated-file settings.
504 (expand-file-name generated-autoload-file 565 (no-autoloads nil)
505 (expand-file-name "lisp" source-directory))) 566 (autoload-modified-buffers nil))
506 (top-dir (file-name-directory autoloads-file)))
507 567
508 (with-current-buffer 568 (with-current-buffer
509 (find-file-noselect (autoload-ensure-default-file autoloads-file)) 569 (find-file-noselect
570 (autoload-ensure-default-file (autoload-generated-file)))
510 (save-excursion 571 (save-excursion
511 572
512 ;; Canonicalize file names and remove the autoload file itself. 573 ;; Canonicalize file names and remove the autoload file itself.
513 (setq files (delete (autoload-trim-file-name buffer-file-name) 574 (setq files (delete (file-relative-name buffer-file-name)
514 (mapcar 'autoload-trim-file-name files))) 575 (mapcar 'file-relative-name files)))
515 576
516 (goto-char (point-min)) 577 (goto-char (point-min))
517 (while (search-forward generate-autoload-section-header nil t) 578 (while (search-forward generate-autoload-section-header nil t)
518 (let* ((form (autoload-read-section-header)) 579 (let* ((form (autoload-read-section-header))
519 (file (nth 3 form))) 580 (file (nth 3 form)))
529 (not (time-less-p last-time file-time))) 590 (not (time-less-p last-time file-time)))
530 ;; file unchanged 591 ;; file unchanged
531 (push file no-autoloads) 592 (push file no-autoloads)
532 (setq files (delete file files))))))) 593 (setq files (delete file files)))))))
533 ((not (stringp file))) 594 ((not (stringp file)))
534 ((not (file-exists-p (expand-file-name file top-dir))) 595 ((not (and (file-exists-p file)
596 ;; Remove duplicates as well, just in case.
597 (member file files)))
535 ;; Remove the obsolete section. 598 ;; Remove the obsolete section.
536 (autoload-remove-section (match-beginning 0))) 599 (autoload-remove-section (match-beginning 0)))
537 ((equal (nth 4 form) (nth 5 (file-attributes file))) 600 ((not (time-less-p (nth 4 form)
601 (nth 5 (file-attributes file))))
538 ;; File hasn't changed. 602 ;; File hasn't changed.
539 nil) 603 nil)
540 (t 604 (t
541 (update-file-autoloads file))) 605 (autoload-remove-section (match-beginning 0))
606 (if (autoload-generate-file-autoloads
607 file (current-buffer) buffer-file-name)
608 (push file no-autoloads))))
542 (setq files (delete file files))))) 609 (setq files (delete file files)))))
543 ;; Elements remaining in FILES have no existing autoload sections yet. 610 ;; Elements remaining in FILES have no existing autoload sections yet.
544 (setq no-autoloads 611 (dolist (file files)
545 (append no-autoloads 612 (if (autoload-generate-file-autoloads file nil buffer-file-name)
546 (delq nil (mapcar 'update-file-autoloads files)))) 613 (push file no-autoloads)))
614
547 (when no-autoloads 615 (when no-autoloads
548 ;; Sort them for better readability. 616 ;; Sort them for better readability.
549 (setq no-autoloads (sort no-autoloads 'string<)) 617 (setq no-autoloads (sort no-autoloads 'string<))
550 ;; Add the `no-autoloads' section. 618 ;; Add the `no-autoloads' section.
551 (goto-char (point-max)) 619 (goto-char (point-max))
552 (search-backward "\f" nil t) 620 (search-backward "\f" nil t)
553 (autoload-insert-section-header 621 (autoload-insert-section-header
554 (current-buffer) nil nil no-autoloads this-time) 622 (current-buffer) nil nil no-autoloads this-time)
555 (insert generate-autoload-section-trailer)) 623 (insert generate-autoload-section-trailer))
556 624
557 (save-buffer)))) 625 (save-buffer)
626 ;; In case autoload entries were added to other files because of
627 ;; file-local autoload-generated-file settings.
628 (autoload-save-buffers))))
558 629
559 (define-obsolete-function-alias 'update-autoloads-from-directories 630 (define-obsolete-function-alias 'update-autoloads-from-directories
560 'update-directory-autoloads "22.1") 631 'update-directory-autoloads "22.1")
561 632
562 ;;;###autoload 633 ;;;###autoload