+(defvar elint-env) ; from elint-init-env
+
+(defun elint-init-form (form)
+ "Process FORM, adding to ELINT-ENV if recognized."
+ (cond
+ ;; Eg nnmaildir seems to use [] as a form of comment syntax.
+ ((not (listp form))
+ (elint-warning "Skipping non-list form `%s'" form))
+ ;; Add defined variable
+ ((memq (car form) '(defvar defconst defcustom))
+ (setq elint-env (elint-env-add-var elint-env (cadr form))))
+ ;; Add function
+ ((memq (car form) '(defun defsubst))
+ (setq elint-env (elint-env-add-func elint-env (cadr form) (nth 2 form))))
+ ;; FIXME needs a handler to say second arg is not a variable when we come
+ ;; to scan the form.
+ ((eq (car form) 'define-derived-mode)
+ (setq elint-env (elint-env-add-func elint-env (cadr form) ())
+ elint-env (elint-env-add-var elint-env (cadr form))
+ elint-env (elint-env-add-var elint-env
+ (intern (format "%s-map" (cadr form))))))
+ ((eq (car form) 'define-minor-mode)
+ (setq elint-env (elint-env-add-func elint-env (cadr form) '(&optional arg))
+ ;; FIXME mode map?
+ elint-env (elint-env-add-var elint-env (cadr form))))
+ ((and (eq (car form) 'easy-menu-define)
+ (cadr form))
+ (setq elint-env (elint-env-add-func elint-env (cadr form) '(event))
+ elint-env (elint-env-add-var elint-env (cadr form))))
+ ;; FIXME it would be nice to check the autoloads are correct.
+ ((eq (car form) 'autoload)
+ (setq elint-env (elint-env-add-func elint-env (cadr (cadr form)) 'unknown)))
+ ((eq (car form) 'declare-function)
+ (setq elint-env (elint-env-add-func
+ elint-env (cadr form)
+ (if (or (< (length form) 4)
+ (eq (nth 3 form) t)
+ (unless (stringp (nth 2 form))
+ (elint-error "Malformed declaration for `%s'"
+ (cadr form))
+ t))
+ 'unknown
+ (nth 3 form)))))
+ ((and (eq (car form) 'defalias) (listp (nth 2 form)))
+ ;; If the alias points to something already in the environment,
+ ;; add the alias to the environment with the same arguments.
+ ;; FIXME symbol-function, eg backquote.el?
+ (let ((def (elint-env-find-func elint-env (cadr (nth 2 form)))))
+ (setq elint-env (elint-env-add-func elint-env (cadr (cadr form))
+ (if def (cadr def) 'unknown)))))
+ ;; Add macro, both as a macro and as a function
+ ((eq (car form) 'defmacro)
+ (setq elint-env (elint-env-add-macro elint-env (cadr form)
+ (cons 'lambda (cddr form)))
+ elint-env (elint-env-add-func elint-env (cadr form) (nth 2 form))))
+ ((and (eq (car form) 'put)
+ (= 4 (length form))
+ (eq (car-safe (cadr form)) 'quote)
+ (equal (nth 2 form) '(quote error-conditions)))
+ (set (make-local-variable 'elint-extra-errors)
+ (cons (cadr (cadr form)) elint-extra-errors)))
+ ((eq (car form) 'provide)
+ (add-to-list 'elint-features (eval (cadr form))))
+ ;; Import variable definitions
+ ((memq (car form) '(require cc-require cc-require-when-compile))
+ (let ((name (eval (cadr form)))
+ (file (eval (nth 2 form)))
+ (elint-doing-cl (bound-and-true-p elint-doing-cl)))
+ (unless (memq name elint-features)
+ (add-to-list 'elint-features name)
+ ;; cl loads cl-macs in an opaque manner.
+ ;; Since cl-macs requires cl, we can just process cl-macs.
+ ;; FIXME: AFAIK, `cl' now behaves properly and does not need any
+ ;; special treatment any more. Can someone who understands this
+ ;; code confirm? --Stef
+ (and (eq name 'cl) (not elint-doing-cl)
+ ;; We need cl if elint-form is to be able to expand cl macros.
+ (require 'cl)
+ (setq name 'cl-macs
+ file nil
+ elint-doing-cl t)) ; blech
+ (setq elint-env (elint-add-required-env elint-env name file))))))
+ elint-env)
+