Function: nnmail-split-it

nnmail-split-it is a byte-compiled function defined in nnmail.el.gz.

Signature

(nnmail-split-it SPLIT)

Source Code

;; Defined in /usr/src/emacs/lisp/gnus/nnmail.el.gz
;; Alist of split expressions their equivalent regexps.

(defun nnmail-split-it (split)
  ;; Return a list of groups matching SPLIT.
  (let (cached-pair)
    (cond
     ;; nil split
     ((null split)
      nil)

     ;; A group name.  Do the \& and \N subs into the string.
     ((stringp split)
      (nnmail-log-split split)
      (list (nnmail-expand-newtext split t)))

     ;; Junk the message.
     ((eq split 'junk)
      (nnmail-log-split "junk")
      (list 'junk))

     ;; Builtin & operation.
     ((eq (car split) '&)
      (mapcan 'nnmail-split-it (cdr split)))

     ;; Builtin | operation.
     ((eq (car split) '|)
      (let (done)
	(while (and (not done) (cdr split))
	  (setq split (cdr split)
		done (nnmail-split-it (car split))))
	done))

     ;; Builtin : operation.
     ((eq (car split) ':)
      (nnmail-log-split split)
      (nnmail-split-it (save-excursion (eval (cdr split) t))))

     ;; Builtin ! operation.
     ((eq (car split) '!)
      (funcall (cadr split) (nnmail-split-it (caddr split))))

     ;; Check the cache for the regexp for this split.
     ((setq cached-pair (assq split nnmail-split-cache))
      (let (split-result
	    match-data
	    (end-point (point-max))
	    (value (nth 1 split)))
	(if (symbolp value)
	    (setq value (cdr (assq value nnmail-split-abbrev-alist))))
	(while (and (goto-char end-point)
		    (re-search-backward (cdr cached-pair) nil t))
	  (setq match-data (match-data))
	  (nnmail-log-split split)
	  (let ((split-rest (cddr split))
		(end (match-end 0))
		;; The searched regexp is \(\(FIELD\).*\)\(VALUE\).
		;; So, start-of-value is the point just before the
		;; beginning of the value, whereas after-header-name
		;; is the point just after the field name.
		(start-of-value (match-end 1))
		(after-header-name (match-end 2)))
	    ;; Start the next search just before the beginning of the
	    ;; VALUE match.
	    (setq end-point (1- start-of-value))
	    ;; Handle - RESTRICTs
	    (while (eq (car split-rest) '-)
	      ;; RESTRICT must start after-header-name and
	      ;; end after start-of-value, so that, for
	      ;; (any "foo" - "x-foo" "foo.list")
	      ;; we do not exclude foo.list just because
	      ;; the header is: ``To: x-foo, foo''
	      (goto-char end)
	      (setq split-rest
                    (unless (and (re-search-backward (cadr split-rest)
                                                     after-header-name t)
                                 (> (match-end 0) start-of-value))
                      (cddr split-rest))))
	    (when split-rest
	      (goto-char end)
	      ;; Someone might want to do a \N sub on this match, so
	      ;; restore the match data.
	      (set-match-data match-data)
	      (dolist (sp (nnmail-split-it (car split-rest)))
		(unless (member sp split-result)
		  (push sp split-result))))))
	split-result))

     ;; Not in cache, compute a regexp for the field/value pair.
     (t
      (let ((field (nth 0 split))
	    (value (nth 1 split))
	    (split-rest (cddr split))
	    partial-front
	    partial-rear
	    regexp)
	(if (symbolp value)
	    (setq value (cdr (assq value nnmail-split-abbrev-alist))))
	(if (and (>= (length value) 2)
		 (string= ".*" (substring value 0 2)))
	    (setq value (substring value 2)
		  partial-front ""))
	;; Same trick for the rear of the regexp
	(if (and (>= (length value) 2)
		 (string= ".*" (substring value -2)))
	    (setq value (substring value 0 -2)
		  partial-rear ""))
	;; Invert the match-partial-words behavior if the optional
	;; last element is specified.
	(while (eq (car split-rest) '-)
	  (setq split-rest (cddr split-rest)))
	(when (if (cadr split-rest)
		  (not nnmail-split-fancy-match-partial-words)
		nnmail-split-fancy-match-partial-words)
	  (setq partial-front ""
		partial-rear ""))
	(setq regexp (concat "^\\(\\("
			     (if (symbolp field)
				 (cdr (assq field nnmail-split-abbrev-alist))
			       field)
			     "\\):.*\\)"
			     (or partial-front "\\<")
			     "\\("
			     value
			     "\\)"
			     (or partial-rear "\\>")))
	(push (cons split regexp) nnmail-split-cache)
	;; Now that it's in the cache, just call nnmail-split-it again
	;; on the same split, which will find it immediately in the cache.
	(nnmail-split-it split))))))