X-Git-Url: http://git.chise.org/gitweb/?p=elisp%2Fflim.git;a=blobdiff_plain;f=mime-def.el;h=9ee7781a1b555b1845872059433889722a88e474;hp=e479011d23c66d8bf62cd8d20dc69e72fa618b96;hb=HEAD;hpb=8c7cab8199f8a11ab69dc7731d9e5306f58e86d5 diff --git a/mime-def.el b/mime-def.el index e479011..9ee7781 100644 --- a/mime-def.el +++ b/mime-def.el @@ -1,8 +1,10 @@ -;;; mime-def.el --- definition module about MIME +;;; mime-def.el --- definition module about MIME -*- coding: iso-8859-4; -*- -;; Copyright (C) 1995,1996,1997,1998 Free Software Foundation, Inc. +;; Copyright (C) 1995,96,97,98,99,2000,2001,2002,2003,2004,2005,2006 +;; Free Software Foundation, Inc. -;; Author: MORIOKA Tomohiko +;; Author: MORIOKA Tomohiko +;; Shuhei KOBAYASHI ;; Keywords: definition, MIME, multimedia, mail, news ;; This file is part of FLIM (Faithful Library about Internet Message). @@ -19,17 +21,20 @@ ;; 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., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. ;;; Code: +(require 'custom) (require 'mcharset) +(require 'alist) + +(eval-when-compile (require 'luna)) ; luna-arglist-to-arguments (eval-and-compile - (defconst mime-library-product ["FLIM" (1 11 3) "Saidaiji"] - "Product name, version number and code name of MIME-library package.") - ) + (defconst mime-library-product ["FLIM" (1 14 9) "Gojò"] + "Product name, version number and code name of MIME-library package.")) (defmacro mime-product-name (product) `(aref ,product 0)) @@ -51,32 +56,73 @@ ;;; @ variables ;;; -(require 'custom) - -(eval-when-compile (require 'cl)) - -(defgroup mime nil +(defgroup mime '((default-mime-charset custom-variable)) "Emacs MIME Interfaces" :group 'news :group 'mail) -(custom-handle-keyword 'default-mime-charset :group 'mime - 'custom-variable) - (defcustom mime-uuencode-encoding-name-list '("x-uue" "x-uuencode") "*List of encoding names for uuencode format." :group 'mime :type '(repeat string)) -;;; @ required functions +;;; @@ for encoded-word +;;; + +(defgroup mime-header nil + "Header representation, specially encoded-word" + :group 'mime) + +;;; @@@ decoding ;;; -(defsubst eliminate-top-spaces (string) - "Eliminate top sequence of space or tab in STRING." - (if (string-match "^[ \t]+" string) - (substring string (match-end 0)) - string)) +(defcustom mime-field-decoding-max-size 1000 + "*Max size to decode header field." + :group 'mime-header + :type '(choice (integer :tag "Limit (bytes)") + (const :tag "Don't limit" nil))) + +(defcustom mime-header-accept-quoted-encoded-words nil + "*Accept encoded-words in quoted-strings." + :group 'mime-header + :type 'boolean) + + +;;; @@@ encoding +;;; + +(defcustom mime-field-encoding-method-alist + '(("X-Nsubject" . iso-2022-jp-2) + ("Newsgroups" . nil) + ("Message-ID" . nil) + (t . mime) + ) + "*Alist to specify field encoding method. +Its key is field-name, value is encoding method. + +If method is `mime', this field will be encoded into MIME format. + +If method is a MIME-charset, this field will be encoded as the charset +when it must be convert into network-code. + +If method is `default-mime-charset', this field will be encoded as +variable `default-mime-charset' when it must be convert into +network-code. + +If method is nil, this field will not be encoded." + :group 'mime-header + :type '(repeat (cons (choice :tag "Field" + (string :tag "Name") + (const :tag "Default" t)) + (choice :tag "Method" + (const :tag "MIME conversion" mime) + (symbol :tag "non-MIME conversion") + (const :tag "no-conversion" nil))))) + + +;;; @ required functions +;;; (defsubst regexp-* (regexp) (concat regexp "*")) @@ -84,33 +130,32 @@ (defsubst regexp-or (&rest args) (concat "\\(" (mapconcat (function identity) args "\\|") "\\)")) +(or (fboundp 'char-int) + (defalias 'char-int 'identity)) -;;; @ about STD 11 -;;; -(eval-and-compile - (defconst std11-quoted-pair-regexp "\\\\.") - (defconst std11-non-qtext-char-list '(?\" ?\\ ?\r ?\n)) - (defconst std11-qtext-regexp - (eval-when-compile - (concat "[^" (apply #'string std11-non-qtext-char-list) "]")))) -(defconst std11-quoted-string-regexp - (eval-when-compile - (concat "\"" - (regexp-* - (regexp-or std11-qtext-regexp std11-quoted-pair-regexp)) - "\""))) +;;; @ MIME constants +;;; +(defconst mime-tspecial-char-list + '(?\] ?\[ ?\( ?\) ?< ?> ?@ ?, ?\; ?: ?\\ ?\" ?/ ?? ?=)) +(defconst mime-token-regexp + (concat "[^" mime-tspecial-char-list "\000-\040]+")) +(defconst mime-attribute-char-regexp + (concat "[^" mime-tspecial-char-list "\000-\040" + "*'%" ; introduced in RFC 2231. + "]")) -;;; @ about MIME -;;; +(defconst mime-charset-regexp + (concat "[^" mime-tspecial-char-list "\000-\040" + "*'%" ; should not include "%"? + "]+")) -(defconst mime-tspecials "][()<>@,\;:\\\"/?=") -(defconst mime-token-regexp (concat "[^" mime-tspecials "\000-\040]+")) -(defconst mime-charset-regexp mime-token-regexp) +;; More precisely, length of "[A-Za-z]+" is limited to at most 8. +;; (defconst mime-language-regexp "[A-Za-z]+\\(-[A-Za-z]+\\)*") +(defconst mime-language-regexp "[-A-Za-z]+") -(defconst mime-media-type/subtype-regexp - (concat mime-token-regexp "/" mime-token-regexp)) +(defconst mime-encoding-regexp mime-token-regexp) ;;; @@ base64 / B @@ -156,26 +201,25 @@ ;;; (defsubst make-mime-content-type (type subtype &optional parameters) - (list* (cons 'type type) - (cons 'subtype subtype) - (nreverse parameters)) - ) + (cons (cons 'type type) + (cons (cons 'subtype subtype) + parameters))) (defsubst mime-content-type-primary-type (content-type) "Return primary-type of CONTENT-TYPE." (cdr (car content-type))) (defsubst mime-content-type-subtype (content-type) - "Return primary-type of CONTENT-TYPE." - (cdr (cadr content-type))) + "Return subtype of CONTENT-TYPE." + (cdr (car (cdr content-type)))) (defsubst mime-content-type-parameters (content-type) - "Return primary-type of CONTENT-TYPE." - (cddr content-type)) + "Return parameters of CONTENT-TYPE." + (cdr (cdr content-type))) (defsubst mime-content-type-parameter (content-type parameter) "Return PARAMETER value of CONTENT-TYPE." - (cdr (assoc parameter (mime-content-type-parameters content-type)))) + (cdr (assoc parameter (cdr (cdr content-type))))) (defsubst mime-type/subtype-string (type &optional subtype) @@ -189,6 +233,10 @@ ;;; @ Content-Disposition ;;; +(defsubst make-mime-content-disposition (type &optional parameters) + (cons (cons 'type type) + parameters)) + (defsubst mime-content-disposition-type (content-disposition) "Return disposition-type of CONTENT-DISPOSITION." (cdr (car content-disposition))) @@ -206,130 +254,6 @@ (mime-content-disposition-parameter content-disposition "filename")) -;;; @ MIME entity -;;; - -(defmacro make-mime-entity-internal (representation-type location - &optional content-type - children parent node-id - ;; for NOV - decoded-subject decoded-from - date message-id references - chars lines - xref - ;; for other fields - original-header parsed-header - ;; for buffer representation - buffer - header-start header-end - body-start body-end) - `(vector ,representation-type ,location - ,content-type nil nil ,children ,parent ,node-id - ;; for NOV - ,decoded-subject ,decoded-from - ,date ,message-id ,references - ,chars ,lines - ,xref - ;; for other fields - ,original-header ,parsed-header - ;; for buffer representation - ,buffer ,header-start ,header-end ,body-start ,body-end)) - -(defmacro mime-entity-representation-type-internal (entity) - `(aref ,entity 0)) -(defmacro mime-entity-set-representation-type-internal (entity type) - `(aset ,entity 0 ,type)) -(defmacro mime-entity-location-internal (entity) - `(aref ,entity 1)) -(defmacro mime-entity-set-location-internal (entity location) - `(aset ,entity 1 ,location)) - -(defmacro mime-entity-content-type-internal (entity) - `(aref ,entity 2)) -(defmacro mime-entity-set-content-type-internal (entity type) - `(aset ,entity 2 ,type)) -(defmacro mime-entity-content-disposition-internal (entity) - `(aref ,entity 3)) -(defmacro mime-entity-set-content-disposition-internal (entity disposition) - `(aset ,entity 3 ,disposition)) -(defmacro mime-entity-encoding-internal (entity) - `(aref ,entity 4)) -(defmacro mime-entity-set-encoding-internal (entity encoding) - `(aset ,entity 4 ,encoding)) - -(defmacro mime-entity-children-internal (entity) - `(aref ,entity 5)) -(defmacro mime-entity-set-children-internal (entity children) - `(aset ,entity 5 ,children)) -(defmacro mime-entity-parent-internal (entity) - `(aref ,entity 6)) -(defmacro mime-entity-node-id-internal (entity) - `(aref ,entity 7)) - -(defmacro mime-entity-decoded-subject-internal (entity) - `(aref ,entity 8)) -(defmacro mime-entity-set-decoded-subject-internal (entity subject) - `(aset ,entity 8 ,subject)) -(defmacro mime-entity-decoded-from-internal (entity) - `(aref ,entity 9)) -(defmacro mime-entity-set-decoded-from-internal (entity from) - `(aset ,entity 9 ,from)) -(defmacro mime-entity-date-internal (entity) - `(aref ,entity 10)) -(defmacro mime-entity-set-date-internal (entity date) - `(aset ,entity 10 ,date)) -(defmacro mime-entity-message-id-internal (entity) - `(aref ,entity 11)) -(defmacro mime-entity-set-message-id-internal (entity message-id) - `(aset ,entity 11 ,message-id)) -(defmacro mime-entity-references-internal (entity) - `(aref ,entity 12)) -(defmacro mime-entity-set-references-internal (entity references) - `(aset ,entity 12 ,references)) -(defmacro mime-entity-chars-internal (entity) - `(aref ,entity 13)) -(defmacro mime-entity-set-chars-internal (entity chars) - `(aset ,entity 13 ,chars)) -(defmacro mime-entity-lines-internal (entity) - `(aref ,entity 14)) -(defmacro mime-entity-set-lines-internal (entity lines) - `(aset ,entity 14 ,lines)) -(defmacro mime-entity-xref-internal (entity) - `(aref ,entity 15)) -(defmacro mime-entity-set-xref-internal (entity xref) - `(aset ,entity 15 ,xref)) - -(defmacro mime-entity-original-header-internal (entity) - `(aref ,entity 16)) -(defmacro mime-entity-set-original-header-internal (entity header) - `(aset ,entity 16 ,header)) -(defmacro mime-entity-parsed-header-internal (entity) - `(aref ,entity 17)) -(defmacro mime-entity-set-parsed-header-internal (entity header) - `(aset ,entity 17 ,header)) - -(defmacro mime-entity-buffer-internal (entity) - `(aref ,entity 18)) -(defmacro mime-entity-set-buffer-internal (entity buffer) - `(aset ,entity 18 ,buffer)) -(defmacro mime-entity-header-start-internal (entity) - `(aref ,entity 19)) -(defmacro mime-entity-set-header-start-internal (entity point) - `(aset ,entity 19 ,point)) -(defmacro mime-entity-header-end-internal (entity) - `(aref ,entity 20)) -(defmacro mime-entity-set-header-end-internal (entity point) - `(aset ,entity 20 ,point)) -(defmacro mime-entity-body-start-internal (entity) - `(aref ,entity 21)) -(defmacro mime-entity-set-body-start-internal (entity point) - `(aset ,entity 21 ,point)) -(defmacro mime-entity-body-end-internal (entity) - `(aref ,entity 22)) -(defmacro mime-entity-set-body-end-internal (entity point) - `(aset ,entity 22 ,point)) - - ;;; @ message structure ;;; @@ -339,12 +263,7 @@ Please use reference function `mime-entity-SLOT' to get value of SLOT. Following is a list of slots of the structure: -buffer buffer includes this entity (buffer). node-id node-id (list of integers) -header-start minimum point of header in raw-buffer -header-end maximum point of header in raw-buffer -body-start minimum point of body in raw-buffer -body-end maximum point of body in raw-buffer content-type content-type (content-type) content-disposition content-disposition (content-disposition) encoding Content-Transfer-Encoding (string or nil) @@ -356,83 +275,7 @@ message/rfc822, `mime-entity' structures of them are included in (make-variable-buffer-local 'mime-message-structure) - -;;; @ for mm-backend -;;; - -(require 'alist) - -(defvar mime-entity-implementation-alist nil) - -(defmacro mm-define-backend (type &optional parents) - "Define TYPE as a mm-backend. -If PARENTS is specified, TYPE inherits PARENTS. -Each parent must be backend name (symbol)." - (if parents - `(let ((rest ',(reverse parents))) - (while rest - (set-alist 'mime-entity-implementation-alist - ',type - (copy-alist - (cdr (assq (car rest) - mime-entity-implementation-alist)))) - (setq rest (cdr rest)) - )))) - -(defmacro mm-define-method (name args &rest body) - "Define NAME as a method function of (nth 1 (car ARGS)) backend. - -ARGS is like an argument list of lambda, but (car ARGS) must be -specialized parameter. (car (car ARGS)) is name of variable and (nth -1 (car ARGS)) is name of backend." - (let* ((specializer (car args)) - (class (nth 1 specializer)) - (self (car specializer))) - `(let ((imps (cdr (assq ',class mime-entity-implementation-alist))) - (func (lambda ,(if self - (cons self (cdr args)) - (cdr args)) - ,@body))) - (if imps - (set-alist 'mime-entity-implementation-alist - ',class (put-alist ',name func imps)) - (set-alist 'mime-entity-implementation-alist - ',class - (list (cons ',name func))) - )))) - -(put 'mm-define-method 'lisp-indent-function 'defun) - -(eval-when-compile - (defmacro eval-module-depended-macro (module definition) - (condition-case nil - (progn - (require (eval module)) - definition) - (error `(eval-after-load ,(symbol-name (eval module)) ',definition)) - )) - ) - -(eval-module-depended-macro - 'edebug - (def-edebug-spec mm-define-method - (&define name ((arg symbolp) - [&rest arg] - [&optional ["&optional" arg &rest arg]] - &optional ["&rest" arg] - ) - def-body)) - ) - -(defsubst mm-arglist-to-arguments (arglist) - (let (dest) - (while arglist - (let ((arg (car arglist))) - (or (memq arg '(&optional &rest)) - (setq dest (cons arg dest))) - ) - (setq arglist (cdr arglist))) - (nreverse dest))) +(make-obsolete-variable 'mime-message-structure "should not use it.") ;;; @ for mel-backend @@ -446,12 +289,12 @@ If ARGS is specified, NAME is defined as a generic function for the service." `(progn (add-to-list 'mel-service-list ',name) - (defvar ,(intern (format "%s-obarray" name)) (make-vector 1 nil)) + (defvar ,(intern (format "%s-obarray" name)) (make-vector 7 0)) ,@(if args `((defun ,name ,args ,@rest (funcall (mel-find-function ',name ,(car (last args))) - ,@(mm-arglist-to-arguments (butlast args))) + ,@(luna-arglist-to-arguments (butlast args))) ))) ))