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))))))