changeset 105316:3d13129b958c

(check-declare-scan): Read the declaration rather than parsing it as a regexp. This relaxes the layout requirements and makes errors easier to detect. (check-declare-verify): Check file is regular. (check-declare-directory): Doc fix.
author Glenn Morris <rgm@gnu.org>
date Thu, 01 Oct 2009 02:02:39 +0000
parents 20091666686c
children 78728d295b59
files lisp/emacs-lisp/check-declare.el
diffstat 1 files changed, 23 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/emacs-lisp/check-declare.el	Thu Oct 01 01:58:58 2009 +0000
+++ b/lisp/emacs-lisp/check-declare.el	Thu Oct 01 02:02:39 2009 +0000
@@ -81,28 +81,30 @@
 exists, not that it defines FN.  This is for function definitions that we
 don't know how to recognize (e.g. some macros)."
   (let ((m (format "Scanning %s..." file))
-        alist fnfile fn arglist fileonly)
+        alist form len fn fnfile arglist fileonly)
     (message "%s" m)
     (with-temp-buffer
       (insert-file-contents file)
-      (while (re-search-forward
-              "^[ \t]*(declare-function[ \t]+\\(\\S-+\\)[ \t]+\
-\"\\(\\S-+\\)\"" nil t)
-        (setq fn (match-string 1)
-              fnfile (match-string 2)
-              fnfile (check-declare-locate fnfile (expand-file-name file))
-              arglist (progn
-                        (skip-chars-forward " \t\n")
-                        ;; Use `t' to distinguish no arglist
-                        ;; specified from an empty one.
-                        (if (looking-at "\\((\\|nil\\|t\\)")
-                            (read (current-buffer))
-                          t))
-              fileonly (progn
-                        (skip-chars-forward " \t\n")
-                        (if (looking-at "\\(t\\|'\\sw+\\)")
-                            (match-string 1)))
-              alist (cons (list fnfile fn arglist fileonly) alist))))
+      ;; FIXME we could theoretically be inside a string.
+      (while (re-search-forward "^[ \t]*\\((declare-function\\)[ \t\n]" nil t)
+        (goto-char (match-beginning 1))
+        (if (and (setq form (ignore-errors (read (current-buffer)))
+                       len (length form))
+                 (> len 2) (< len 6)
+                 (symbolp (setq fn (cadr form)))
+                 (setq fn (symbol-name fn)) ; later we use as a search string
+                 (stringp (setq fnfile (nth 2 form)))
+                 (setq fnfile (check-declare-locate fnfile
+                                                    (expand-file-name file)))
+                 ;; Use `t' to distinguish unspecified arglist from empty one.
+                 (or (eq t (setq arglist (if (> len 3)
+                                             (nth 3 form)
+                                           t)))
+                     (listp arglist))
+                 (symbolp (setq fileonly (nth 4 form))))
+            (setq alist (cons (list fnfile fn arglist fileonly) alist))
+          ;; FIXME make this more noticeable.
+          (message "Malformed declaration for `%s'" (cadr form)))))
     (message "%sdone" m)
     alist))
 
@@ -138,7 +140,7 @@
     (message "%s" m)
     (if ext
         (setq fnfile (substring fnfile 4)))
-    (if (file-exists-p fnfile)
+    (if (file-regular-p fnfile)
         (with-temp-buffer
           (insert-file-contents fnfile)
           ;; defsubst's don't _have_ to be known at compile time.
@@ -291,9 +293,7 @@
 ;;;###autoload
 (defun check-declare-directory (root)
   "Check veracity of all `declare-function' statements under directory ROOT.
-Returns non-nil if any false statements are found.  For this to
-work correctly, the statements must adhere to the format
-described in the documentation of `declare-function'."
+Returns non-nil if any false statements are found."
   (interactive "DDirectory to check: ")
   (or (file-directory-p (setq root (expand-file-name root)))
       (error "Directory `%s' not found" root))