comparison lisp/utils/autoload.el @ 12:bcdc7deadc19 r19-15b7

Import from CVS: tag r19-15b7
author cvs
date Mon, 13 Aug 2007 08:48:16 +0200
parents 376386a54a3c
children 4103f0995bd7
comparison
equal deleted inserted replaced
11:91ffe8bd52e4 12:bcdc7deadc19
1 ;;; autoload.el --- maintain autoloads in loaddefs.el. 1 ;;; autoload.el --- maintain autoloads in loaddefs.el.
2
3 ;;; Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. 2 ;;; Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
4 ;;; Copyright (C) 1995 Tinker Systems and INS Engineering Corp. 3 ;;; Copyright (C) 1995 Tinker Systems and INS Engineering Corp.
5 ;;; Copyright (C) 1996 Ben Wing. 4 ;;; Copyright (C) 1996 Ben Wing.
6 5
7 ;; Author: Roland McGrath <roland@gnu.ai.mit.edu> 6 ;; Author: Roland McGrath <roland@gnu.ai.mit.edu>
8 ;; Keywords: maint 7 ;; Keywords: maint
9 8
10 ;;; This program is free software; you can redistribute it and/or modify 9 ;; This file is part of XEmacs.
11 ;;; it under the terms of the GNU General Public License as published by 10
12 ;;; the Free Software Foundation; either version 2, or (at your option) 11 ;; XEmacs is free software; you can redistribute it and/or modify it
13 ;;; any later version. 12 ;; under the terms of the GNU General Public License as published by
14 ;;; 13 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;;; This program is distributed in the hope that it will be useful, 14 ;; any later version.
16 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15
17 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 ;; XEmacs is distributed in the hope that it will be useful, but
18 ;;; GNU General Public License for more details. 17 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;;; 18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 ;;; A copy of the GNU General Public License can be obtained from this 19 ;; General Public License for more details.
21 ;;; program's author (send electronic mail to roland@ai.mit.edu) or from 20
22 ;;; the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 21 ;; You should have received a copy of the GNU General Public License
23 ;;; 02139, USA. 22 ;; along with XEmacs; see the file COPYING. If not, write to the Free
24 ;;; 23 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 24 ;; 02111-1307, USA.
26 ;;; Synched up with: FSF 19.30. 25
26 ;;; Synched up with: Not synched with FSF.
27 27
28 ;;; Commentary: 28 ;;; Commentary:
29 29
30 ;; This code helps GNU Emacs maintainers keep the loaddefs.el file up to 30 ;; This code helps GNU Emacs maintainers keep the loaddefs.el file up to
31 ;; date. It interprets magic cookies of the form ";;;###autoload" in 31 ;; date. It interprets magic cookies of the form ";;;###autoload" in
57 (if macrop (list 'quote 'macro) nil))) 57 (if macrop (list 'quote 'macro) nil)))
58 nil))) 58 nil)))
59 59
60 (put 'define-skeleton 'doc-string-elt 3) 60 (put 'define-skeleton 'doc-string-elt 3)
61 61
62 (defconst generate-autoload-cookie ";;;###autoload" 62 (defvar generate-autoload-cookie ";;;###autoload"
63 "Magic comment indicating the following form should be autoloaded. 63 "Magic comment indicating the following form should be autoloaded.
64 Used by \\[update-file-autoloads]. This string should be 64 Used by `update-file-autoloads'. This string should be
65 meaningless to Lisp (e.g., a comment). 65 meaningless to Lisp (e.g., a comment).
66 66
67 This string is used: 67 This string is used:
68 68
69 ;;;###autoload 69 ;;;###autoload
70 \(defun function-to-be-autoloaded () ...) 70 \(defun function-to-be-autoloaded () ...)
71 71
72 If this string appears alone on a line, the following form will be read and 72 If this string appears alone on a line, the following form will be
73 an autoload made for it. If it is followed by the string \"immediate\", 73 read and an autoload made for it. If it is followed by the string
74 then the form on the following will be copied verbatim. If there is further 74 \"immediate\", then the form on the following line will be copied
75 text on the line, that text will be copied verbatim to 75 verbatim. If there is further text on the line, that text will be
76 `generated-autoload-file'.") 76 copied verbatim to `generated-autoload-file'.")
77 77
78 (defconst generate-autoload-section-header "\f\n;;;### " 78 (defvar generate-autoload-section-header "\f\n;;;### "
79 "String inserted before the form identifying 79 "String inserted before the form identifying
80 the section of autoloads for a file.") 80 the section of autoloads for a file.")
81 81
82 (defconst generate-autoload-section-trailer "\n;;;***\n" 82 (defvar generate-autoload-section-trailer "\n;;;***\n"
83 "String which indicates the end of the section of autoloads for a file.") 83 "String which indicates the end of the section of autoloads for a file.")
84 84
85 ;;; Forms which have doc-strings which should be printed specially. 85 ;;; Forms which have doc-strings which should be printed specially.
86 ;;; A doc-string-elt property of ELT says that (nth ELT FORM) is 86 ;;; A doc-string-elt property of ELT says that (nth ELT FORM) is
87 ;;; the doc-string in FORM. 87 ;;; the doc-string in FORM.
105 (put 'defvar 'doc-string-elt 3) 105 (put 'defvar 'doc-string-elt 3)
106 (put 'defconst 'doc-string-elt 3) 106 (put 'defconst 'doc-string-elt 3)
107 (put 'defmacro 'doc-string-elt 3) 107 (put 'defmacro 'doc-string-elt 3)
108 108
109 (defun autoload-trim-file-name (file) 109 (defun autoload-trim-file-name (file)
110 ;; returns a relative pathname of FILE including the last directory. 110 "Returns a relative pathname of FILE including the last directory."
111 (setq file (expand-file-name file)) 111 (setq file (expand-file-name file))
112 (file-relative-name file 112 (file-relative-name file (file-name-directory
113 (file-name-directory 113 (directory-file-name
114 (directory-file-name 114 (file-name-directory file)))))
115 (file-name-directory file)))))
116 115
117 ;;;###autoload 116 ;;;###autoload
118 (defun generate-file-autoloads (file &optional funlist) 117 (defun generate-file-autoloads (file &optional funlist)
119 "Insert at point a loaddefs autoload section for FILE. 118 "Insert at point a loaddefs autoload section for FILE.
120 autoloads are generated for defuns and defmacros in FILE 119 autoloads are generated for defuns and defmacros in FILE
121 marked by `generate-autoload-cookie' (which see). 120 marked by `generate-autoload-cookie' (which see).
122 If FILE is being visited in a buffer, the contents of the buffer 121 If FILE is being visited in a buffer, the contents of the buffer
123 are used." 122 are used."
124 (interactive "fGenerate autoloads for file: ") 123 (interactive "fGenerate autoloads for file: ")
124 (generate-file-autoloads-1 file funlist))
125
126 (defun* generate-file-autoloads-1 (file funlist)
127 "Insert at point a loaddefs autoload section for FILE.
128 autoloads are generated for defuns and defmacros in FILE
129 marked by `generate-autoload-cookie' (which see).
130 If FILE is being visited in a buffer, the contents of the buffer
131 are used."
125 (let ((outbuf (current-buffer)) 132 (let ((outbuf (current-buffer))
126 (autoloads-done '()) 133 (autoloads-done '())
127 (load-name (let ((name (file-name-nondirectory file))) 134 (load-name (replace-in-string (file-name-nondirectory file)
128 (if (string-match "\\.elc?$" name) 135 "\\.elc?$"
129 (substring name 0 (match-beginning 0)) 136 ""))
130 name))) 137 (trim-name (autoload-trim-file-name file))
131 (dofiles (not (null funlist))) 138 (dofiles (not (null funlist)))
132 (print-length nil) 139 (print-length nil)
133 (print-readably t) ; XEmacs 140 (print-readably t) ; XEmacs
134 (float-output-format nil) 141 (float-output-format nil)
135 (done-any nil) 142 ;; (done-any nil)
136 (visited (get-file-buffer file)) 143 (visited (get-file-buffer file))
137 output-end) 144 output-end)
138 145
139 ;; If the autoload section we create here uses an absolute 146 ;; If the autoload section we create here uses an absolute
140 ;; pathname for FILE in its header, and then Emacs is installed 147 ;; pathname for FILE in its header, and then Emacs is installed
142 ;; `update-autoloads-here' won't be able to find the files to be 149 ;; `update-autoloads-here' won't be able to find the files to be
143 ;; autoloaded. So, if FILE is in the same directory or a 150 ;; autoloaded. So, if FILE is in the same directory or a
144 ;; subdirectory of the current buffer's directory, we'll make it 151 ;; subdirectory of the current buffer's directory, we'll make it
145 ;; relative to the current buffer's directory. 152 ;; relative to the current buffer's directory.
146 (setq file (expand-file-name file)) 153 (setq file (expand-file-name file))
147 (let* ((source-truename (file-truename file)) 154
148 (dir-truename (file-name-as-directory
149 (file-truename default-directory)))
150 (len (length dir-truename)))
151 (if (and (< len (length source-truename))
152 (string= dir-truename (substring source-truename 0 len)))
153 (setq file (substring source-truename len))))
154
155 (message "Generating autoloads for %s..." file)
156 (save-excursion 155 (save-excursion
157 (unwind-protect 156 (unwind-protect
158 (progn 157 (progn
159 (set-buffer (find-file-noselect file)) 158 (set-buffer (or visited (find-file-noselect file)))
160 (save-excursion 159 (save-excursion
161 (save-restriction 160 (save-restriction
162 (widen) 161 (widen)
162 (goto-char (point-min))
163 (unless (search-forward generate-autoload-cookie nil t)
164 (message "No autoloads found in %s" trim-name)
165 (return-from generate-file-autoloads-1))
166
167 (message "Generating autoloads for %s..." trim-name)
163 (goto-char (point-min)) 168 (goto-char (point-min))
164 (while (if dofiles funlist (not (eobp))) 169 (while (if dofiles funlist (not (eobp)))
165 (if (not dofiles) 170 (if (not dofiles)
166 (skip-chars-forward " \t\n\f") 171 (skip-chars-forward " \t\n\f")
167 (goto-char (point-min)) 172 (goto-char (point-min))
175 (looking-at (regexp-quote generate-autoload-cookie))) 180 (looking-at (regexp-quote generate-autoload-cookie)))
176 (if dofiles 181 (if dofiles
177 nil 182 nil
178 (search-forward generate-autoload-cookie) 183 (search-forward generate-autoload-cookie)
179 (skip-chars-forward " \t")) 184 (skip-chars-forward " \t"))
180 (setq done-any t) 185 ;; (setq done-any t)
181 (if (or dofiles (eolp)) 186 (if (or dofiles (eolp))
182 ;; Read the next form and make an autoload. 187 ;; Read the next form and make an autoload.
183 (let* ((form (prog1 (read (current-buffer)) 188 (let* ((form (prog1 (read (current-buffer))
184 (or (bolp) (forward-line 1)))) 189 (or (bolp) (forward-line 1))))
185 (autoload (make-autoload form load-name)) 190 (autoload (make-autoload form load-name))
284 (t 289 (t
285 (forward-sexp 1) 290 (forward-sexp 1)
286 (forward-line 1))) 291 (forward-line 1)))
287 (if dofiles 292 (if dofiles
288 (setq funlist (cdr funlist))))))) 293 (setq funlist (cdr funlist)))))))
289 (or visited 294 (unless visited
290 ;; We created this buffer, so we should kill it. 295 ;; We created this buffer, so we should kill it.
291 (kill-buffer (current-buffer))) 296 (kill-buffer (current-buffer)))
292 (set-buffer outbuf) 297 (set-buffer outbuf)
293 (setq output-end (point-marker)))) 298 (setq output-end (point-marker))))
294 (if t ;; done-any 299 (if t ;; done-any
295 ;; XEmacs -- always do this so that we cache the information 300 ;; XEmacs -- always do this so that we cache the information
296 ;; that we've processed the file already. 301 ;; that we've processed the file already.
297 (progn 302 (progn
298 (insert generate-autoload-section-header) 303 (insert generate-autoload-section-header)
299 (prin1 (list 'autoloads autoloads-done load-name 304 (prin1 (list 'autoloads autoloads-done load-name trim-name)
300 (autoload-trim-file-name file)
301 (nth 5 (file-attributes file)))
302 outbuf) 305 outbuf)
303 (terpri outbuf) 306 (terpri outbuf)
304 (insert ";;; Generated autoloads from " 307 ;;;; (insert ";;; Generated autoloads from "
305 (autoload-trim-file-name file) "\n") 308 ;;;; (autoload-trim-file-name file) "\n")
306 ;; Warn if we put a line in loaddefs.el 309 ;; Warn if we put a line in loaddefs.el
307 ;; that is long enough to cause trouble. 310 ;; that is long enough to cause trouble.
311 (when (< output-end (point))
312 (setq output-end (point-marker)))
308 (while (< (point) output-end) 313 (while (< (point) output-end)
309 (let ((beg (point))) 314 (let ((beg (point)))
310 (end-of-line) 315 (end-of-line)
311 (if (> (- (point) beg) 900) 316 (if (> (- (point) beg) 900)
312 (progn 317 (progn
316 (forward-line 1)) 321 (forward-line 1))
317 (goto-char output-end) 322 (goto-char output-end)
318 (insert generate-autoload-section-trailer))) 323 (insert generate-autoload-section-trailer)))
319 (or noninteractive ; XEmacs: only need one line in -batch mode. 324 (or noninteractive ; XEmacs: only need one line in -batch mode.
320 (message "Generating autoloads for %s...done" file)))) 325 (message "Generating autoloads for %s...done" file))))
326
321 327
322 (defconst generated-autoload-file (expand-file-name "../lisp/prim/loaddefs.el" 328 (defvar generated-autoload-file
323 data-directory) 329 (expand-file-name "../lisp/prim/auto-autoloads.el" data-directory)
324 "*File \\[update-file-autoloads] puts autoloads into. 330 "*File `update-file-autoloads' puts autoloads into.
325 A .el file can set this in its local variables section to make its 331 A .el file can set this in its local variables section to make its
326 autoloads go somewhere else.") 332 autoloads go somewhere else.")
327
328 (defvar generate-autoload-dynamic-but-inefficient nil
329 "If non-nil, `update-file-autoloads' will always read in its files.
330 This allows you to bind `generated-autoload-file' in your local variables
331 (do you really want to do that?) but makes it very slow in updating
332 lots of files.")
333 333
334 ;;;###autoload 334 ;;;###autoload
335 (defun update-file-autoloads (file) 335 (defun update-file-autoloads (file)
336 "Update the autoloads for FILE in `generated-autoload-file' 336 "Update the autoloads for FILE in `generated-autoload-file'
337 \(which FILE might bind in its local variables)." 337 \(which FILE might bind in its local variables)."
338 (interactive "fUpdate autoloads for file: ") 338 (interactive "fUpdate autoloads for file: ")
339 ;; avoid horrid horrid problems with relative filenames. 339 (setq file (expand-file-name file))
340 (setq file (expand-file-name file default-directory)) 340 (let ((load-name (replace-in-string (file-name-nondirectory file)
341 (let ((load-name (let ((name (file-name-nondirectory file))) 341 "\\.elc?$"
342 (if (string-match "\\.elc?$" name) 342 ""))
343 (substring name 0 (match-beginning 0))
344 name)))
345 (trim-name (autoload-trim-file-name file)) 343 (trim-name (autoload-trim-file-name file))
346 (found nil) 344 section-begin form)
347 (pass 'first)
348 (existing-buffer (get-file-buffer file)))
349 (save-excursion 345 (save-excursion
350 ;; We want to get a value for generated-autoload-file from
351 ;; the local variables section if it's there.
352 (and generate-autoload-dynamic-but-inefficient
353 (set-buffer (find-file-noselect file)))
354 (set-buffer (or (get-file-buffer generated-autoload-file) 346 (set-buffer (or (get-file-buffer generated-autoload-file)
355 (find-file-noselect generated-autoload-file))) 347 (find-file-noselect generated-autoload-file)))
356 (save-excursion 348 ;; First delete all sections for this file.
357 (save-restriction 349 (goto-char (point-min))
358 (widen) 350 (while (search-forward generate-autoload-section-header nil t)
359 (while pass 351 (setq section-begin (match-beginning 0))
360 ;; This is done in two passes: 352 (setq form (read (current-buffer)))
361 ;; 1st pass: Look for the section for LOAD-NAME anywhere in the file. 353 (when (string= (nth 2 form) load-name)
362 ;; 2st pass: Find a place to insert it. Use alphabetical order. 354 (search-forward generate-autoload-section-trailer)
363 (goto-char (point-min)) 355 (delete-region section-begin (point))))
364 (while (and (not found) 356
365 (search-forward generate-autoload-section-header nil t)) 357 ;; Now find insertion point for new section
366 (let ((form (condition-case () 358 (block find-insertion-point
367 (read (current-buffer)) 359 (goto-char (point-min))
368 (end-of-file nil)))) 360 (while (search-forward generate-autoload-section-header nil t)
369 (cond ((and (eq pass 'first) 361 (setq form (read (current-buffer)))
370 (string= (nth 2 form) load-name)) 362 (when (string< trim-name (nth 3 form))
371 ;; We found the section for this file. 363 ;; Found alphabetically correct insertion point
372 ;; Check if it is up to date. 364 (goto-char (match-beginning 0))
373 (let ((begin (match-beginning 0)) 365 (return-from find-insertion-point))
374 (last-time (nth 4 form)) 366 (search-forward generate-autoload-section-trailer))
375 (file-time (nth 5 (file-attributes file)))) 367 (when (eq (point) (point-min)) ; No existing entries?
376 (if (and (or (null existing-buffer) 368 (goto-char (point-max)))) ; Append.
377 (not (buffer-modified-p existing-buffer))) 369
378 (listp last-time) (= (length last-time) 2) 370 ;; Add in new sections for file
379 (or (> (car last-time) (car file-time)) 371 (generate-file-autoloads file))
380 (and (= (car last-time) (car file-time)) 372
381 (>= (nth 1 last-time) 373 (when (interactive-p) (save-buffer))))
382 (nth 1 file-time)))))
383 (progn
384 (or noninteractive
385 ;; jwz: too loud in -batch mode
386 (message
387 "Autoload section for %s is up to date."
388 file))
389 (setq found 'up-to-date))
390 ;; Okay, we found it and it's not up to date...
391 (search-forward generate-autoload-section-trailer)
392 (delete-region begin (point))
393 ;; if the file has moved, then act like it hasn't
394 ;; been found and then reinsert it alphabetically.
395 (setq found (string= trim-name (nth 3 form)))
396 )))
397 ;; XEmacs change -- we organize by sub-directories
398 ;; so inserting new autoload entries is a bit tricky...
399 ((and (eq pass 'last)
400 (string< trim-name (nth 3 form)))
401 ;; We've come to a section alphabetically later than
402 ;; LOAD-NAME. We assume the file is in order and so
403 ;; there must be no section for LOAD-NAME. We will
404 ;; insert one before the section here.
405 (goto-char (match-beginning 0))
406 (setq found 'new))
407 )))
408 (cond (found
409 (setq pass nil)) ; success -- exit loop
410 ((eq pass 'first)
411 (setq pass 'last))
412 (t
413 ;; failure -- exit loop
414 (setq pass nil))))
415 (or (eq found 'up-to-date)
416 ;; XEmacs -- don't do the following. If we do, then
417 ;; every time we update autoloads we have to search
418 ;; the whole file (yuck).
419 ; (and (eq found 'new)
420 ; ;; Check that FILE has any cookies before generating a
421 ; ;; new section for it.
422 ; (save-excursion
423 ; (set-buffer (find-file-noselect file))
424 ; (save-excursion
425 ; (widen)
426 ; (goto-char (point-min))
427 ; (if (search-forward (concat "\n"
428 ; generate-autoload-cookie)
429 ; nil t)
430 ; nil
431 ; (if (interactive-p)
432 ; (message file " has no autoloads"))
433 ; t))))
434 (generate-file-autoloads file))))
435 (if (interactive-p) (save-buffer))
436 (if (and (null existing-buffer)
437 (setq existing-buffer (get-file-buffer file)))
438 (kill-buffer existing-buffer)))))
439 374
440 ;;;###autoload 375 ;;;###autoload
441 (defun update-autoloads-here () 376 (defun update-autoloads-here ()
442 "\ 377 "Update sections of the current buffer generated by `update-file-autoloads'."
443 Update sections of the current buffer generated by \\[update-file-autoloads]."
444 (interactive) 378 (interactive)
445 (let ((generated-autoload-file (buffer-file-name))) 379 (let ((generated-autoload-file (buffer-file-name)))
446 (save-excursion 380 (save-excursion
447 (goto-char (point-min)) 381 (goto-char (point-min))
448 (while (search-forward generate-autoload-section-header nil t) 382 (while (search-forward generate-autoload-section-header nil t)
467 (if (or (get-file-buffer loc) 401 (if (or (get-file-buffer loc)
468 (file-exists-p loc)) 402 (file-exists-p loc))
469 (setq file loc) 403 (setq file loc)
470 nil)))))) 404 nil))))))
471 (t 405 (t
472 (setq file (if (y-or-n-p (format "Can't find library `%s'; remove its autoloads? " 406 (setq file
473 (nth 2 form) file)) 407 (if (y-or-n-p
474 t 408 (format
475 (condition-case () 409 "Can't find library `%s'; remove its autoloads? "
476 (read-file-name 410 (nth 2 form) file))
477 (format "Find `%s' load file: " 411 t
478 (nth 2 form)) 412 (condition-case ()
479 nil nil t) 413 (read-file-name
480 (quit nil)))))) 414 (format "Find `%s' load file: "
415 (nth 2 form))
416 nil nil t)
417 (quit nil))))))
481 (if file 418 (if file
482 (let ((begin (match-beginning 0))) 419 (let ((begin (match-beginning 0)))
483 (search-forward generate-autoload-section-trailer) 420 (search-forward generate-autoload-section-trailer)
484 (delete-region begin (point)))) 421 (delete-region begin (point))))
485 (if (stringp file) 422 (if (stringp file)
486 (generate-file-autoloads file))))))) 423 (generate-file-autoloads file)))))))
487 424
488 ;;;###autoload 425 ;;;###autoload
489 (defun update-directory-autoloads (dir) 426 (defun update-autoloads-from-directory (dir)
490 "Run \\[update-file-autoloads] on each .el file in DIR." 427 "Update `generated-autoload-file' with all the current autoloads from DIR.
428 This runs `update-file-autoloads' on each .el file in DIR.
429 Obsolete autoload entries for files that no longer exist are deleted."
491 (interactive "DUpdate autoloads for directory: ") 430 (interactive "DUpdate autoloads for directory: ")
492 (let ((enable-local-eval nil)) 431 (setq dir (expand-file-name dir))
493 (mapcar 'update-file-autoloads 432 (let ((simple-dir (file-name-as-directory
494 (directory-files dir t "^[^=].*\\.el$"))) 433 (file-name-nondirectory
495 (if (interactive-p) 434 (directory-file-name dir))))
496 (save-excursion 435 (enable-local-eval nil))
497 (set-buffer (find-file-noselect generated-autoload-file)) 436 (save-excursion
498 (save-buffer)))) 437 (set-buffer (find-file-noselect generated-autoload-file))
438 (goto-char (point-min))
439 (while (search-forward generate-autoload-section-header nil t)
440 (let* ((begin (match-beginning 0))
441 (form (condition-case ()
442 (read (current-buffer))
443 (end-of-file nil)))
444 (file (nth 3 form)))
445 (when (and (stringp file)
446 (string= (file-name-directory file) simple-dir)
447 (not (file-exists-p
448 (expand-file-name
449 (file-name-nondirectory file) dir))))
450 ;; Remove the obsolete section.
451 (search-forward generate-autoload-section-trailer)
452 (delete-region begin (point)))))
453 ;; Update or create autoload sections for existing files.
454 (mapcar 'update-file-autoloads (directory-files dir t "^[^=].*\\.el$"))
455 (unless noninteractive
456 (save-buffer)))))
499 457
500 ;;;###autoload 458 ;;;###autoload
501 (defun batch-update-autoloads () 459 (defun batch-update-autoloads ()
502 "Update the autoloads for the files or directories on the command line. 460 "Update the autoloads for the files or directories on the command line.
503 Runs \\[update-file-autoloads] on files and \\[update-directory-autoloads] 461 Runs `update-file-autoloads' on files and `update-directory-autoloads'
504 on directories. Must be used only with -batch, and kills Emacs on completion. 462 on directories. Must be used only with -batch, and kills Emacs on completion.
505 Each file will be processed even if an error occurred previously. 463 Each file will be processed even if an error occurred previously.
506 For example, invoke `emacs -batch -f batch-update-autoloads *.el'." 464 For example, invoke `xemacs -batch -f batch-update-autoloads *.el'."
507 (if (not noninteractive) 465 (unless noninteractive
508 (error "batch-update-autoloads is to be used only with -batch")) 466 (error "batch-update-autoloads is to be used only with -batch"))
509 (let ((lost nil) 467 (let ((defdir default-directory)
510 (args command-line-args-left) 468 (enable-local-eval nil)) ; Don't query in batch mode.
511 (defdir default-directory)
512 (enable-local-eval nil)) ;Don't query in batch mode.
513 (message "Updating autoloads in %s..." generated-autoload-file) 469 (message "Updating autoloads in %s..." generated-autoload-file)
514 (let ((frob (function 470 (dolist (arg command-line-args-left)
515 (lambda (file) 471 (setq arg (expand-file-name arg defdir))
516 (condition-case lossage 472 (cond
517 (let ((default-directory defdir)) 473 ((file-directory-p arg)
518 (update-file-autoloads file)) 474 (message "Updating autoloads for directory %s..." arg)
519 (error 475 (update-autoloads-from-directory arg))
520 (princ ">>Error processing ") 476 ((file-exists-p arg)
521 (princ file) 477 (update-file-autoloads arg))
522 (princ ": ") 478 (t (error "No such file or directory: %s" arg))))
523 (if (fboundp 'display-error)
524 (display-error lossage nil)
525 (prin1 lossage))
526 (princ "\n")
527 (setq lost t)))))))
528 (while args
529 (if (file-directory-p (expand-file-name (car args)))
530 (let ((rest (directory-files (car args) t "\\.el$")))
531 (if noninteractive
532 (message "Processing directory %s..." (car args)))
533 (while rest
534 (funcall frob (car rest))
535 (setq rest (cdr rest))))
536 (funcall frob (car args)))
537 (setq args (cdr args))))
538 (save-some-buffers t) 479 (save-some-buffers t)
539 (message "Done") 480 (message "Done")
540 (kill-emacs (if lost 1 0)))) 481 (kill-emacs 0)))
541 482
542 (provide 'autoload) 483 (provide 'autoload)
543 484
544 ;;; autoload.el ends here 485 ;;; autoload.el ends here