comparison lisp/emacs-lisp/autoload.el @ 107894:9b05dc529495

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.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Sun, 18 Apr 2010 17:45:44 -0400
parents 8aeda91ab827
children b668431e0039
comparison
equal deleted inserted replaced
107893:3d1b30daa7a9 107894:9b05dc529495
326 326
327 (defvar no-update-autoloads nil 327 (defvar no-update-autoloads nil
328 "File local variable to prevent scanning this file for autoload cookies.") 328 "File local variable to prevent scanning this file for autoload cookies.")
329 329
330 (defun autoload-file-load-name (file) 330 (defun autoload-file-load-name (file)
331 (let ((name (file-name-nondirectory file))) 331 "Compute the name that will be used to load FILE."
332 ;; OUTFILE should be the name of the global loaddefs.el file, which
333 ;; is expected to be at the root directory of the files we're
334 ;; scanning for autoloads and will be in the `load-path'.
335 (let* ((outfile (default-value 'generated-autoload-file))
336 (name (file-relative-name file (file-name-directory outfile)))
337 (names '())
338 (dir (file-name-directory outfile)))
339 ;; If `name' has directory components, only keep the
340 ;; last few that are really needed.
341 (while name
342 (setq name (directory-file-name name))
343 (push (file-name-nondirectory name) names)
344 (setq name (file-name-directory name)))
345 (while (not name)
346 (cond
347 ((null (cdr names)) (setq name (car names)))
348 ((file-exists-p (expand-file-name "subdirs.el" dir))
349 ;; FIXME: here we only check the existence of subdirs.el,
350 ;; without checking its content. This makes it generate wrong load
351 ;; names for cases like lisp/term which is not added to load-path.
352 (setq dir (expand-file-name (pop names) dir)))
353 (t (setq name (mapconcat 'identity names "/")))))
332 (if (string-match "\\.elc?\\(\\.\\|\\'\\)" name) 354 (if (string-match "\\.elc?\\(\\.\\|\\'\\)" name)
333 (substring name 0 (match-beginning 0)) 355 (substring name 0 (match-beginning 0))
334 name))) 356 name)))
335 357
336 (defun generate-file-autoloads (file) 358 (defun generate-file-autoloads (file)
340 If FILE is being visited in a buffer, the contents of the buffer 362 If FILE is being visited in a buffer, the contents of the buffer
341 are used. 363 are used.
342 Return non-nil in the case where no autoloads were added at point." 364 Return non-nil in the case where no autoloads were added at point."
343 (interactive "fGenerate autoloads for file: ") 365 (interactive "fGenerate autoloads for file: ")
344 (autoload-generate-file-autoloads file (current-buffer))) 366 (autoload-generate-file-autoloads file (current-buffer)))
367
368 (defvar print-readably)
345 369
346 ;; When called from `generate-file-autoloads' we should ignore 370 ;; When called from `generate-file-autoloads' we should ignore
347 ;; `generated-autoload-file' altogether. When called from 371 ;; `generated-autoload-file' altogether. When called from
348 ;; `update-file-autoloads' we don't know `outbuf'. And when called from 372 ;; `update-file-autoloads' we don't know `outbuf'. And when called from
349 ;; `update-directory-autoloads' it's in between: we know the default 373 ;; `update-directory-autoloads' it's in between: we know the default
371 (print-readably t) ; This does something in Lucid Emacs. 395 (print-readably t) ; This does something in Lucid Emacs.
372 (float-output-format nil) 396 (float-output-format nil)
373 (visited (get-file-buffer file)) 397 (visited (get-file-buffer file))
374 (otherbuf nil) 398 (otherbuf nil)
375 (absfile (expand-file-name file)) 399 (absfile (expand-file-name file))
376 relfile
377 ;; nil until we found a cookie. 400 ;; nil until we found a cookie.
378 output-start) 401 output-start ostart)
379 (with-current-buffer (or visited 402 (with-current-buffer (or visited
380 ;; It is faster to avoid visiting the file. 403 ;; It is faster to avoid visiting the file.
381 (autoload-find-file file)) 404 (autoload-find-file file))
382 ;; Obey the no-update-autoloads file local variable. 405 ;; Obey the no-update-autoloads file local variable.
383 (unless no-update-autoloads 406 (unless no-update-autoloads
384 (message "Generating autoloads for %s..." file) 407 (message "Generating autoloads for %s..." file)
385 (setq load-name 408 (setq load-name
386 (if (stringp generated-autoload-load-name) 409 (if (stringp generated-autoload-load-name)
387 generated-autoload-load-name 410 generated-autoload-load-name
388 (autoload-file-load-name file))) 411 (autoload-file-load-name absfile)))
412 (when (and outfile
413 (not (equal outfile (autoload-generated-file))))
414 (setq otherbuf t))
389 (save-excursion 415 (save-excursion
390 (save-restriction 416 (save-restriction
391 (widen) 417 (widen)
392 (goto-char (point-min)) 418 (goto-char (point-min))
393 (while (not (eobp)) 419 (while (not (eobp))
394 (skip-chars-forward " \t\n\f") 420 (skip-chars-forward " \t\n\f")
395 (cond 421 (cond
396 ((looking-at (regexp-quote generate-autoload-cookie)) 422 ((looking-at (regexp-quote generate-autoload-cookie))
397 ;; If not done yet, figure out where to insert this text. 423 ;; If not done yet, figure out where to insert this text.
398 (unless output-start 424 (unless output-start
399 (when (and outfile 425 (let ((outbuf
400 (not (equal outfile (autoload-generated-file)))) 426 (or (if otherbuf
401 ;; A file-local setting of autoload-generated-file says 427 ;; A file-local setting of
402 ;; we should ignore OUTBUF. 428 ;; autoload-generated-file says we
403 (setq outbuf nil) 429 ;; should ignore OUTBUF.
404 (setq otherbuf t)) 430 nil
405 (unless outbuf 431 outbuf)
406 (setq outbuf (autoload-find-destination absfile)) 432 (autoload-find-destination absfile load-name)
407 (unless outbuf 433 ;; The file has autoload cookies, but they're
408 ;; The file has autoload cookies, but they're 434 ;; already up-to-date. If OUTFILE is nil, the
409 ;; already up-to-date. If OUTFILE is nil, the 435 ;; entries are in the expected OUTBUF,
410 ;; entries are in the expected OUTBUF, otherwise 436 ;; otherwise they're elsewhere.
411 ;; they're elsewhere. 437 (throw 'done otherbuf))))
412 (throw 'done outfile))) 438 (with-current-buffer outbuf
413 (with-current-buffer outbuf 439 (setq output-start (point-marker)
414 (setq relfile (file-relative-name absfile)) 440 ostart (point)))))
415 (setq output-start (point)))
416 ;; (message "file=%S, relfile=%S, dest=%S"
417 ;; file relfile (autoload-generated-file))
418 )
419 (search-forward generate-autoload-cookie) 441 (search-forward generate-autoload-cookie)
420 (skip-chars-forward " \t") 442 (skip-chars-forward " \t")
421 (if (eolp) 443 (if (eolp)
422 (condition-case err 444 (condition-case err
423 ;; Read the next form and make an autoload. 445 ;; Read the next form and make an autoload.
425 (or (bolp) (forward-line 1)))) 447 (or (bolp) (forward-line 1))))
426 (autoload (make-autoload form load-name))) 448 (autoload (make-autoload form load-name)))
427 (if autoload 449 (if autoload
428 (push (nth 1 form) autoloads-done) 450 (push (nth 1 form) autoloads-done)
429 (setq autoload form)) 451 (setq autoload form))
430 (let ((autoload-print-form-outbuf outbuf)) 452 (let ((autoload-print-form-outbuf
453 (marker-buffer output-start)))
431 (autoload-print-form autoload))) 454 (autoload-print-form autoload)))
432 (error 455 (error
433 (message "Error in %s: %S" file err))) 456 (message "Error in %s: %S" file err)))
434 457
435 ;; Copy the rest of the line to the output. 458 ;; Copy the rest of the line to the output.
440 (if (= (char-after (1+ (point))) ? ) 463 (if (= (char-after (1+ (point))) ? )
441 ;; Eat one space. 464 ;; Eat one space.
442 (forward-char 1)) 465 (forward-char 1))
443 (point)) 466 (point))
444 (progn (forward-line 1) (point))) 467 (progn (forward-line 1) (point)))
445 outbuf))) 468 (marker-buffer output-start))))
446 ((looking-at ";") 469 ((looking-at ";")
447 ;; Don't read the comment. 470 ;; Don't read the comment.
448 (forward-line 1)) 471 (forward-line 1))
449 (t 472 (t
450 (forward-sexp 1) 473 (forward-sexp 1)
452 475
453 (when output-start 476 (when output-start
454 (let ((secondary-autoloads-file-buf 477 (let ((secondary-autoloads-file-buf
455 (if (local-variable-p 'generated-autoload-file) 478 (if (local-variable-p 'generated-autoload-file)
456 (current-buffer)))) 479 (current-buffer))))
457 (with-current-buffer outbuf 480 (with-current-buffer (marker-buffer output-start)
458 (save-excursion 481 (save-excursion
459 ;; Insert the section-header line which lists the file name 482 ;; Insert the section-header line which lists the file name
460 ;; and which functions are in it, etc. 483 ;; and which functions are in it, etc.
484 (assert (= ostart output-start))
461 (goto-char output-start) 485 (goto-char output-start)
462 (autoload-insert-section-header 486 (let ((relfile (file-relative-name absfile)))
463 outbuf autoloads-done load-name relfile 487 (autoload-insert-section-header
464 (if secondary-autoloads-file-buf 488 (marker-buffer output-start)
465 ;; MD5 checksums are much better because they do not 489 autoloads-done load-name relfile
466 ;; change unless the file changes (so they'll be 490 (if secondary-autoloads-file-buf
467 ;; equal on two different systems and will change 491 ;; MD5 checksums are much better because they do not
468 ;; less often than time-stamps, thus leading to fewer 492 ;; change unless the file changes (so they'll be
469 ;; unneeded changes causing spurious conflicts), but 493 ;; equal on two different systems and will change
470 ;; using time-stamps is a very useful optimization, 494 ;; less often than time-stamps, thus leading to fewer
471 ;; so we use time-stamps for the main autoloads file 495 ;; unneeded changes causing spurious conflicts), but
472 ;; (loaddefs.el) where we have special ways to 496 ;; using time-stamps is a very useful optimization,
473 ;; circumvent the "random change problem", and MD5 497 ;; so we use time-stamps for the main autoloads file
474 ;; checksum in secondary autoload files where we do 498 ;; (loaddefs.el) where we have special ways to
475 ;; not need the time-stamp optimization because it is 499 ;; circumvent the "random change problem", and MD5
476 ;; already provided by the primary autoloads file. 500 ;; checksum in secondary autoload files where we do
477 (md5 secondary-autoloads-file-buf 501 ;; not need the time-stamp optimization because it is
478 ;; We'd really want to just use 502 ;; already provided by the primary autoloads file.
479 ;; `emacs-internal' instead. 503 (md5 secondary-autoloads-file-buf
480 nil nil 'emacs-mule-unix) 504 ;; We'd really want to just use
481 (nth 5 (file-attributes relfile)))) 505 ;; `emacs-internal' instead.
482 (insert ";;; Generated autoloads from " relfile "\n")) 506 nil nil 'emacs-mule-unix)
507 (nth 5 (file-attributes relfile))))
508 (insert ";;; Generated autoloads from " relfile "\n")))
483 (insert generate-autoload-section-trailer)))) 509 (insert generate-autoload-section-trailer))))
484 (message "Generating autoloads for %s...done" file)) 510 (message "Generating autoloads for %s...done" file))
485 (or visited 511 (or visited
486 ;; We created this buffer, so we should kill it. 512 ;; We created this buffer, so we should kill it.
487 (kill-buffer (current-buffer)))) 513 (kill-buffer (current-buffer))))
488 ;; If the entries were added to some other buffer, then the file 514 (or (not output-start)
489 ;; doesn't add entries to OUTFILE. 515 ;; If the entries were added to some other buffer, then the file
490 (or (not output-start) otherbuf)))) 516 ;; doesn't add entries to OUTFILE.
517 otherbuf))))
491 518
492 (defun autoload-save-buffers () 519 (defun autoload-save-buffers ()
493 (while autoload-modified-buffers 520 (while autoload-modified-buffers
494 (with-current-buffer (pop autoload-modified-buffers) 521 (with-current-buffer (pop autoload-modified-buffers)
495 (save-buffer)))) 522 (save-buffer))))
509 (if save-after (autoload-save-buffers)) 536 (if save-after (autoload-save-buffers))
510 (if (called-interactively-p 'interactive) 537 (if (called-interactively-p 'interactive)
511 (message "Autoload section for %s is up to date." file))) 538 (message "Autoload section for %s is up to date." file)))
512 (if no-autoloads file))) 539 (if no-autoloads file)))
513 540
514 (defun autoload-find-destination (file) 541 (defun autoload-find-destination (file load-name)
515 "Find the destination point of the current buffer's autoloads. 542 "Find the destination point of the current buffer's autoloads.
516 FILE is the file name of the current buffer. 543 FILE is the file name of the current buffer.
517 Returns a buffer whose point is placed at the requested location. 544 Returns a buffer whose point is placed at the requested location.
518 Returns nil if the file's autoloads are uptodate, otherwise 545 Returns nil if the file's autoloads are uptodate, otherwise
519 removes any prior now out-of-date autoload entries." 546 removes any prior now out-of-date autoload entries."
520 (catch 'up-to-date 547 (catch 'up-to-date
521 (let* ((load-name (autoload-file-load-name file)) 548 (let* ((buf (current-buffer))
522 (buf (current-buffer))
523 (existing-buffer (if buffer-file-name buf)) 549 (existing-buffer (if buffer-file-name buf))
524 (found nil)) 550 (found nil))
525 (with-current-buffer 551 (with-current-buffer
526 ;; We used to use `raw-text' to read this file, but this causes 552 ;; We used to use `raw-text' to read this file, but this causes
527 ;; problems when the file contains non-ASCII characters. 553 ;; problems when the file contains non-ASCII characters.
530 ;; This is to make generated-autoload-file have Unix EOLs, so 556 ;; This is to make generated-autoload-file have Unix EOLs, so
531 ;; that it is portable to all platforms. 557 ;; that it is portable to all platforms.
532 (unless (zerop (coding-system-eol-type buffer-file-coding-system)) 558 (unless (zerop (coding-system-eol-type buffer-file-coding-system))
533 (set-buffer-file-coding-system 'unix)) 559 (set-buffer-file-coding-system 'unix))
534 (or (> (buffer-size) 0) 560 (or (> (buffer-size) 0)
535 (error "Autoloads file %s does not exist" buffer-file-name)) 561 (error "Autoloads file %s lacks boilerplate" buffer-file-name))
536 (or (file-writable-p buffer-file-name) 562 (or (file-writable-p buffer-file-name)
537 (error "Autoloads file %s is not writable" buffer-file-name)) 563 (error "Autoloads file %s is not writable" buffer-file-name))
538 (widen) 564 (widen)
539 (goto-char (point-min)) 565 (goto-char (point-min))
540 ;; Look for the section for LOAD-NAME. 566 ;; Look for the section for LOAD-NAME.
650 ;; File hasn't changed. 676 ;; File hasn't changed.
651 nil) 677 nil)
652 (t 678 (t
653 (autoload-remove-section (match-beginning 0)) 679 (autoload-remove-section (match-beginning 0))
654 (if (autoload-generate-file-autoloads 680 (if (autoload-generate-file-autoloads
681 ;; Passing `current-buffer' makes it insert at point.
655 file (current-buffer) buffer-file-name) 682 file (current-buffer) buffer-file-name)
656 (push file no-autoloads)))) 683 (push file no-autoloads))))
657 (push file done) 684 (push file done)
658 (setq files (delete file files))))) 685 (setq files (delete file files)))))
659 ;; Elements remaining in FILES have no existing autoload sections yet. 686 ;; Elements remaining in FILES have no existing autoload sections yet.
660 (dolist (file files) 687 (dolist (file files)
661 (cond 688 (cond
662 ((member (expand-file-name file) autoload-excludes) nil) 689 ((member (expand-file-name file) autoload-excludes) nil)
690 ;; Passing nil as second argument forces
691 ;; autoload-generate-file-autoloads to look for the right
692 ;; spot where to insert each autoloads section.
663 ((autoload-generate-file-autoloads file nil buffer-file-name) 693 ((autoload-generate-file-autoloads file nil buffer-file-name)
664 (push file no-autoloads)))) 694 (push file no-autoloads))))
665 695
666 (when no-autoloads 696 (when no-autoloads
667 ;; Sort them for better readability. 697 ;; Sort them for better readability.