Merge from emacs--devo--0, emacs--rel--22
[gnus] / lisp / mm-util.el
index db19de9..7a944bb 100644 (file)
@@ -1,7 +1,7 @@
 ;;; mm-util.el --- Utility functions for Mule and low level things
 
 ;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-;;   2005, 2006 Free Software Foundation, Inc.
+;;   2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;;     MORIOKA Tomohiko <morioka@jaist.ac.jp>
@@ -9,7 +9,7 @@
 
 ;; GNU Emacs 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)
+;; the Free Software Foundation; either version 3, or (at your option)
 ;; any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 
 ;;; Code:
 
+;; For Emacs < 22.2.
+(eval-and-compile
+  (unless (fboundp 'declare-function) (defmacro declare-function (&rest r))))
+
 (eval-when-compile (require 'cl))
 (require 'mail-prsvr)
 
        (require 'timer))
     (require 'timer)))
 
+(defvar mm-mime-mule-charset-alist )
+
 (eval-and-compile
-  (mapcar
+  (mapc
    (lambda (elem)
      (let ((nfunc (intern (format "mm-%s" (car elem)))))
        (if (fboundp (car elem))
           (defalias nfunc (car elem))
         (defalias nfunc (cdr elem)))))
-   '((decode-coding-string . (lambda (s a) s))
-     (encode-coding-string . (lambda (s a) s))
-     (encode-coding-region . ignore)
-     (coding-system-list . ignore)
-     (decode-coding-region . ignore)
+   '((coding-system-list . ignore)
      (char-int . identity)
      (coding-system-equal . equal)
      (annotationp . ignore)
      (multibyte-string-p . ignore)
      (insert-byte . insert-char)
      (multibyte-char-to-unibyte . identity)
+     (set-buffer-multibyte . ignore)
      (special-display-p
       . (lambda (buffer-name)
          "Returns non-nil if a buffer named BUFFER-NAME gets a special frame."
                            (string-match (car elem) buffer-name)
                            (throw 'return (cdr elem))))))))))))
 
+(eval-and-compile
+  (if (featurep 'xemacs)
+      (if (featurep 'file-coding)
+         ;; Don't modify string if CODING-SYSTEM is nil.
+         (progn
+           (defun mm-decode-coding-string (str coding-system)
+             (if coding-system
+                 (decode-coding-string str coding-system)
+               str))
+           (defun mm-encode-coding-string (str coding-system)
+             (if coding-system
+                 (encode-coding-string str coding-system)
+               str))
+           (defun mm-decode-coding-region (start end coding-system)
+             (if coding-system
+                 (decode-coding-region start end coding-system)))
+           (defun mm-encode-coding-region (start end coding-system)
+             (if coding-system
+                 (encode-coding-region start end coding-system))))
+       (defun mm-decode-coding-string (str coding-system) str)
+       (defun mm-encode-coding-string (str coding-system) str)
+       (defalias 'mm-decode-coding-region 'ignore)
+       (defalias 'mm-encode-coding-region 'ignore))
+    (defalias 'mm-decode-coding-string 'decode-coding-string)
+    (defalias 'mm-encode-coding-string 'encode-coding-string)
+    (defalias 'mm-decode-coding-region 'decode-coding-region)
+    (defalias 'mm-encode-coding-region 'encode-coding-region)))
+
 (defalias 'mm-string-to-multibyte
   (cond
    ((featurep 'xemacs)
@@ -189,7 +220,10 @@ non-nil, an alias is created and added to
 the alias.  Else windows-NUMBER is used."
   (interactive
    (let ((completion-ignore-case t)
-        (candidates (cp-supported-codepages)))
+        (candidates (if (fboundp 'cp-supported-codepages)
+                        (cp-supported-codepages)
+                      ;; Removed in Emacs 23 (unicode), sosignal an error:
+                      (error "`codepage-setup' is obsolete in this Emacs version."))))
      (list (completing-read "Setup DOS Codepage: (default 437) " candidates
                            nil t nil nil "437"))))
   (when alias
@@ -229,6 +263,16 @@ the alias.  Else windows-NUMBER is used."
     ,@(when (and (not (mm-coding-system-p 'windows-31j))
                 (mm-coding-system-p 'cp932))
        '((windows-31j . cp932)))
+    ;; Charset name: GBK, Charset aliases: CP936, MS936, windows-936
+    ;; http://www.iana.org/assignments/charset-reg/GBK
+    ;; Emacs 22.1 has cp936, but not gbk, so we alias it:
+    ,@(when (and (not (mm-coding-system-p 'gbk))
+                (mm-coding-system-p 'cp936))
+       '((gbk . cp936)))
+    ;; ISO8859-1 is a bogus name for ISO-8859-1
+    ,@(when (and (not (mm-coding-system-p 'iso8859-1))
+                (mm-coding-system-p 'iso-8859-1))
+       '((iso8859-1 . iso-8859-1)))
     )
   "A mapping from unknown or invalid charset names to the real charset names.
 
@@ -391,6 +435,7 @@ could use `autoload-coding-system' here."
                       (cons (symbol :tag "charset")
                             (symbol :tag "form"))))
   :group 'mime)
+(put 'mm-charset-eval-alist 'risky-local-variable t)
 
 (defvar mm-binary-coding-system
   (cond
@@ -451,6 +496,10 @@ could use `autoload-coding-system' here."
     (iso-2022-jp latin-jisx0201 japanese-jisx0208 japanese-jisx0208-1978)
     (euc-kr korean-ksc5601)
     (gb2312 chinese-gb2312)
+    (gbk chinese-gbk)
+    (gb18030 gb18030-2-byte
+            gb18030-4-byte-bmp gb18030-4-byte-smp
+            gb18030-4-byte-ext-1 gb18030-4-byte-ext-2)
     (big5 chinese-big5-1 chinese-big5-2)
     (tibetan tibetan)
     (thai-tis620 thai-tis620)
@@ -519,7 +568,7 @@ with Mule charsets.  It is completely useless for Emacs."
          cs mime mule alist)
       (while css
        (setq cs (pop css)
-             mime (or (coding-system-get cs :mime-charset) ; Emacs 23 (unicode)
+             mime (or (coding-system-get cs :mime-charset); Emacs 23 (unicode)
                       (coding-system-get cs 'mime-charset)))
        (when (and mime
                   (not (eq t (setq mule
@@ -849,9 +898,10 @@ This affects whether coding conversion should be attempted generally."
   (autoload 'latin-unity-massage-name "latin-unity")
   (autoload 'latin-unity-maybe-remap "latin-unity")
   (autoload 'latin-unity-representations-feasible-region "latin-unity")
-  (autoload 'latin-unity-representations-present-region "latin-unity")
-  (defvar latin-unity-coding-systems)
-  (defvar latin-unity-ucs-list))
+  (autoload 'latin-unity-representations-present-region "latin-unity"))
+
+(defvar latin-unity-coding-systems)
+(defvar latin-unity-ucs-list)
 
 (defun mm-xemacs-find-mime-charset-1 (begin end)
   "Determine which MIME charset to use to send region as message.
@@ -922,6 +972,8 @@ But this is very much a corner case, so don't worry about it."
   (when (featurep 'xemacs)
     `(and (featurep 'mule) (mm-xemacs-find-mime-charset-1 ,begin ,end))))
 
+(declare-function mm-delete-duplicates "mm-util" (list))
+
 (defun mm-find-mime-charset-region (b e &optional hack-charsets)
   "Return the MIME charsets needed to encode the region between B and E.
 nil means ASCII, a single-element list represents an appropriate MIME
@@ -968,6 +1020,8 @@ charset, and a longer list means no appropriate charset."
        ;; Otherwise, we'll get nil, and the next setq will get invoked.
        (setq charsets (mm-xemacs-find-mime-charset b e))
 
+       ;; Fixme: won't work for unibyte Emacs 23:
+
        ;; We're not multibyte, or a single coding system won't cover it.
        (setq charsets
              (mm-delete-duplicates
@@ -978,8 +1032,8 @@ charset, and a longer list means no appropriate charset."
             (memq 'iso-8859-15 charsets)
             (memq 'iso-8859-15 hack-charsets)
             (save-excursion (mm-iso-8859-x-to-15-region b e)))
-       (mapcar (lambda (x) (setq charsets (delq (car x) charsets)))
-               mm-iso-8859-15-compatible))
+       (dolist (x mm-iso-8859-15-compatible)
+         (setq charsets (delq (car x) charsets))))
     (if (and (memq 'iso-2022-jp-2 charsets)
             (memq 'iso-2022-jp-2 hack-charsets))
        (setq charsets (delq 'iso-2022-jp charsets)))
@@ -999,16 +1053,18 @@ charset, and a longer list means no appropriate charset."
 (defmacro mm-with-unibyte-buffer (&rest forms)
   "Create a temporary buffer, and evaluate FORMS there like `progn'.
 Use unibyte mode for this."
-  `(let (default-enable-multibyte-characters)
-     (with-temp-buffer ,@forms)))
+  `(with-temp-buffer
+     (mm-disable-multibyte)
+     ,@forms))
 (put 'mm-with-unibyte-buffer 'lisp-indent-function 0)
 (put 'mm-with-unibyte-buffer 'edebug-form-spec '(body))
 
 (defmacro mm-with-multibyte-buffer (&rest forms)
   "Create a temporary buffer, and evaluate FORMS there like `progn'.
 Use multibyte mode for this."
-  `(let ((default-enable-multibyte-characters t))
-     (with-temp-buffer ,@forms)))
+  `(with-temp-buffer
+     (mm-enable-multibyte)
+     ,@forms))
 (put 'mm-with-multibyte-buffer 'lisp-indent-function 0)
 (put 'mm-with-multibyte-buffer 'edebug-form-spec '(body))
 
@@ -1061,10 +1117,10 @@ Emacs 23 (unicode)."
     ;; Remove composition since the base charsets have been included.
     ;; Remove eight-bit-*, treat them as ascii.
     (let ((css (find-charset-region b e)))
-      (mapcar (lambda (cs) (setq css (delq cs css)))
-             '(composition eight-bit-control eight-bit-graphic
-                           control-1))
-      css))
+      (dolist (cs
+              '(composition eight-bit-control eight-bit-graphic control-1)
+              css)
+       (setq css (delq cs css)))))
    (t
     ;; We are in a unibyte buffer or XEmacs non-mule, so we futz around a bit.
     (save-excursion
@@ -1098,7 +1154,7 @@ Emacs 23 (unicode)."
     (nreverse out)))
 
 (defvar mm-inhibit-file-name-handlers
-  '(jka-compr-handler image-file-handler)
+  '(jka-compr-handler image-file-handler epa-file-handler)
   "A list of handlers doing (un)compression (etc) thingies.")
 
 (defun mm-insert-file-contents (filename &optional visit beg end replace
@@ -1172,6 +1228,8 @@ If INHIBIT is non-nil, inhibit `mm-inhibit-file-name-handlers'."
           inhibit-file-name-handlers)))
     (write-region start end filename append visit lockname)))
 
+(autoload 'gmm-write-region "gmm-utils")
+
 ;; It is not a MIME function, but some MIME functions use it.
 (if (and (fboundp 'make-temp-file)
         (ignore-errors
@@ -1263,6 +1321,8 @@ If SUFFIX is non-nil, add that at the end of the file name."
          (if (eq (point) end) 'ascii (mm-guess-charset))
        (goto-char point)))))
 
+(declare-function mm-detect-coding-region "mm-util" (start end))
+
 (if (fboundp 'coding-system-get)
     (defun mm-detect-mime-charset-region (start end)
       "Detect MIME charset of the text in the region between START and END."
@@ -1405,7 +1465,7 @@ gzip, bzip2, etc. are allowed."
                    (funcall (symbol-value 'set-auto-coding-function)
                             nil (- (point-max) (point-min)))
                  (error nil)))))
-          ((featurep 'file-coding) ;; XEmacs
+          ((and (featurep 'xemacs) (featurep 'file-coding)) ;; XEmacs
            (let ((case-fold-search t)
                  (end (point-at-eol))
                  codesys start)