From 87b8db2bf304147a6ef8d50dda3b13a0397fa581 Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Sat, 17 Nov 2007 03:47:59 +0000 Subject: New file. --- lisp/emacs-lisp/check-declare.el | 195 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 lisp/emacs-lisp/check-declare.el (limited to 'lisp/emacs-lisp/check-declare.el') diff --git a/lisp/emacs-lisp/check-declare.el b/lisp/emacs-lisp/check-declare.el new file mode 100644 index 00000000000..e0d9601f4b4 --- /dev/null +++ b/lisp/emacs-lisp/check-declare.el @@ -0,0 +1,195 @@ +;;; check-declare.el --- Check declare-function statements + +;; Copyright (C) 2007 Free Software Foundation, Inc. + +;; Author: Glenn Morris +;; Keywords: lisp, tools, maint + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;; The byte-compiler often warns about undefined functions that you +;; know will actually be defined when it matters. The `declare-function' +;; statement allows you to suppress these warnings. This package +;; checks that all such statements in a file or directory are accurate. +;; The entry points are `check-declare-file' and `check-declare-directory'. + +;;; Code: + +(defconst check-declare-warning-buffer "*Check Declarations Warnings*" + "Name of buffer used to display any `check-declare' warnings.") + +(defun check-declare-scan (file) + "Scan FILE for `declare-function' calls. +Return a list with elements of the form (FNFILE FN ARGLIST), where +ARGLIST may be absent. This claims that FNFILE defines FN, with ARGLIST." + (let ((m (format "Scanning %s..." file)) + alist fnfile fn) + (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)) + (or (file-name-absolute-p fnfile) + (setq fnfile (expand-file-name fnfile (file-name-directory file)))) + (setq alist (cons + (list fnfile fn + (progn + (skip-chars-forward " \t\n") + ;; Use `t' to distinguish no arglist + ;; specified from an empty one. + (if (looking-at "\\((\\|nil\\)") + (read (current-buffer)) + t))) + alist)))) + (message "%sdone" m) + alist)) + +(autoload 'byte-compile-arglist-signature "bytecomp") + +(defun check-declare-verify (fnfile fnlist) + "Check that FNFILE contains function definitions matching FNLIST. +Each element of FNLIST has the form (FILE FN ARGLIST), where +ARGLIST is optional. This means FILE claimed FN was defined in +FNFILE with the specified ARGLIST. Returns nil if all claims are +found to be true, otherwise a list of errors with elements of the form +\(FILE FN TYPE), where TYPE is a string giving details of the error." + (let ((m (format "Checking %s..." fnfile)) + re fn sig siglist arglist type errlist) + (message "%s" m) + (if (file-exists-p fnfile) + (with-temp-buffer + (insert-file-contents fnfile) + (setq re (format "^[ \t]*(defun[ \t]+%s\\>" + (regexp-opt (mapcar 'cadr fnlist) t))) + (while (re-search-forward re nil t) + (skip-chars-forward " \t\n") + (setq fn (match-string 1) + sig (if (looking-at "\\((\\|nil\\)") + (byte-compile-arglist-signature + (read (current-buffer)))) + ;; alist of functions and arglist signatures. + siglist (cons (cons fn sig) siglist))))) + (dolist (e fnlist) + (setq arglist (nth 2 e) + type + (if re ; re non-nil means found a file + (if (setq sig (assoc (cadr e) siglist)) + ;; Recall we use t to mean no arglist specified, + ;; to distinguish from an empty arglist. + (unless (eq arglist t) + (unless (equal (byte-compile-arglist-signature arglist) + (cdr sig)) + "arglist mismatch")) + "function not found") + "file not found")) + (when type + (setq errlist (cons (list (car e) (cadr e) type) errlist)))) + (message "%s%s" m (if errlist "problems found" "OK")) + errlist)) + +(defun check-declare-sort (alist) + "Sort a list with elements FILE (FNFILE ...). +Returned list has elements FNFILE (FILE ...)." + (let (file fnfile rest sort a) + (dolist (e alist) + (setq file (car e)) + (dolist (f (cdr e)) + (setq fnfile (car f) + rest (cdr f)) + (if (setq a (assoc fnfile sort)) + (setcdr a (append (cdr a) (list (cons file rest)))) + (setq sort (cons (list fnfile (cons file rest)) sort))))) + sort)) + +(defun check-declare-warn (file fn fnfile type) + "Warn that FILE made a false claim about FN in FNFILE. +TYPE is a string giving the nature of the error. Warning is displayed in +`check-declare-warning-buffer'." + (display-warning 'check-declare + (format "%s said `%s' was defined in %s: %s" + (file-name-nondirectory file) fn + (file-name-nondirectory fnfile) + type) + nil check-declare-warning-buffer)) + +(defun check-declare-files (&rest files) + "Check veracity of all `declare-function' statements in FILES. +Return a list of any errors found." + (let (alist err errlist) + (dolist (file files) + (setq alist (cons (cons file (check-declare-scan file)) alist))) + ;; Sort so that things are ordered by the files supposed to + ;; contain the defuns. + (dolist (e (check-declare-sort alist)) + (if (setq err (check-declare-verify (car e) (cdr e))) + (setq errlist (cons (cons (car e) err) errlist)))) + (if (get-buffer check-declare-warning-buffer) + (kill-buffer check-declare-warning-buffer)) + ;; Sort back again so that errors are ordered by the files + ;; containing the declare-function statements. + (dolist (e (check-declare-sort errlist)) + (dolist (f (cdr e)) + (check-declare-warn (car e) (cadr f) (car f) (nth 2 f)))) + errlist)) + +;;;###autoload +(defun check-declare-file (file) + "Check veracity of all `declare-function' statements in FILE. +See `check-declare-directory' for more information." + (interactive "fFile to check: ") + (or (file-exists-p file) + (error "File `%s' not found" file)) + (let ((m (format "Checking %s..." file)) + errlist) + (message "%s" m) + (setq errlist (check-declare-files file)) + (message "%s%s" m (if errlist "problems found" "OK")) + errlist)) + +;;;###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'." + (interactive "DDirectory to check: ") + (or (file-directory-p (setq root (expand-file-name root))) + (error "Directory `%s' not found" root)) + (let ((m "Checking `declare-function' statements...") + (m2 "Finding files with declarations...") + errlist files) + (message "%s" m) + (message "%s" m2) + (setq files (process-lines "find" root "-name" "*.el" + "-exec" "grep" "-l" + "^[ ]*(declare-function" "{}" ";")) + (message "%s%d found" m2 (length files)) + (when files + (setq errlist (apply 'check-declare-files files)) + (message "%s%s" m (if errlist "problems found" "OK")) + errlist))) + +(provide 'check-declare) + +;; arch-tag: a4d6cdc4-deb7-4502-b327-0e4ef3d82d96 +;;; check-declare.el ends here. -- cgit v1.2.3 From f3a4724d5c6597e5722761a83d313565256eb6c7 Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Mon, 19 Nov 2007 00:09:20 +0000 Subject: (check-declare-verify): If fnfile does not exist, try adding `.el' extension. Also search for defsubsts. --- lisp/emacs-lisp/check-declare.el | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'lisp/emacs-lisp/check-declare.el') diff --git a/lisp/emacs-lisp/check-declare.el b/lisp/emacs-lisp/check-declare.el index e0d9601f4b4..0b78da165db 100644 --- a/lisp/emacs-lisp/check-declare.el +++ b/lisp/emacs-lisp/check-declare.el @@ -30,6 +30,10 @@ ;; checks that all such statements in a file or directory are accurate. ;; The entry points are `check-declare-file' and `check-declare-directory'. +;;; TODO: + +;; 1. Handle defstructs (eg uniquify-item-base in desktop.el). + ;;; Code: (defconst check-declare-warning-buffer "*Check Declarations Warnings*" @@ -76,14 +80,17 @@ found to be true, otherwise a list of errors with elements of the form (let ((m (format "Checking %s..." fnfile)) re fn sig siglist arglist type errlist) (message "%s" m) + (or (file-exists-p fnfile) + (setq fnfile (concat fnfile ".el"))) (if (file-exists-p fnfile) (with-temp-buffer (insert-file-contents fnfile) - (setq re (format "^[ \t]*(defun[ \t]+%s\\>" + ;; defsubst's don't _have_ to be known at compile time. + (setq re (format "^[ \t]*(def\\(un\\|subst\\)[ \t]+%s\\>" (regexp-opt (mapcar 'cadr fnlist) t))) (while (re-search-forward re nil t) (skip-chars-forward " \t\n") - (setq fn (match-string 1) + (setq fn (match-string 2) sig (if (looking-at "\\((\\|nil\\)") (byte-compile-arglist-signature (read (current-buffer)))) -- cgit v1.2.3 From 82b3ac7a99c49b585e0fde395454f895da666998 Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Tue, 20 Nov 2007 03:53:33 +0000 Subject: (check-declare-verify): Tweak regexp for end of function-name. Handle define-derived-mode. --- lisp/ChangeLog | 5 +++++ lisp/emacs-lisp/check-declare.el | 12 ++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'lisp/emacs-lisp/check-declare.el') diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 784c2d09da8..300ae8b628b 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,8 @@ +2007-11-20 Glenn Morris + + * emacs-lisp/check-declare.el (check-declare-verify): Tweak regexp + for end of function-name. Handle define-derived-mode. + 2007-11-20 Dan Nicolaescu * progmodes/idlw-help.el: Require browse-url unconditionally, it diff --git a/lisp/emacs-lisp/check-declare.el b/lisp/emacs-lisp/check-declare.el index 0b78da165db..c3e41086599 100644 --- a/lisp/emacs-lisp/check-declare.el +++ b/lisp/emacs-lisp/check-declare.el @@ -86,14 +86,18 @@ found to be true, otherwise a list of errors with elements of the form (with-temp-buffer (insert-file-contents fnfile) ;; defsubst's don't _have_ to be known at compile time. - (setq re (format "^[ \t]*(def\\(un\\|subst\\)[ \t]+%s\\>" + (setq re (format "^[ \t]*(\\(def\\(?:un\\|subst\\|\ +ine-derived-mode\\)\\)\[ \t]+%s\\([ \t;]+\\|$\\)" (regexp-opt (mapcar 'cadr fnlist) t))) (while (re-search-forward re nil t) (skip-chars-forward " \t\n") (setq fn (match-string 2) - sig (if (looking-at "\\((\\|nil\\)") - (byte-compile-arglist-signature - (read (current-buffer)))) + sig (if (string-equal "define-derived-mode" + (match-string 1)) + '(0 . 0) + (if (looking-at "\\((\\|nil\\)") + (byte-compile-arglist-signature + (read (current-buffer))))) ;; alist of functions and arglist signatures. siglist (cons (cons fn sig) siglist))))) (dolist (e fnlist) -- cgit v1.2.3 From 2ae3bb8564e12902c7bdefe692de5292ea6a423d Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Wed, 21 Nov 2007 09:03:16 +0000 Subject: (check-declare-verify): Skip C files for now. Handle define-minor-mode, and defalias (with no argument checking). --- lisp/ChangeLog | 6 +++ lisp/emacs-lisp/check-declare.el | 90 +++++++++++++++++++++++----------------- 2 files changed, 59 insertions(+), 37 deletions(-) (limited to 'lisp/emacs-lisp/check-declare.el') diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 6a8e8e75186..20a65f205f5 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,9 @@ +2007-11-21 Glenn Morris + + * emacs-lisp/check-declare.el (check-declare-verify): Skip C files + for now. Handle define-minor-mode, and defalias (with no argument + checking). + 2007-11-21 Dan Nicolaescu * frame.el (msdos-mouse-p): diff --git a/lisp/emacs-lisp/check-declare.el b/lisp/emacs-lisp/check-declare.el index c3e41086599..76719f1b876 100644 --- a/lisp/emacs-lisp/check-declare.el +++ b/lisp/emacs-lisp/check-declare.el @@ -34,6 +34,8 @@ ;; 1. Handle defstructs (eg uniquify-item-base in desktop.el). +;; 2. Check C files (look in src/)? + ;;; Code: (defconst check-declare-warning-buffer "*Check Declarations Warnings*" @@ -80,43 +82,57 @@ found to be true, otherwise a list of errors with elements of the form (let ((m (format "Checking %s..." fnfile)) re fn sig siglist arglist type errlist) (message "%s" m) - (or (file-exists-p fnfile) - (setq fnfile (concat fnfile ".el"))) - (if (file-exists-p fnfile) - (with-temp-buffer - (insert-file-contents fnfile) - ;; defsubst's don't _have_ to be known at compile time. - (setq re (format "^[ \t]*(\\(def\\(?:un\\|subst\\|\ -ine-derived-mode\\)\\)\[ \t]+%s\\([ \t;]+\\|$\\)" - (regexp-opt (mapcar 'cadr fnlist) t))) - (while (re-search-forward re nil t) - (skip-chars-forward " \t\n") - (setq fn (match-string 2) - sig (if (string-equal "define-derived-mode" - (match-string 1)) - '(0 . 0) - (if (looking-at "\\((\\|nil\\)") - (byte-compile-arglist-signature - (read (current-buffer))))) - ;; alist of functions and arglist signatures. - siglist (cons (cons fn sig) siglist))))) - (dolist (e fnlist) - (setq arglist (nth 2 e) - type - (if re ; re non-nil means found a file - (if (setq sig (assoc (cadr e) siglist)) - ;; Recall we use t to mean no arglist specified, - ;; to distinguish from an empty arglist. - (unless (eq arglist t) - (unless (equal (byte-compile-arglist-signature arglist) - (cdr sig)) - "arglist mismatch")) - "function not found") - "file not found")) - (when type - (setq errlist (cons (list (car e) (cadr e) type) errlist)))) - (message "%s%s" m (if errlist "problems found" "OK")) - errlist)) + (if (string-equal (file-name-extension fnfile) "c") + (progn + (message "%sskipping C file" m) + nil) + (or (file-exists-p fnfile) + (setq fnfile (concat fnfile ".el"))) + (if (file-exists-p fnfile) + (with-temp-buffer + (insert-file-contents fnfile) + ;; defsubst's don't _have_ to be known at compile time. + (setq re (format "^[ \t]*(\\(def\\(?:un\\|subst\\|\ +ine-derived-mode\\|ine-minor-mode\\|alias[ \t]+'\\)\\)\ +\[ \t]*%s\\([ \t;]+\\|$\\)" + (regexp-opt (mapcar 'cadr fnlist) t))) + (while (re-search-forward re nil t) + (skip-chars-forward " \t\n") + (setq fn (match-string 2) + sig (cond ((string-equal (match-string 1) + "define-derived-mode") + '(0 . 0)) + ((string-equal (match-string 1) + "define-minor-mode") + '(0 . 1)) + ;; Can't easily check alias arguments. + ((string-equal (match-string 1) + "defalias") + t) + (t + (if (looking-at "\\((\\|nil\\)") + (byte-compile-arglist-signature + (read (current-buffer)))))) + ;; alist of functions and arglist signatures. + siglist (cons (cons fn sig) siglist))))) + (dolist (e fnlist) + (setq arglist (nth 2 e) + type + (if re ; re non-nil means found a file + (if (setq sig (assoc (cadr e) siglist)) + ;; Recall we use t to mean no arglist specified, + ;; to distinguish from an empty arglist. + (unless (or (eq arglist t) + (eq sig t)) + (unless (equal (byte-compile-arglist-signature arglist) + (cdr sig)) + "arglist mismatch")) + "function not found") + "file not found")) + (when type + (setq errlist (cons (list (car e) (cadr e) type) errlist)))) + (message "%s%s" m (if errlist "problems found" "OK")) + errlist))) (defun check-declare-sort (alist) "Sort a list with elements FILE (FNFILE ...). -- cgit v1.2.3 From 9769d49f91e944dfe1b7a44684df4382c8a19411 Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Thu, 22 Nov 2007 04:19:48 +0000 Subject: (check-declare-scan): Expand .c files relative to src/ directory. (check-declare-verify): Handle .c files (without arg checking). --- lisp/ChangeLog | 15 +++++ lisp/emacs-lisp/check-declare.el | 117 ++++++++++++++++++++++----------------- 2 files changed, 80 insertions(+), 52 deletions(-) (limited to 'lisp/emacs-lisp/check-declare.el') diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 2280c706bd5..08cfd22f581 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,18 @@ +2007-11-22 Glenn Morris + + * dos-fns.el (int86): + * term/mac-win.el (mac-font-panel-mode): Fix declarations. + + * calendar/cal-menu.el (cal-menu-holidays-menu): Fix holiday-list call. + + * calendar/holidays.el (holiday-list): Add autoload cookie. + + * emacs-lisp/check-declare.el (check-declare-scan): Expand .c + files relative to src/ directory. + (check-declare-verify): Handle .c files (without arg checking). + + * emacs-lisp/byte-run.el (declare-function): Doc fix. + 2007-11-22 Dan Nicolaescu * replace.el (occur-mode-map): Add a major mode menu with entries diff --git a/lisp/emacs-lisp/check-declare.el b/lisp/emacs-lisp/check-declare.el index 76719f1b876..5da8691beed 100644 --- a/lisp/emacs-lisp/check-declare.el +++ b/lisp/emacs-lisp/check-declare.el @@ -34,7 +34,7 @@ ;; 1. Handle defstructs (eg uniquify-item-base in desktop.el). -;; 2. Check C files (look in src/)? +;; 2. Argument checking for functions defined in C. ;;; Code: @@ -56,7 +56,15 @@ ARGLIST may be absent. This claims that FNFILE defines FN, with ARGLIST." (setq fn (match-string 1) fnfile (match-string 2)) (or (file-name-absolute-p fnfile) - (setq fnfile (expand-file-name fnfile (file-name-directory file)))) + (setq fnfile + (expand-file-name fnfile + ;; .c files are assumed to be + ;; relative to the Emacs src/ directory. + (if (string-equal + "c" (file-name-extension fnfile)) + (expand-file-name "src" + source-directory) + (file-name-directory file))))) (setq alist (cons (list fnfile fn (progn @@ -80,59 +88,64 @@ FNFILE with the specified ARGLIST. Returns nil if all claims are found to be true, otherwise a list of errors with elements of the form \(FILE FN TYPE), where TYPE is a string giving details of the error." (let ((m (format "Checking %s..." fnfile)) + (cflag (string-equal "c" (file-name-extension fnfile))) re fn sig siglist arglist type errlist) (message "%s" m) - (if (string-equal (file-name-extension fnfile) "c") - (progn - (message "%sskipping C file" m) - nil) - (or (file-exists-p fnfile) - (setq fnfile (concat fnfile ".el"))) - (if (file-exists-p fnfile) - (with-temp-buffer - (insert-file-contents fnfile) - ;; defsubst's don't _have_ to be known at compile time. - (setq re (format "^[ \t]*(\\(def\\(?:un\\|subst\\|\ + (or cflag + (file-exists-p fnfile) + (setq fnfile (concat fnfile ".el"))) + (if (file-exists-p fnfile) + (with-temp-buffer + (insert-file-contents fnfile) + ;; defsubst's don't _have_ to be known at compile time. + (setq re (format (if cflag + "^[ \t]*\\(DEFUN\\)[ \t]*([ \t]*\"%s\"" + "^[ \t]*(\\(def\\(?:un\\|subst\\|\ ine-derived-mode\\|ine-minor-mode\\|alias[ \t]+'\\)\\)\ -\[ \t]*%s\\([ \t;]+\\|$\\)" - (regexp-opt (mapcar 'cadr fnlist) t))) - (while (re-search-forward re nil t) - (skip-chars-forward " \t\n") - (setq fn (match-string 2) - sig (cond ((string-equal (match-string 1) - "define-derived-mode") - '(0 . 0)) - ((string-equal (match-string 1) - "define-minor-mode") - '(0 . 1)) - ;; Can't easily check alias arguments. - ((string-equal (match-string 1) - "defalias") - t) - (t - (if (looking-at "\\((\\|nil\\)") - (byte-compile-arglist-signature - (read (current-buffer)))))) - ;; alist of functions and arglist signatures. - siglist (cons (cons fn sig) siglist))))) - (dolist (e fnlist) - (setq arglist (nth 2 e) - type - (if re ; re non-nil means found a file - (if (setq sig (assoc (cadr e) siglist)) - ;; Recall we use t to mean no arglist specified, - ;; to distinguish from an empty arglist. - (unless (or (eq arglist t) - (eq sig t)) - (unless (equal (byte-compile-arglist-signature arglist) - (cdr sig)) - "arglist mismatch")) - "function not found") - "file not found")) - (when type - (setq errlist (cons (list (car e) (cadr e) type) errlist)))) - (message "%s%s" m (if errlist "problems found" "OK")) - errlist))) +\[ \t]*%s\\([ \t;]+\\|$\\)") + (regexp-opt (mapcar 'cadr fnlist) t))) + (while (re-search-forward re nil t) + (skip-chars-forward " \t\n") + (setq fn (match-string 2) + ;; (min . max) for a fixed number of arguments, or + ;; arglists with optional elements. + ;; (min) for arglists with &rest. + sig (cond ((string-equal (match-string 1) + "define-derived-mode") + '(0 . 0)) + ((string-equal (match-string 1) + "define-minor-mode") + '(0 . 1)) + ;; Can't easily check alias arguments. + ((string-equal (match-string 1) + "defalias") + t) + (t + (if (looking-at "\\((\\|nil\\)") + (byte-compile-arglist-signature + (read (current-buffer)))))) + ;; alist of functions and arglist signatures. + siglist (cons (cons fn sig) siglist))))) + (dolist (e fnlist) + (setq arglist (nth 2 e) + type + (if re ; re non-nil means found a file + (if (setq sig (assoc (cadr e) siglist)) + ;; Recall we use t to mean no arglist specified, + ;; to distinguish from an empty arglist. + ;; FIXME c arg checking not yet implemented. + (unless (or cflag + (eq arglist t) + (eq sig t)) + (unless (equal (byte-compile-arglist-signature arglist) + (cdr sig)) + "arglist mismatch")) + "function not found") + "file not found")) + (when type + (setq errlist (cons (list (car e) (cadr e) type) errlist)))) + (message "%s%s" m (if errlist "problems found" "OK")) + errlist)) (defun check-declare-sort (alist) "Sort a list with elements FILE (FNFILE ...). -- cgit v1.2.3 From ad95f32a98471c83bbb612925e3f3cbc4d30d08d Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Thu, 22 Nov 2007 06:20:53 +0000 Subject: (check-declare-verify): Implement arglist checking for C files. --- lisp/emacs-lisp/check-declare.el | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'lisp/emacs-lisp/check-declare.el') diff --git a/lisp/emacs-lisp/check-declare.el b/lisp/emacs-lisp/check-declare.el index 5da8691beed..c1cdb3a2e80 100644 --- a/lisp/emacs-lisp/check-declare.el +++ b/lisp/emacs-lisp/check-declare.el @@ -34,8 +34,6 @@ ;; 1. Handle defstructs (eg uniquify-item-base in desktop.el). -;; 2. Argument checking for functions defined in C. - ;;; Code: (defconst check-declare-warning-buffer "*Check Declarations Warnings*" @@ -89,7 +87,7 @@ found to be true, otherwise a list of errors with elements of the form \(FILE FN TYPE), where TYPE is a string giving details of the error." (let ((m (format "Checking %s..." fnfile)) (cflag (string-equal "c" (file-name-extension fnfile))) - re fn sig siglist arglist type errlist) + re fn sig siglist arglist type errlist minargs maxargs) (message "%s" m) (or cflag (file-exists-p fnfile) @@ -110,7 +108,18 @@ ine-derived-mode\\|ine-minor-mode\\|alias[ \t]+'\\)\\)\ ;; (min . max) for a fixed number of arguments, or ;; arglists with optional elements. ;; (min) for arglists with &rest. - sig (cond ((string-equal (match-string 1) + sig (cond (cflag + (re-search-forward "," nil t 3) + (skip-chars-forward " \t\n") + ;; Assuming minargs and maxargs on same line. + (when (looking-at "\\([0-9]+\\)[ \t]*,[ \t]*\ +\\([0-9]+\\|MANY\\|UNEVALLED\\)") + (setq minargs (string-to-number (match-string 1)) + maxargs (match-string 2)) + (cons minargs (unless (string-match "[^0-9]" + maxargs) + (string-to-number maxargs))))) + ((string-equal (match-string 1) "define-derived-mode") '(0 . 0)) ((string-equal (match-string 1) @@ -133,9 +142,7 @@ ine-derived-mode\\|ine-minor-mode\\|alias[ \t]+'\\)\\)\ (if (setq sig (assoc (cadr e) siglist)) ;; Recall we use t to mean no arglist specified, ;; to distinguish from an empty arglist. - ;; FIXME c arg checking not yet implemented. - (unless (or cflag - (eq arglist t) + (unless (or (eq arglist t) (eq sig t)) (unless (equal (byte-compile-arglist-signature arglist) (cdr sig)) -- cgit v1.2.3 From 64cea5550d3c36c42da295585b8591e7fc58e6a6 Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Thu, 22 Nov 2007 06:53:24 +0000 Subject: (check-declare-verify): Fix previous change. Warn if could not find an arglist to check. --- lisp/emacs-lisp/check-declare.el | 48 ++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 19 deletions(-) (limited to 'lisp/emacs-lisp/check-declare.el') diff --git a/lisp/emacs-lisp/check-declare.el b/lisp/emacs-lisp/check-declare.el index c1cdb3a2e80..a4767794132 100644 --- a/lisp/emacs-lisp/check-declare.el +++ b/lisp/emacs-lisp/check-declare.el @@ -108,17 +108,22 @@ ine-derived-mode\\|ine-minor-mode\\|alias[ \t]+'\\)\\)\ ;; (min . max) for a fixed number of arguments, or ;; arglists with optional elements. ;; (min) for arglists with &rest. + ;; sig = 'err means we could not find an arglist. sig (cond (cflag - (re-search-forward "," nil t 3) - (skip-chars-forward " \t\n") - ;; Assuming minargs and maxargs on same line. - (when (looking-at "\\([0-9]+\\)[ \t]*,[ \t]*\ + (or + (when (re-search-forward "," nil t 3) + (skip-chars-forward " \t\n") + ;; Assuming minargs and maxargs on same line. + (when (looking-at "\\([0-9]+\\)[ \t]*,[ \t]*\ \\([0-9]+\\|MANY\\|UNEVALLED\\)") - (setq minargs (string-to-number (match-string 1)) - maxargs (match-string 2)) - (cons minargs (unless (string-match "[^0-9]" - maxargs) - (string-to-number maxargs))))) + (setq minargs (string-to-number + (match-string 1)) + maxargs (match-string 2)) + (cons minargs (unless (string-match "[^0-9]" + maxargs) + (string-to-number + maxargs))))) + 'err)) ((string-equal (match-string 1) "define-derived-mode") '(0 . 0)) @@ -129,24 +134,29 @@ ine-derived-mode\\|ine-minor-mode\\|alias[ \t]+'\\)\\)\ ((string-equal (match-string 1) "defalias") t) + ((looking-at "\\((\\|nil\\)") + (byte-compile-arglist-signature + (read (current-buffer)))) (t - (if (looking-at "\\((\\|nil\\)") - (byte-compile-arglist-signature - (read (current-buffer)))))) + 'err)) ;; alist of functions and arglist signatures. siglist (cons (cons fn sig) siglist))))) (dolist (e fnlist) (setq arglist (nth 2 e) type - (if re ; re non-nil means found a file - (if (setq sig (assoc (cadr e) siglist)) + (if re ; re non-nil means found a file + (if (setq sig (assoc (cadr e) siglist)) ; found function ;; Recall we use t to mean no arglist specified, ;; to distinguish from an empty arglist. - (unless (or (eq arglist t) - (eq sig t)) - (unless (equal (byte-compile-arglist-signature arglist) - (cdr sig)) - "arglist mismatch")) + (unless (eq arglist t) + (setq sig (cdr-safe sig)) + (cond ((eq sig t)) ; defalias, can't check + ((eq sig 'err) + "arglist not found") ; internal error + ((not (equal (byte-compile-arglist-signature + arglist) + sig)) + "arglist mismatch"))) "function not found") "file not found")) (when type -- cgit v1.2.3 From 7d4184ba6f4495a049b179c948acbd05da4c5040 Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Thu, 22 Nov 2007 20:25:51 +0000 Subject: (check-declare-locate): New function. (check-declare-scan): Use check-declare-locate. (check-declare-verify): No longer adjust fnfile, now check-declare-locate does it. --- lisp/emacs-lisp/check-declare.el | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) (limited to 'lisp/emacs-lisp/check-declare.el') diff --git a/lisp/emacs-lisp/check-declare.el b/lisp/emacs-lisp/check-declare.el index a4767794132..08172c08e95 100644 --- a/lisp/emacs-lisp/check-declare.el +++ b/lisp/emacs-lisp/check-declare.el @@ -39,6 +39,23 @@ (defconst check-declare-warning-buffer "*Check Declarations Warnings*" "Name of buffer used to display any `check-declare' warnings.") +(defun check-declare-locate (file basefile) + "Return the full path of FILE. +Expands files with a \".c\" extension relative to the Emacs +\"src/\" directory. Otherwise, `locate-library' searches for +FILE. If that fails, expands FILE relative to BASEFILE's +directory part. The returned file might not exist." + (if (string-equal "c" (file-name-extension file)) + (expand-file-name file (expand-file-name "src" source-directory)) + (let ((tfile (locate-library (file-name-nondirectory file)))) + (if tfile + (replace-regexp-in-string "\\.elc\\'" ".el" tfile) + (setq tfile (expand-file-name file (file-name-directory basefile))) + (if (or (file-exists-p tfile) + (string-match "\\.el\\'" tfile)) + tfile + (concat tfile ".el")))))) + (defun check-declare-scan (file) "Scan FILE for `declare-function' calls. Return a list with elements of the form (FNFILE FN ARGLIST), where @@ -52,18 +69,9 @@ ARGLIST may be absent. This claims that FNFILE defines FN, with ARGLIST." "^[ \t]*(declare-function[ \t]+\\(\\S-+\\)[ \t]+\ \"\\(\\S-+\\)\"" nil t) (setq fn (match-string 1) - fnfile (match-string 2)) - (or (file-name-absolute-p fnfile) - (setq fnfile - (expand-file-name fnfile - ;; .c files are assumed to be - ;; relative to the Emacs src/ directory. - (if (string-equal - "c" (file-name-extension fnfile)) - (expand-file-name "src" - source-directory) - (file-name-directory file))))) - (setq alist (cons + fnfile (match-string 2) + fnfile (check-declare-locate fnfile (expand-file-name file)) + alist (cons (list fnfile fn (progn (skip-chars-forward " \t\n") @@ -89,9 +97,6 @@ found to be true, otherwise a list of errors with elements of the form (cflag (string-equal "c" (file-name-extension fnfile))) re fn sig siglist arglist type errlist minargs maxargs) (message "%s" m) - (or cflag - (file-exists-p fnfile) - (setq fnfile (concat fnfile ".el"))) (if (file-exists-p fnfile) (with-temp-buffer (insert-file-contents fnfile) -- cgit v1.2.3 From faf7b3960e4cd3e0122529d9efdd337bc6f3d876 Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Sat, 24 Nov 2007 03:11:14 +0000 Subject: Comment. --- lisp/emacs-lisp/check-declare.el | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lisp/emacs-lisp/check-declare.el') diff --git a/lisp/emacs-lisp/check-declare.el b/lisp/emacs-lisp/check-declare.el index 08172c08e95..14342264bf6 100644 --- a/lisp/emacs-lisp/check-declare.el +++ b/lisp/emacs-lisp/check-declare.el @@ -30,6 +30,8 @@ ;; checks that all such statements in a file or directory are accurate. ;; The entry points are `check-declare-file' and `check-declare-directory'. +;; For more information, see Info node `elisp(Declaring Functions)'. + ;;; TODO: ;; 1. Handle defstructs (eg uniquify-item-base in desktop.el). -- cgit v1.2.3 From a6e02a86c73e9aae58fb4e761fba9330effb8cfd Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Tue, 27 Nov 2007 03:54:47 +0000 Subject: (check-declare-locate): Handle compressed files. (check-declare-verify): Handle define-generic-mode, define-global(ized)-minor-mode, define-obsolete-function-alias. --- lisp/emacs-lisp/check-declare.el | 63 +++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 23 deletions(-) (limited to 'lisp/emacs-lisp/check-declare.el') diff --git a/lisp/emacs-lisp/check-declare.el b/lisp/emacs-lisp/check-declare.el index 14342264bf6..800d0fa5fc0 100644 --- a/lisp/emacs-lisp/check-declare.el +++ b/lisp/emacs-lisp/check-declare.el @@ -36,6 +36,8 @@ ;; 1. Handle defstructs (eg uniquify-item-base in desktop.el). +;; 2. Handle fset (eg dired-omit-old-add-entry in dired-x.el). + ;;; Code: (defconst check-declare-warning-buffer "*Check Declarations Warnings*" @@ -51,7 +53,12 @@ directory part. The returned file might not exist." (expand-file-name file (expand-file-name "src" source-directory)) (let ((tfile (locate-library (file-name-nondirectory file)))) (if tfile - (replace-regexp-in-string "\\.elc\\'" ".el" tfile) + (progn + (setq tfile (replace-regexp-in-string "\\.elc\\'" ".el" tfile)) + (if (and (not (file-exists-p tfile)) + (file-exists-p (concat tfile ".gz"))) + (concat tfile ".gz") + tfile)) (setq tfile (expand-file-name file (file-name-directory basefile))) (if (or (file-exists-p tfile) (string-match "\\.el\\'" tfile)) @@ -106,12 +113,14 @@ found to be true, otherwise a list of errors with elements of the form (setq re (format (if cflag "^[ \t]*\\(DEFUN\\)[ \t]*([ \t]*\"%s\"" "^[ \t]*(\\(def\\(?:un\\|subst\\|\ -ine-derived-mode\\|ine-minor-mode\\|alias[ \t]+'\\)\\)\ +ine-\\(?:derived\\|generic\\|\\(?:global\\(?:ized\\)?-\\)?minor\\)-mode\ +\\|\\(?:ine-obsolete-function-\\)?alias[ \t]+'\\)\\)\ \[ \t]*%s\\([ \t;]+\\|$\\)") (regexp-opt (mapcar 'cadr fnlist) t))) (while (re-search-forward re nil t) (skip-chars-forward " \t\n") (setq fn (match-string 2) + type (match-string 1) ;; (min . max) for a fixed number of arguments, or ;; arglists with optional elements. ;; (min) for arglists with &rest. @@ -131,15 +140,21 @@ ine-derived-mode\\|ine-minor-mode\\|alias[ \t]+'\\)\\)\ (string-to-number maxargs))))) 'err)) - ((string-equal (match-string 1) - "define-derived-mode") + ((string-match + "\\`define-\\(derived\\|generic\\)-mode\\'" + type) '(0 . 0)) - ((string-equal (match-string 1) - "define-minor-mode") + ((string-match + "\\`define\\(-global\\(ized\\)?\\)?-minor-mode\\'" + type) '(0 . 1)) + ;; Prompt to update. + ((string-match + "\\`define-obsolete-function-alias\\>" + type) + 'obsolete) ;; Can't easily check alias arguments. - ((string-equal (match-string 1) - "defalias") + ((string-match "\\`defalias\\>" type) t) ((looking-at "\\((\\|nil\\)") (byte-compile-arglist-signature @@ -151,21 +166,23 @@ ine-derived-mode\\|ine-minor-mode\\|alias[ \t]+'\\)\\)\ (dolist (e fnlist) (setq arglist (nth 2 e) type - (if re ; re non-nil means found a file - (if (setq sig (assoc (cadr e) siglist)) ; found function - ;; Recall we use t to mean no arglist specified, - ;; to distinguish from an empty arglist. - (unless (eq arglist t) - (setq sig (cdr-safe sig)) - (cond ((eq sig t)) ; defalias, can't check - ((eq sig 'err) - "arglist not found") ; internal error - ((not (equal (byte-compile-arglist-signature - arglist) - sig)) - "arglist mismatch"))) - "function not found") - "file not found")) + (if (not re) + "file not found" + (if (not (setq sig (assoc (cadr e) siglist))) + "function not found" + (setq sig (cdr sig)) + (cond ((eq sig 'obsolete) ; check even when no arglist specified + "obsolete alias") + ;; arglist t means no arglist specified, as + ;; opposed to an empty arglist. + ((eq arglist t) nil) + ((eq sig t) nil) ; defalias, can't check + ((eq sig 'err) + "arglist not found") ; internal error + ((not (equal (byte-compile-arglist-signature + arglist) + sig)) + "arglist mismatch"))))) (when type (setq errlist (cons (list (car e) (cadr e) type) errlist)))) (message "%s%s" m (if errlist "problems found" "OK")) -- cgit v1.2.3 From 4ab4de9ce6fec1ff368f5b244ba1f8d3b37632cc Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Wed, 28 Nov 2007 03:53:44 +0000 Subject: (check-declare-locate): Reflow doc. (check-declare-verify): Handle fset. --- lisp/emacs-lisp/check-declare.el | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'lisp/emacs-lisp/check-declare.el') diff --git a/lisp/emacs-lisp/check-declare.el b/lisp/emacs-lisp/check-declare.el index 800d0fa5fc0..d98b59d774e 100644 --- a/lisp/emacs-lisp/check-declare.el +++ b/lisp/emacs-lisp/check-declare.el @@ -46,9 +46,9 @@ (defun check-declare-locate (file basefile) "Return the full path of FILE. Expands files with a \".c\" extension relative to the Emacs -\"src/\" directory. Otherwise, `locate-library' searches for -FILE. If that fails, expands FILE relative to BASEFILE's -directory part. The returned file might not exist." +\"src/\" directory. Otherwise, `locate-library' searches for FILE. +If that fails, expands FILE relative to BASEFILE's directory part. +The returned file might not exist." (if (string-equal "c" (file-name-extension file)) (expand-file-name file (expand-file-name "src" source-directory)) (let ((tfile (locate-library (file-name-nondirectory file)))) @@ -112,7 +112,7 @@ found to be true, otherwise a list of errors with elements of the form ;; defsubst's don't _have_ to be known at compile time. (setq re (format (if cflag "^[ \t]*\\(DEFUN\\)[ \t]*([ \t]*\"%s\"" - "^[ \t]*(\\(def\\(?:un\\|subst\\|\ + "^[ \t]*(\\(fset[ \t]+'\\|def\\(?:un\\|subst\\|\ ine-\\(?:derived\\|generic\\|\\(?:global\\(?:ized\\)?-\\)?minor\\)-mode\ \\|\\(?:ine-obsolete-function-\\)?alias[ \t]+'\\)\\)\ \[ \t]*%s\\([ \t;]+\\|$\\)") @@ -153,8 +153,8 @@ ine-\\(?:derived\\|generic\\|\\(?:global\\(?:ized\\)?-\\)?minor\\)-mode\ "\\`define-obsolete-function-alias\\>" type) 'obsolete) - ;; Can't easily check alias arguments. - ((string-match "\\`defalias\\>" type) + ;; Can't easily check arguments in these cases. + ((string-match "\\`\\(defalias\\|fset\\)\\>" type) t) ((looking-at "\\((\\|nil\\)") (byte-compile-arglist-signature @@ -176,7 +176,7 @@ ine-\\(?:derived\\|generic\\|\\(?:global\\(?:ized\\)?-\\)?minor\\)-mode\ ;; arglist t means no arglist specified, as ;; opposed to an empty arglist. ((eq arglist t) nil) - ((eq sig t) nil) ; defalias, can't check + ((eq sig t) nil) ; eg defalias - can't check arguments ((eq sig 'err) "arglist not found") ; internal error ((not (equal (byte-compile-arglist-signature -- cgit v1.2.3 From 122bcd7ef24fbf416f339dc093d0bf59bbb1ed5b Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Thu, 29 Nov 2007 04:23:49 +0000 Subject: (check-declare-locate, check-declare-verify): Handle `external' files. (check-declare-errmsg): New function. (check-declare-verify, check-declare-file, check-declare-directory): Use check-declare-errmsg to report the number of problems. --- lisp/emacs-lisp/check-declare.el | 68 +++++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 19 deletions(-) (limited to 'lisp/emacs-lisp/check-declare.el') diff --git a/lisp/emacs-lisp/check-declare.el b/lisp/emacs-lisp/check-declare.el index d98b59d774e..5d2ee740e4b 100644 --- a/lisp/emacs-lisp/check-declare.el +++ b/lisp/emacs-lisp/check-declare.el @@ -48,22 +48,31 @@ Expands files with a \".c\" extension relative to the Emacs \"src/\" directory. Otherwise, `locate-library' searches for FILE. If that fails, expands FILE relative to BASEFILE's directory part. -The returned file might not exist." - (if (string-equal "c" (file-name-extension file)) - (expand-file-name file (expand-file-name "src" source-directory)) - (let ((tfile (locate-library (file-name-nondirectory file)))) - (if tfile - (progn - (setq tfile (replace-regexp-in-string "\\.elc\\'" ".el" tfile)) - (if (and (not (file-exists-p tfile)) - (file-exists-p (concat tfile ".gz"))) - (concat tfile ".gz") - tfile)) - (setq tfile (expand-file-name file (file-name-directory basefile))) - (if (or (file-exists-p tfile) - (string-match "\\.el\\'" tfile)) - tfile - (concat tfile ".el")))))) +The returned file might not exist. If FILE has an \"ext:\" prefix, so does +the result." + (let ((ext (string-match "^ext:" file)) + tfile) + (if ext + (setq file (substring file 4))) + (setq file + (if (string-equal "c" (file-name-extension file)) + (expand-file-name file (expand-file-name "src" source-directory)) + (if (setq tfile (locate-library (file-name-nondirectory file))) + (progn + (setq tfile + (replace-regexp-in-string "\\.elc\\'" ".el" tfile)) + (if (and (not (file-exists-p tfile)) + (file-exists-p (concat tfile ".gz"))) + (concat tfile ".gz") + tfile)) + (setq tfile (expand-file-name file + (file-name-directory basefile))) + (if (or (file-exists-p tfile) + (string-match "\\.el\\'" tfile)) + tfile + (concat tfile ".el"))))) + (if ext (concat "ext:" file) + file))) (defun check-declare-scan (file) "Scan FILE for `declare-function' calls. @@ -93,6 +102,19 @@ ARGLIST may be absent. This claims that FNFILE defines FN, with ARGLIST." (message "%sdone" m) alist)) +(defun check-declare-errmsg (errlist &optional full) + "Return a string with the number of errors in ERRLIST, if any. +Normally just counts the number of elements in ERRLIST. +With optional argument FULL, sums the number of elements in each element." + (if errlist + (let ((l (length errlist))) + (when full + (setq l 0) + (dolist (e errlist) + (setq l (1+ l)))) + (format "%d problem%s found" l (if (= l 1) "" "s"))) + "OK")) + (autoload 'byte-compile-arglist-signature "bytecomp") (defun check-declare-verify (fnfile fnlist) @@ -104,8 +126,11 @@ found to be true, otherwise a list of errors with elements of the form \(FILE FN TYPE), where TYPE is a string giving details of the error." (let ((m (format "Checking %s..." fnfile)) (cflag (string-equal "c" (file-name-extension fnfile))) + (ext (string-match "^ext:" fnfile)) re fn sig siglist arglist type errlist minargs maxargs) (message "%s" m) + (if ext + (setq fnfile (substring fnfile 4))) (if (file-exists-p fnfile) (with-temp-buffer (insert-file-contents fnfile) @@ -185,7 +210,12 @@ ine-\\(?:derived\\|generic\\|\\(?:global\\(?:ized\\)?-\\)?minor\\)-mode\ "arglist mismatch"))))) (when type (setq errlist (cons (list (car e) (cadr e) type) errlist)))) - (message "%s%s" m (if errlist "problems found" "OK")) + (message "%s%s" m + (if (or re (not ext)) + (check-declare-errmsg errlist) + (prog1 + "skipping external file" + (setq errlist nil)))) errlist)) (defun check-declare-sort (alist) @@ -244,7 +274,7 @@ See `check-declare-directory' for more information." errlist) (message "%s" m) (setq errlist (check-declare-files file)) - (message "%s%s" m (if errlist "problems found" "OK")) + (message "%s%s" m (check-declare-errmsg errlist)) errlist)) ;;;###autoload @@ -267,7 +297,7 @@ described in the documentation of `declare-function'." (message "%s%d found" m2 (length files)) (when files (setq errlist (apply 'check-declare-files files)) - (message "%s%s" m (if errlist "problems found" "OK")) + (message "%s%s" m (check-declare-errmsg errlist t)) errlist))) (provide 'check-declare) -- cgit v1.2.3 From 630456e692497691ef97c9e3f140efc796817558 Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Fri, 30 Nov 2007 07:47:39 +0000 Subject: (check-declare-scan): Doc fix. Handle declare-function third argument `t' and fourth argument. (check-declare-verify): Doc fix. Handle `fileonly' case. Use progn rather than prog1. --- lisp/emacs-lisp/check-declare.el | 57 ++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 26 deletions(-) (limited to 'lisp/emacs-lisp/check-declare.el') diff --git a/lisp/emacs-lisp/check-declare.el b/lisp/emacs-lisp/check-declare.el index 5d2ee740e4b..9fc8a9e61e7 100644 --- a/lisp/emacs-lisp/check-declare.el +++ b/lisp/emacs-lisp/check-declare.el @@ -34,10 +34,6 @@ ;;; TODO: -;; 1. Handle defstructs (eg uniquify-item-base in desktop.el). - -;; 2. Handle fset (eg dired-omit-old-add-entry in dired-x.el). - ;;; Code: (defconst check-declare-warning-buffer "*Check Declarations Warnings*" @@ -76,10 +72,13 @@ the result." (defun check-declare-scan (file) "Scan FILE for `declare-function' calls. -Return a list with elements of the form (FNFILE FN ARGLIST), where -ARGLIST may be absent. This claims that FNFILE defines FN, with ARGLIST." +Return a list with elements of the form (FNFILE FN ARGLIST FILEONLY), +where only the first two elements need be present. This claims that FNFILE +defines FN, with ARGLIST. FILEONLY non-nil means only check that FNFILE +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) + alist fnfile fn arglist fileonly) (message "%s" m) (with-temp-buffer (insert-file-contents file) @@ -89,16 +88,18 @@ ARGLIST may be absent. This claims that FNFILE defines FN, with ARGLIST." (setq fn (match-string 1) fnfile (match-string 2) fnfile (check-declare-locate fnfile (expand-file-name file)) - alist (cons - (list fnfile fn - (progn - (skip-chars-forward " \t\n") - ;; Use `t' to distinguish no arglist - ;; specified from an empty one. - (if (looking-at "\\((\\|nil\\)") - (read (current-buffer)) - t))) - alist)))) + 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)))) (message "%sdone" m) alist)) @@ -119,11 +120,14 @@ With optional argument FULL, sums the number of elements in each element." (defun check-declare-verify (fnfile fnlist) "Check that FNFILE contains function definitions matching FNLIST. -Each element of FNLIST has the form (FILE FN ARGLIST), where -ARGLIST is optional. This means FILE claimed FN was defined in -FNFILE with the specified ARGLIST. Returns nil if all claims are -found to be true, otherwise a list of errors with elements of the form -\(FILE FN TYPE), where TYPE is a string giving details of the error." +Each element of FNLIST has the form (FILE FN ARGLIST FILEONLY), where +only the first two elements need be present. This means FILE claimed FN +was defined in FNFILE with the specified ARGLIST. FILEONLY non-nil means +to only check that FNFILE exists, not that it actually defines FN. + +Returns nil if all claims are found to be true, otherwise a list +of errors with elements of the form \(FILE FN TYPE), where TYPE +is a string giving details of the error." (let ((m (format "Checking %s..." fnfile)) (cflag (string-equal "c" (file-name-extension fnfile))) (ext (string-match "^ext:" fnfile)) @@ -194,7 +198,8 @@ ine-\\(?:derived\\|generic\\|\\(?:global\\(?:ized\\)?-\\)?minor\\)-mode\ (if (not re) "file not found" (if (not (setq sig (assoc (cadr e) siglist))) - "function not found" + (unless (nth 3 e) ; fileonly + "function not found") (setq sig (cdr sig)) (cond ((eq sig 'obsolete) ; check even when no arglist specified "obsolete alias") @@ -213,9 +218,9 @@ ine-\\(?:derived\\|generic\\|\\(?:global\\(?:ized\\)?-\\)?minor\\)-mode\ (message "%s%s" m (if (or re (not ext)) (check-declare-errmsg errlist) - (prog1 - "skipping external file" - (setq errlist nil)))) + (progn + (setq errlist nil) + "skipping external file"))) errlist)) (defun check-declare-sort (alist) -- cgit v1.2.3