Mercurial > emacs
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. |