X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=tl-822.el;h=3464c68b425d300aaf29c33d66c40e71aa25b762;hb=92c6f7232633f831366a00b4ce55e1a93c9b7eca;hp=08d0a5d761822ebda7fd8b182eaf5d1cb8f5eecf;hpb=a750aa303c901c82d389140dd049996ed9d2ec8c;p=elisp%2Fmu-cite.git diff --git a/tl-822.el b/tl-822.el index 08d0a5d..3464c68 100644 --- a/tl-822.el +++ b/tl-822.el @@ -1,102 +1,54 @@ -;;; ;;; tl-822.el --- RFC 822 parser for GNU Emacs -;;; -;;; Copyright (C) 1995 Free Software Foundation, Inc. -;;; Copyright (C) 1995,1996 MORIOKA Tomohiko -;;; -;;; Author: MORIOKA Tomohiko -;;; Keywords: mail, news, RFC 822 -;;; -;;; This file is part of tl (Tiny Library). -;;; -;;; This program 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 2, or -;;; (at your option) any later version. -;;; -;;; This program 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 This program. If not, write to the Free Software -;;; Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. -;;; + +;; Copyright (C) 1995,1996 Free Software Foundation, Inc. + +;; Author: MORIOKA Tomohiko +;; Keywords: mail, news, RFC 822 + +;; This file is part of tl (Tiny Library). + +;; This program 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 2, or (at +;; your option) any later version. + +;; This program 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 This program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + ;;; Code: (require 'tl-seq) (require 'tl-str) +(require 'std11) (defconst rfc822/RCS-ID - "$Id: tl-822.el,v 7.12 1996-04-19 19:20:52 morioka Exp $") + "$Id: tl-822.el,v 7.60 1996-08-28 22:52:29 morioka Exp $") (defconst rfc822/version (get-version-string rfc822/RCS-ID)) -;;; @ field +;;; @ header ;;; -(defconst rfc822/field-name-regexp "[!-9;-~]+") - -(defconst rfc822/field-top-regexp - (concat "\\(" rfc822/field-name-regexp "\\):")) - -(defconst rfc822::next-field-top-regexp (concat "\n" rfc822/field-top-regexp)) - -(defun rfc822/field-end () - (if (re-search-forward rfc822::next-field-top-regexp nil t) - (goto-char (match-beginning 0)) - (if (re-search-forward "^$" nil t) - (goto-char (1- (match-beginning 0))) - (end-of-line) - )) - (point) - ) - -(defun rfc822/get-field-body (name) - (let ((case-fold-search t)) - (save-excursion - (save-restriction - (narrow-to-region - (goto-char (point-min)) - (or (and (re-search-forward "^$" nil t) (match-end 0)) - (point-max) - )) - (goto-char (point-min)) - (if (re-search-forward (concat "^" name ":[ \t]*") nil t) - (buffer-substring-no-properties - (match-end 0) - (rfc822/field-end) - )) - )))) +(defalias 'rfc822/narrow-to-header 'std11-narrow-to-header) +(defalias 'rfc822/get-header-string 'std11-header-string) +(defalias 'rfc822/get-header-string-except 'std11-header-string-except) +(defalias 'rfc822/get-field-names 'std11-collect-field-names) -;;; @ header +;;; @ field ;;; -(defun rfc822/get-header-string-except (pat boundary) - (let ((case-fold-search t)) - (save-excursion - (save-restriction - (narrow-to-region (goto-char (point-min)) - (progn - (re-search-forward - (concat "^\\(" (regexp-quote boundary) "\\)?$") - nil t) - (match-beginning 0) - )) - (goto-char (point-min)) - (let (field header) - (while (re-search-forward rfc822/field-top-regexp nil t) - (setq field (buffer-substring (match-beginning 0) - (rfc822/field-end) - )) - (if (not (string-match pat field)) - (setq header (concat header field "\n")) - )) - header) - )))) +(defalias `rfc822/field-end 'std11-field-end) +(defalias 'rfc822/get-field-body 'std11-find-field-body) +(defalias 'rfc822/get-field-bodies 'std11-find-field-bodies) ;;; @ quoting @@ -106,15 +58,12 @@ (defconst rfc822/quoted-pair-regexp "\\\\.") (defconst rfc822/non-qtext-char-list '(?\" ?\\ ?\r ?\n)) (defconst rfc822/qtext-regexp - (concat "[^" (char-list-to-string rfc822/non-qtext-char-list) " \t]")) + (concat "[^" (char-list-to-string rfc822/non-qtext-char-list) "]")) (defconst rfc822/quoted-string-regexp (concat "\"" (regexp-* - (concat - "\\(" rfc822/linear-white-space-regexp "?" - (regexp-or rfc822/qtext-regexp rfc822/quoted-pair-regexp) - "\\)")) - rfc822/linear-white-space-regexp "?" + (regexp-or rfc822/qtext-regexp rfc822/quoted-pair-regexp) + ) "\"")) (defun rfc822/wrap-as-quoted-string (str) @@ -162,521 +111,28 @@ ;;; @ unfolding ;;; -(defun rfc822/unfolding-string (str) - (let ((dest "")) - (while (string-match "\n\\s +" str) - (setq dest (concat dest (substring str 0 (match-beginning 0)) " ")) - (setq str (substring str (match-end 0))) - ) - (concat dest str) - )) +(defalias 'rfc822/unfolding-string 'std11-unfold-string) ;;; @ lexical analyze ;;; -(defconst rfc822/special-chars "][()<>@,;:\\<>.\"") -(defconst rfc822/space-chars " \t\n") -(defconst rfc822/non-atom-chars - (concat rfc822/special-chars rfc822/space-chars)) -(defconst rfc822/non-dtext-chars "[]") -(defconst rfc822/non-ctext-chars "()") - -(defun rfc822/analyze-spaces (str) - (let ((i (position-mismatched - (function - (lambda (elt) - (find elt rfc822/space-chars) - )) str)) - ) - (if (> i 0) - (cons (cons 'spaces (substring str 0 i)) - (substring str i) - )) - )) - -(defun rfc822/analyze-special (str) - (if (and (> (length str) 0) - (find (elt str 0) rfc822/special-chars) - ) - (cons (cons 'specials (substring str 0 1)) - (substring str 1) - )) - ) - -(defun rfc822/analyze-atom (str) - (let ((i (position-mismatched - (function - (lambda (elt) - (not (find elt rfc822/non-atom-chars)) - )) str)) - ) - (if (> i 0) - (cons (cons 'atom (substring str 0 i)) - (substring str i) - )) - )) - -(defun rfc822/analyze-quoted-pair (str) - (if (and (>= (length str) 2) - (eq (elt str 0) ?\\) - ) - (cons (cons 'quoted-pair (substring str 0 2)) - (substring str 2) - )) - ) - -(defun rfc822/analyze-quoted-string (str) - (if (and (> (length str) 0) - (eq (elt str 0) ?\") - ) - (let* ((i (position-mismatched - (function - (lambda (elt) - (not (memq elt rfc822/non-qtext-char-list)) - )) - (setq str (substring str 1)) - )) - (rest (substring str i)) - ) - (if (and (> i 0) - (> (length rest) 0) - (eq (elt rest 0) ?\") - ) - (cons (cons 'quoted-string (substring str 0 i)) - (substring rest 1) - ) - )))) - -(defun rfc822/analyze-domain-literal (str) - (if (and (> (length str) 0) - (eq (elt str 0) ?\[) - ) - (let* ((i (position-mismatched - (function - (lambda (elt) - (not (find elt rfc822/non-dtext-chars)) - )) - (setq str (substring str 1)) - )) - (rest (substring str i)) - ) - (if (and (> i 0) - (> (length rest) 0) - (eq (elt rest 0) ?\]) - ) - (cons (cons 'domain-literal (substring str 0 i)) - (substring rest 1) - ) - )))) - -(defun rfc822/analyze-comment (str) - (if (and (> (length str) 0) - (eq (elt str 0) ?\() - ) - (let ((dest "") - chr p ret) - (setq str (substring str 1)) - (catch 'tag - (while (not (string-equal str "")) - (setq p (position-mismatched - (function - (lambda (elt) - (not (find elt rfc822/non-ctext-chars)) - )) str)) - (cond ((> p 0) - (setq dest (concat dest (substring str 0 p))) - (setq str (substring str p)) - ) - ((setq ret (rfc822/analyze-comment str)) - (setq dest (concat dest "(" (cdr (car ret)) ")")) - (setq str (cdr ret)) - ) - (t (throw 'tag nil)) - ) - )) - (if (and (> (length str) 0) - (eq (elt str 0) ?\)) - ) - (cons (cons 'comment dest) - (substring str 1) - ) - )))) - -(defun rfc822/lexical-analyze (str) - (let (dest - (i 0)(len (length str)) - ret) - (while (not (string-equal str "")) - (setq ret - (or (rfc822/analyze-quoted-string str) - (rfc822/analyze-domain-literal str) - (rfc822/analyze-comment str) - (rfc822/analyze-spaces str) - (rfc822/analyze-special str) - (rfc822/analyze-atom str) - '((error) . "") - )) - (setq dest (cons (car ret) dest)) - (setq str (cdr ret)) - ) - (nreverse dest) - )) +(defalias 'rfc822/lexical-analyze 'std11-lexical-analyze) ;;; @ parser ;;; -(defun rfc822/ignored-token-p (token) - (let ((type (car token))) - (or (eq type 'spaces)(eq type 'comment)) - )) - -(defun rfc822/parse-token (lal) - (let (token itl) - (while (and lal - (progn - (setq token (car lal)) - (rfc822/ignored-token-p token) - )) - (setq lal (cdr lal)) - (setq itl (cons token itl)) - ) - (cons (nreverse (cons token itl)) - (cdr lal)) - )) - -(defun rfc822/parse-ascii-token (lal) - (let (token itl parsed token-value) - (while (and lal - (setq token (car lal)) - (if (and (setq token-value (cdr token)) - (find-charset-string token-value) - ) - (setq token nil) - (rfc822/ignored-token-p token) - )) - (setq lal (cdr lal)) - (setq itl (cons token itl)) - ) - (if (and token - (setq parsed (nreverse (cons token itl))) - ) - (cons parsed (cdr lal)) - ))) - -(defun rfc822/parse-token-or-comment (lal) - (let (token itl) - (while (and lal - (progn - (setq token (car lal)) - (eq (car token) 'spaces) - )) - (setq lal (cdr lal)) - (setq itl (cons token itl)) - ) - (cons (reverse (cons token itl)) - (cdr lal)) - )) +(defalias 'rfc822/parse-address 'std11-parse-address) +(defalias 'rfc822/parse-addresses 'std11-parse-addresses) +(defalias 'rfc822/address-string 'std11-address-string) +(defalias 'rfc822/full-name-string 'std11-full-name-string) -(defun rfc822/parse-word (lal) - (let ((ret (rfc822/parse-ascii-token lal))) - (if ret - (let ((elt (car ret)) - (rest (cdr ret)) - ) - (if (or (assq 'atom elt) - (assq 'quoted-string elt)) - (cons (cons 'word elt) rest) - ))))) - -(defun rfc822/parse-word-or-comment (lal) - (let ((ret (rfc822/parse-token-or-comment lal))) - (if ret - (let ((elt (car ret)) - (rest (cdr ret)) - ) - (cond ((or (assq 'atom elt) - (assq 'quoted-string elt)) - (cons (cons 'word elt) rest) - ) - ((assq 'comment elt) - (cons (cons 'comment-word elt) rest) - )) - )))) - -(defun rfc822/parse-phrase (lal) - (let (ret phrase) - (while (setq ret (rfc822/parse-word-or-comment lal)) - (setq phrase (append phrase (cdr (car ret)))) - (setq lal (cdr ret)) - ) - (if phrase - (cons (cons 'phrase phrase) lal) - ))) - -(defun rfc822/parse-local-part (lal) - (let ((ret (rfc822/parse-word lal))) - (if ret - (let ((local-part (cdr (car ret))) dot) - (setq lal (cdr ret)) - (while (and (setq ret (rfc822/parse-ascii-token lal)) - (setq dot (car ret)) - (string-equal (cdr (assq 'specials dot)) ".") - (setq ret (rfc822/parse-word (cdr ret))) - (setq local-part - (append local-part dot (cdr (car ret))) - ) - (setq lal (cdr ret)) - )) - (cons (cons 'local-part local-part) lal) - )))) - -(defun rfc822/parse-sub-domain (lal) - (let ((ret (rfc822/parse-ascii-token lal))) - (if ret - (let ((sub-domain (car ret))) - (if (or (assq 'atom sub-domain) - (assq 'domain-literal sub-domain) - ) - (cons (cons 'sub-domain sub-domain) - (cdr ret) - ) - ))))) - -(defun rfc822/parse-domain (lal) - (let ((ret (rfc822/parse-sub-domain lal))) - (if ret - (let ((domain (cdr (car ret))) dot) - (setq lal (cdr ret)) - (while (and (setq ret (rfc822/parse-ascii-token lal)) - (setq dot (car ret)) - (string-equal (cdr (assq 'specials dot)) ".") - (setq ret (rfc822/parse-sub-domain (cdr ret))) - (setq domain - (append domain dot (cdr (car ret))) - ) - (setq lal (cdr ret)) - )) - (cons (cons 'domain domain) lal) - )))) - -(defun rfc822/parse-at-domain (lal) - (let ((ret (rfc822/parse-ascii-token lal)) at-sign) - (if (and ret - (setq at-sign (car ret)) - (string-equal (cdr (assq 'specials at-sign)) "@") - (setq ret (rfc822/parse-domain (cdr ret))) - ) - (cons (cons 'at-domain (append at-sign (cdr (car ret)))) - (cdr ret)) - ))) - -(defun rfc822/parse-addr-spec (lal) - (let ((ret (rfc822/parse-local-part lal)) - addr at-sign) - (if (and ret - (prog1 - (setq addr (cdr (car ret))) - (setq lal (cdr ret)) - (and (setq ret (rfc822/parse-at-domain lal)) - (setq addr (append addr (cdr (car ret)))) - (setq lal (cdr ret)) - ))) - (cons (cons 'addr-spec addr) lal) - ))) - -(defun rfc822/parse-route (lal) - (let ((ret (rfc822/parse-at-domain lal)) - route comma colon) - (if (and ret - (progn - (setq route (cdr (car ret))) - (setq lal (cdr ret)) - (while (and (setq ret (rfc822/parse-ascii-token lal)) - (setq comma (car ret)) - (string-equal (cdr (assq 'specials comma)) ",") - (setq ret (rfc822/parse-at-domain (cdr ret))) - ) - (setq route (append route comma (cdr (car ret)))) - (setq lal (cdr ret)) - ) - (and (setq ret (rfc822/parse-ascii-token lal)) - (setq colon (car ret)) - (string-equal (cdr (assq 'specials colon)) ":") - (setq route (append route colon)) - ) - )) - (cons (cons 'route route) - (cdr ret) - ) - ))) - -(defun rfc822/parse-route-addr (lal) - (let ((ret (rfc822/parse-ascii-token lal)) - < route addr-spec >) - (if (and ret - (setq < (car ret)) - (string-equal (cdr (assq 'specials <)) "<") - (setq lal (cdr ret)) - (progn (and (setq ret (rfc822/parse-route lal)) - (setq route (cdr (car ret))) - (setq lal (cdr ret)) - ) - (setq ret (rfc822/parse-addr-spec lal)) - ) - (setq addr-spec (cdr (car ret))) - (setq lal (cdr ret)) - (setq ret (rfc822/parse-ascii-token lal)) - (setq > (car ret)) - (string-equal (cdr (assq 'specials >)) ">") - ) - (cons (cons 'route-addr (append route addr-spec)) - (cdr ret) - ) - ))) - -(defun rfc822/parse-phrase-route-addr (lal) - (let ((ret (rfc822/parse-phrase lal)) phrase) - (if ret - (progn - (setq phrase (cdr (car ret))) - (setq lal (cdr ret)) - )) - (if (setq ret (rfc822/parse-route-addr lal)) - (cons (list 'phrase-route-addr - phrase - (cdr (car ret))) - (cdr ret)) - ))) - -(defun rfc822/parse-mailbox (lal) - (let ((ret (or (rfc822/parse-phrase-route-addr lal) - (rfc822/parse-addr-spec lal))) - mbox comment) - (if (and ret - (prog1 - (setq mbox (car ret)) - (setq lal (cdr ret)) - (if (and (setq ret (rfc822/parse-token-or-comment lal)) - (setq comment (cdr (assq 'comment (car ret)))) - ) - (setq lal (cdr ret)) - ))) - (cons (list 'mailbox mbox comment) - lal) - ))) - -(defun rfc822/parse-group (lal) - (let ((ret (rfc822/parse-phrase lal)) - phrase colon comma mbox semicolon) - (if (and ret - (setq phrase (cdr (car ret))) - (setq lal (cdr ret)) - (setq ret (rfc822/parse-ascii-token lal)) - (setq colon (car ret)) - (string-equal (cdr (assq 'specials colon)) ":") - (setq lal (cdr ret)) - (progn - (and (setq ret (rfc822/parse-mailbox lal)) - (setq mbox (list (car ret))) - (setq lal (cdr ret)) - (progn - (while (and (setq ret (rfc822/parse-ascii-token lal)) - (setq comma (car ret)) - (string-equal - (cdr (assq 'specials comma)) ",") - (setq lal (cdr ret)) - (setq ret (rfc822/parse-mailbox lal)) - (setq mbox (cons (car ret) mbox)) - (setq lal (cdr ret)) - ) - ))) - (and (setq ret (rfc822/parse-ascii-token lal)) - (setq semicolon (car ret)) - (string-equal (cdr (assq 'specials semicolon)) ";") - ))) - (cons (list 'group phrase (reverse mbox)) - (cdr ret) - ) - ))) - -(defun rfc822/parse-address (lal) - (or (rfc822/parse-group lal) - (rfc822/parse-mailbox lal) - )) - -(defun rfc822/parse-addresses (lal) - (let ((ret (rfc822/parse-address lal))) - (if ret - (let ((dest (list (car ret)))) - (setq lal (cdr ret)) - (while (and (setq ret (rfc822/parse-ascii-token lal)) - (string-equal (cdr (assq 'specials (car ret))) ",") - (setq ret (rfc822/parse-address (cdr ret))) - ) - (setq dest (cons (car ret) dest)) - (setq lal (cdr ret)) - ) - (reverse dest) - )))) - -(defun rfc822/addr-to-string (seq) - (mapconcat (function - (lambda (token) - (if (eq (car token) 'spaces) - "" - (cdr token) - ))) - seq "") - ) - -(defun rfc822/address-string (address) - (cond ((eq (car address) 'group) - (mapconcat (function rfc822/address-string) - (nth 2 address) - ", ") - ) - ((eq (car address) 'mailbox) - (let ((addr (nth 1 address)) - addr-spec) - (rfc822/addr-to-string - (if (eq (car addr) 'phrase-route-addr) - (nth 2 addr) - (cdr addr) - ) - ))))) - -(defun rfc822/full-name-string (address) - (cond ((eq (car address) 'group) - (mapconcat (function - (lambda (token) - (cdr token) - )) - (nth 1 address) "") - ) - ((eq (car address) 'mailbox) - (let ((addr (nth 1 address)) - (comment (nth 2 address)) - phrase) - (if (eq (car addr) 'phrase-route-addr) - (setq phrase (mapconcat (function - (lambda (token) - (cdr token) - )) - (nth 1 addr) "")) - ) - (or phrase comment) - )))) - -(defun rfc822/extract-address-components (str) - "Extract full name and canonical address from STR. +(defun rfc822/extract-address-components (string) + "Extract full name and canonical address from STRING. Returns a list of the form (FULL-NAME CANONICAL-ADDRESS). If no name can be extracted, FULL-NAME will be nil. [tl-822.el]" - (let* ((structure (car - (rfc822/parse-address - (rfc822/lexical-analyze str) - ))) + (let* ((structure (car (std11-parse-address-string string))) (phrase (rfc822/full-name-string structure)) (address (rfc822/address-string structure)) )