X-Git-Url: http://cgit.sxemacs.org/?a=blobdiff_plain;f=lisp%2Frfc2231.el;h=8ee24b9512788c2c36a918aefda8660b280b393f;hb=6dec94a79261794ce4ce843a2780d23a4effa334;hp=2998472aca2e8ba288af92b1db715c8fc38deb70;hpb=4332ff5dba684cb07cd519a6d8d9b4c197ada538;p=gnus diff --git a/lisp/rfc2231.el b/lisp/rfc2231.el index 2998472ac..8ee24b951 100644 --- a/lisp/rfc2231.el +++ b/lisp/rfc2231.el @@ -1,5 +1,5 @@ ;;; rfc2231.el --- Functions for decoding rfc2231 headers -;; Copyright (C) 1998 Free Software Foundation, Inc. +;; Copyright (C) 1998,99 Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen ;; This file is part of GNU Emacs. @@ -23,7 +23,7 @@ ;;; Code: -(require 'drums) +(require 'ietf-drums) (defun rfc2231-get-value (ct attribute) "Return the value of ATTRIBUTE from CT." @@ -34,86 +34,93 @@ The list will be on the form `(name (attribute . value) (attribute . value)...)" (with-temp-buffer - (let ((ttoken (drums-token-to-list drums-text-token)) - (stoken (drums-token-to-list drums-tspecials)) - (ntoken (drums-token-to-list "0-9")) + (let ((ttoken (ietf-drums-token-to-list ietf-drums-text-token)) + (stoken (ietf-drums-token-to-list ietf-drums-tspecials)) + (ntoken (ietf-drums-token-to-list "0-9")) (prev-value "") display-name mailbox c display-string parameters attribute value type subtype number encoded prev-attribute) - (drums-init (mail-header-remove-whitespace - (mail-header-remove-comments string))) - (let ((table (copy-syntax-table drums-syntax-table))) + (ietf-drums-init (mail-header-remove-whitespace + (mail-header-remove-comments string))) + (let ((table (copy-syntax-table ietf-drums-syntax-table))) (modify-syntax-entry ?\' "w" table) + ;; The following isn't valid, but one should be liberal + ;; in what one receives. + (modify-syntax-entry ?\: "w" table) (set-syntax-table table)) - (setq c (following-char)) + (setq c (char-after)) (when (and (memq c ttoken) (not (memq c stoken))) (setq type (downcase (buffer-substring (point) (progn (forward-sexp 1) (point))))) ;; Do the params (while (not (eobp)) - (setq c (following-char)) + (setq c (char-after)) (unless (eq c ?\;) (error "Invalid header: %s" string)) (forward-char 1) - (setq c (following-char)) - (if (and (memq c ttoken) - (not (memq c stoken))) - (setq attribute - (intern - (downcase - (buffer-substring - (point) (progn (forward-sexp 1) (point)))))) - (error "Invalid header: %s" string)) - (setq c (following-char)) - (setq encoded nil) - (when (eq c ?*) + ;; If c in nil, then this is an invalid header, but + ;; since elm generates invalid headers on this form, + ;; we allow it. + (when (setq c (char-after)) + (if (and (memq c ttoken) + (not (memq c stoken))) + (setq attribute + (intern + (downcase + (buffer-substring + (point) (progn (forward-sexp 1) (point)))))) + (error "Invalid header: %s" string)) + (setq c (char-after)) + (setq encoded nil) + (when (eq c ?*) + (forward-char 1) + (setq c (char-after)) + (when (memq c ntoken) + (setq number + (string-to-number + (buffer-substring + (point) (progn (forward-sexp 1) (point))))) + (setq c (char-after)) + (when (eq c ?*) + (setq encoded t) + (forward-char 1) + (setq c (char-after))))) + ;; See if we have any previous continuations. + (when (and prev-attribute + (not (eq prev-attribute attribute))) + (push (cons prev-attribute prev-value) parameters) + (setq prev-attribute nil + prev-value "")) + (unless (eq c ?=) + (error "Invalid header: %s" string)) (forward-char 1) - (setq c (following-char)) - (when (memq c ntoken) - (setq number - (string-to-number - (buffer-substring - (point) (progn (forward-sexp 1) (point))))) - (setq c (following-char)) - (when (eq c ?*) - (setq encoded t) - (forward-char 1) - (setq c (following-char))))) - ;; See if we have any previous continuations. - (when (and prev-attribute - (not (eq prev-attribute attribute))) - (push (cons prev-attribute prev-value) parameters) - (setq prev-attribute nil - prev-value "")) - (unless (eq c ?=) - (error "Invalid header: %s" string)) - (forward-char 1) - (setq c (following-char)) - (cond - ((eq c ?\") - (setq value - (buffer-substring (1+ (point)) - (progn (forward-sexp 1) (1- (point)))))) - ((and (memq c ttoken) - (not (memq c stoken))) - (setq value (buffer-substring - (point) (progn (forward-sexp 1) (point))))) - (t - (error "Invalid header: %s" string))) - (when encoded - (setq value (rfc2231-decode-encoded-string value))) - (if number - (setq prev-attribute attribute - prev-value (concat prev-value value)) - (push (cons attribute value) parameters))) + (setq c (char-after)) + (cond + ((eq c ?\") + (setq value + (buffer-substring (1+ (point)) + (progn (forward-sexp 1) (1- (point)))))) + ((and (memq c ttoken) + (not (memq c stoken))) + (setq value (buffer-substring + (point) (progn (forward-sexp 1) (point))))) + (t + (error "Invalid header: %s" string))) + (when encoded + (setq value (rfc2231-decode-encoded-string value))) + (if number + (setq prev-attribute attribute + prev-value (concat prev-value value)) + (push (cons attribute value) parameters)))) ;; Take care of any final continuations. (when prev-attribute (push (cons prev-attribute prev-value) parameters)) - `(,type ,@(nreverse parameters)))))) + (when type + `(,type ,@(nreverse parameters))))))) (defun rfc2231-decode-encoded-string (string) "Decode an RFC2231-encoded string. @@ -137,6 +144,64 @@ These look like \"us-ascii'en-us'This%20is%20%2A%2A%2Afun%2A%2A%2A\"." (intern (car elems)))) (buffer-string)))) +(defun rfc2231-encode-string (param value) + "Return and PARAM=VALUE string encoded according to RFC2231." + (let ((control (ietf-drums-token-to-list ietf-drums-no-ws-ctl-token)) + (tspecial (ietf-drums-token-to-list ietf-drums-tspecials)) + (special (ietf-drums-token-to-list "*'%\n\t")) + (ascii (ietf-drums-token-to-list ietf-drums-text-token)) + (num -1) + spacep encodep charsetp charset broken) + (with-temp-buffer + (insert value) + (goto-char (point-min)) + (while (not (eobp)) + (cond + ((or (memq (following-char) control) + (memq (following-char) tspecial) + (memq (following-char) special)) + (setq encodep t)) + ((eq (following-char) ? ) + (setq spacep t)) + ((not (memq (following-char) ascii)) + (setq charsetp t))) + (forward-char 1)) + (when charsetp + (setq charset (mm-encode-body))) + (cond + ((or encodep charsetp) + (goto-char (point-min)) + (while (not (eobp)) + (when (> (current-column) 60) + (insert "\n") + (setq broken t)) + (if (or (not (memq (following-char) ascii)) + (memq (following-char) control) + (memq (following-char) tspecial) + (memq (following-char) special) + (eq (following-char) ? )) + (progn + (insert "%" (format "%02x" (following-char))) + (delete-char 1)) + (forward-char 1))) + (goto-char (point-min)) + (insert (or charset "ascii") "''") + (goto-char (point-min)) + (if (not broken) + (insert param "*=") + (while (not (eobp)) + (insert param "*" (format "%d" (incf num)) "*=") + (forward-line 1)))) + (spacep + (goto-char (point-min)) + (insert param "=\"") + (goto-char (point-max)) + (insert "\"")) + (t + (goto-char (point-min)) + (insert param "="))) + (buffer-string)))) + (provide 'rfc2231) ;;; rfc2231.el ends here