Remove nnml-retrieve-groups that is unnecessary and somewhat problematic
[gnus] / lisp / mm-util.el
index 588915a..ab9145f 100644 (file)
@@ -1,7 +1,6 @@
 ;;; mm-util.el --- Utility functions for Mule and low level things
 
-;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
-;;   2007, 2008, 2009, 2010  Free Software Foundation, Inc.
+;; Copyright (C) 1998-2015 Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;;     MORIOKA Tomohiko <morioka@jaist.ac.jp>
 
 ;;; 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)))
 
 (defvar mm-mime-mule-charset-alist )
+;; Note this is not presently used on Emacs >= 23, which is good,
+;; since it means standalone message-mode (which requires mml and
+;; hence mml-util) does not load gnus-util.
+(autoload 'gnus-completing-read "gnus-util")
 
 ;; Emulate functions that are not available in every (X)Emacs version.
 ;; The name of a function is prefixed with mm-, like `mm-char-int' for
       . ,(lambda (prompt)
           "Return a charset."
           (intern
-           (completing-read
+           (gnus-completing-read
             prompt
-            (mapcar (lambda (e) (list (symbol-name (car e))))
+            (mapcar (lambda (e) (symbol-name (car e)))
                     mm-mime-mule-charset-alist)
-            nil t))))
+            t))))
      ;; `subst-char-in-string' is not available in XEmacs 21.4.
      (subst-char-in-string
       . ,(lambda (from to string &optional inplace)
      (multibyte-char-to-unibyte . identity)
      ;; `set-buffer-multibyte' is an Emacs function, not available in XEmacs.
      (set-buffer-multibyte . ignore)
-     ;; `special-display-p' is an Emacs function, not available in XEmacs.
-     (special-display-p
-      . ,(lambda (buffer-name)
-          "Returns non-nil if a buffer named BUFFER-NAME gets a special frame."
-          (and special-display-function
-               (or (and (member buffer-name special-display-buffer-names) t)
-                   (cdr (assoc buffer-name special-display-buffer-names))
-                   (catch 'return
-                     (dolist (elem special-display-regexps)
-                       (and (stringp elem)
-                            (string-match elem buffer-name)
-                            (throw 'return t))
-                       (and (consp elem)
-                            (stringp (car elem))
-                            (string-match (car elem) buffer-name)
-                            (throw 'return (cdr elem)))))))))
      ;; `substring-no-properties' is available only in Emacs 22.1 or greater.
      (substring-no-properties
       . ,(lambda (string &optional from to)
@@ -171,6 +154,25 @@ to the contents of the accessible portion of the buffer."
               (forward-line 0)
               (1+ (count-lines start (point))))))))))
 
+;; `special-display-p' is an Emacs function, not available in XEmacs.
+(defalias 'mm-special-display-p
+  (if (featurep 'emacs)
+      'special-display-p
+    (lambda (buffer-name)
+      "Returns non-nil if a buffer named BUFFER-NAME gets a special frame."
+      (and special-display-function
+          (or (and (member buffer-name special-display-buffer-names) t)
+              (cdr (assoc buffer-name special-display-buffer-names))
+              (catch 'return
+                (dolist (elem special-display-regexps)
+                  (and (stringp elem)
+                       (string-match elem buffer-name)
+                       (throw 'return t))
+                  (and (consp elem)
+                       (stringp (car elem))
+                       (string-match (car elem) buffer-name)
+                       (throw 'return (cdr elem))))))))))
+
 ;; `decode-coding-string', `encode-coding-string', `decode-coding-region'
 ;; and `encode-coding-region' are available in Emacs and XEmacs built with
 ;; the `file-coding' feature, but the XEmacs versions treat nil, that is
@@ -202,19 +204,10 @@ to the contents of the accessible portion of the buffer."
     (defalias 'mm-decode-coding-region 'decode-coding-region)
     (defalias 'mm-encode-coding-region 'encode-coding-region)))
 
-;; `string-to-multibyte' is available only in Emacs 22.1 or greater.
-(defalias 'mm-string-to-multibyte
-  (cond
-   ((featurep 'xemacs)
-    'identity)
-   ((fboundp 'string-to-multibyte)
-    'string-to-multibyte)
-   (t
-    (lambda (string)
-      "Return a multibyte string with the same individual chars as STRING."
-      (mapconcat
-       (lambda (ch) (mm-string-as-multibyte (char-to-string ch)))
-       string "")))))
+;; `string-to-multibyte' is available only in Emacs.
+(defalias 'mm-string-to-multibyte (if (featurep 'xemacs)
+                                     'identity
+                                   'string-to-multibyte))
 
 ;; `char-or-char-int-p' is an XEmacs function, not available in Emacs.
 (eval-and-compile
@@ -225,42 +218,43 @@ to the contents of the accessible portion of the buffer."
      (t 'identity))))
 
 ;; `ucs-to-char' is a function that Mule-UCS provides.
-(if (featurep 'xemacs)
-    (cond ((and (fboundp 'unicode-to-char) ;; XEmacs 21.5.
-               (subrp (symbol-function 'unicode-to-char)))
-          (if (featurep 'mule)
-              (defalias 'mm-ucs-to-char 'unicode-to-char)
+(eval-and-compile
+  (if (featurep 'xemacs)
+      (cond ((and (fboundp 'unicode-to-char) ;; XEmacs 21.5.
+                 (subrp (symbol-function 'unicode-to-char)))
+            (if (featurep 'mule)
+                (defalias 'mm-ucs-to-char 'unicode-to-char)
+              (defun mm-ucs-to-char (codepoint)
+                "Convert Unicode codepoint to character."
+                (or (unicode-to-char codepoint) ?#))))
+           ((featurep 'mule)
+            (defun mm-ucs-to-char (codepoint)
+              "Convert Unicode codepoint to character."
+              (if (fboundp 'ucs-to-char) ;; Mule-UCS is loaded.
+                  (progn
+                    (defalias 'mm-ucs-to-char
+                      (lambda (codepoint)
+                        "Convert Unicode codepoint to character."
+                        (condition-case nil
+                            (or (ucs-to-char codepoint) ?#)
+                          (error ?#))))
+                    (mm-ucs-to-char codepoint))
+                (condition-case nil
+                    (or (int-to-char codepoint) ?#)
+                  (error ?#)))))
+           (t
             (defun mm-ucs-to-char (codepoint)
               "Convert Unicode codepoint to character."
-              (or (unicode-to-char codepoint) ?#))))
-         ((featurep 'mule)
-          (defun mm-ucs-to-char (codepoint)
-            "Convert Unicode codepoint to character."
-            (if (fboundp 'ucs-to-char) ;; Mule-UCS is loaded.
-                (progn
-                  (defalias 'mm-ucs-to-char
-                    (lambda (codepoint)
-                      "Convert Unicode codepoint to character."
-                      (condition-case nil
-                          (or (ucs-to-char codepoint) ?#)
-                        (error ?#))))
-                  (mm-ucs-to-char codepoint))
               (condition-case nil
                   (or (int-to-char codepoint) ?#)
                 (error ?#)))))
-         (t
-          (defun mm-ucs-to-char (codepoint)
-            "Convert Unicode codepoint to character."
-            (condition-case nil
-                (or (int-to-char codepoint) ?#)
-              (error ?#)))))
-  (if (let ((char (make-char 'japanese-jisx0208 36 34)))
-       (eq char (decode-char 'ucs char)))
-      ;; Emacs 23.
-      (defalias 'mm-ucs-to-char 'identity)
-    (defun mm-ucs-to-char (codepoint)
-      "Convert Unicode codepoint to character."
-      (or (decode-char 'ucs codepoint) ?#))))
+    (if (let ((char (make-char 'japanese-jisx0208 36 34)))
+         (eq char (decode-char 'ucs char)))
+       ;; Emacs 23.
+       (defalias 'mm-ucs-to-char 'identity)
+      (defun mm-ucs-to-char (codepoint)
+       "Convert Unicode codepoint to character."
+       (or (decode-char 'ucs codepoint) ?#)))))
 
 ;; Fixme:  This seems always to be used to read a MIME charset, so it
 ;; should be re-named and fixed (in Emacs) to offer completion only on
@@ -272,18 +266,19 @@ to the contents of the accessible portion of the buffer."
 ;; Actually, there should be an `mm-coding-system-mime-charset'.
 (eval-and-compile
   (defalias 'mm-read-coding-system
-    (cond
-     ((fboundp 'read-coding-system)
-      (if (and (featurep 'xemacs)
-              (<= (string-to-number emacs-version) 21.1))
-         (lambda (prompt &optional default-coding-system)
-           (read-coding-system prompt))
-       'read-coding-system))
-     (t (lambda (prompt &optional default-coding-system)
-         "Prompt the user for a coding system."
-         (completing-read
-          prompt (mapcar (lambda (s) (list (symbol-name (car s))))
-                         mm-mime-mule-charset-alist)))))))
+    (if (featurep 'emacs) 'read-coding-system
+      (cond
+       ((fboundp 'read-coding-system)
+       (if (and (featurep 'xemacs)
+                (<= (string-to-number emacs-version) 21.1))
+           (lambda (prompt &optional default-coding-system)
+             (read-coding-system prompt))
+         'read-coding-system))
+       (t (lambda (prompt &optional default-coding-system)
+           "Prompt the user for a coding system."
+           (gnus-completing-read
+            prompt (mapcar (lambda (s) (symbol-name (car s)))
+                           mm-mime-mule-charset-alist))))))))
 
 (defvar mm-coding-system-list nil)
 (defun mm-get-coding-system-list ()
@@ -304,34 +299,6 @@ system object in XEmacs."
       ;; no-MULE XEmacs:
       (car (memq cs (mm-get-coding-system-list))))))
 
-(defun mm-codepage-setup (number &optional alias)
-  "Create a coding system cpNUMBER.
-The coding system is created using `codepage-setup'.  If ALIAS is
-non-nil, an alias is created and added to
-`mm-charset-synonym-alist'.  If ALIAS is a string, it's used as
-the alias.  Else windows-NUMBER is used."
-  (interactive
-   (let ((completion-ignore-case t)
-        (candidates (if (fboundp 'cp-supported-codepages)
-                        (cp-supported-codepages)
-                      ;; Removed in Emacs 23 (unicode), so signal an error:
-                      (error "`codepage-setup' not present in this Emacs version"))))
-     (list (completing-read "Setup DOS Codepage: (default 437) " candidates
-                           nil t nil nil "437"))))
-  (when alias
-    (setq alias (if (stringp alias)
-                   (intern alias)
-                 (intern (format "windows-%s" number)))))
-  (let* ((cp (intern (format "cp%s" number))))
-    (unless (mm-coding-system-p cp)
-      (if (fboundp 'codepage-setup)    ; silence compiler
-         (codepage-setup number)
-       (error "`codepage-setup' not present in this Emacs version")))
-    (when (and alias
-              ;; Don't add alias if setup of cp failed.
-              (mm-coding-system-p cp))
-      (add-to-list 'mm-charset-synonym-alist (cons alias cp)))))
-
 (defvar mm-charset-synonym-alist
   `(
     ;; Not in XEmacs, but it's not a proper MIME charset anyhow.
@@ -380,11 +347,38 @@ the alias.  Else windows-NUMBER is used."
 
 See `mm-codepage-iso-8859-list' and `mm-codepage-ibm-list'.")
 
+(defun mm-codepage-setup (number &optional alias)
+  "Create a coding system cpNUMBER.
+The coding system is created using `codepage-setup'.  If ALIAS is
+non-nil, an alias is created and added to
+`mm-charset-synonym-alist'.  If ALIAS is a string, it's used as
+the alias.  Else windows-NUMBER is used."
+  (interactive
+   (let ((completion-ignore-case t)
+        (candidates (if (fboundp 'cp-supported-codepages)
+                        (cp-supported-codepages)
+                      ;; Removed in Emacs 23 (unicode), so signal an error:
+                      (error "`codepage-setup' not present in this Emacs version"))))
+     (list (gnus-completing-read "Setup DOS Codepage" candidates
+                                 t nil nil "437"))))
+  (when alias
+    (setq alias (if (stringp alias)
+                   (intern alias)
+                 (intern (format "windows-%s" number)))))
+  (let* ((cp (intern (format "cp%s" number))))
+    (unless (mm-coding-system-p cp)
+      (if (fboundp 'codepage-setup)    ; silence compiler
+         (codepage-setup number)
+       (error "`codepage-setup' not present in this Emacs version")))
+    (when (and alias
+              ;; Don't add alias if setup of cp failed.
+              (mm-coding-system-p cp))
+      (add-to-list 'mm-charset-synonym-alist (cons alias cp)))))
+
 (defcustom mm-codepage-iso-8859-list
   (list 1250 ;; Windows-1250 is a variant of Latin-2 heavily used by Microsoft
        ;; Outlook users in Czech republic.  Use this to allow reading of
-       ;; their e-mails.  cp1250 should be defined by M-x codepage-setup
-       ;; (Emacs 21).
+       ;; their e-mails.
        '(1252 . 1) ;; Windows-1252 is a superset of iso-8859-1 (West
                    ;; Europe).  See also `gnus-article-dumbquotes-map'.
        '(1254 . 9) ;; Windows-1254 is a superset of iso-8859-9 (Turkish).
@@ -429,7 +423,7 @@ corresponding number of an iso-8859 charset."
   ;; Cf. http://thread.gmane.org/v9lkng5nwy.fsf@marauder.physik.uni-ulm.de
   "List of IBM codepage numbers.
 
-The codepage mappings slighly differ between IBM and other vendors.
+The codepage mappings slightly differ between IBM and other vendors.
 See \"ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/IBM/README.TXT\".
 
 If an element is a number corresponding to a supported windows
@@ -494,8 +488,8 @@ Unless LIST is given, `mm-codepage-ibm-list' is used."
 (defcustom mm-charset-eval-alist
   (if (featurep 'xemacs)
       nil ;; I don't know what would be useful for XEmacs.
-    '(;; Emacs 21 offers 1250 1251 1253 1257.  Emacs 22 provides autoloads for
-      ;; 1250-1258 (i.e. `mm-codepage-setup' does nothing).
+    '(;; Emacs 22 provides autoloads for 1250-1258
+      ;; (i.e. `mm-codepage-setup' does nothing).
       (windows-1250 . (mm-codepage-setup 1250 t))
       (windows-1251 . (mm-codepage-setup 1251 t))
       (windows-1253 . (mm-codepage-setup 1253 t))
@@ -555,7 +549,8 @@ is not available."
         (let ((cs (cdr (assq charset mm-charset-override-alist))))
           (and cs (mm-coding-system-p cs) cs))))
    ;; ascii
-   ((eq charset 'us-ascii)
+   ((or (eq charset 'us-ascii)
+       (string-match "ansi.x3.4" (symbol-name charset)))
     'ascii)
    ;; Check to see whether we can handle this charset.  (This depends
    ;; on there being some coding system matching each `mime-charset'
@@ -849,17 +844,17 @@ Valid elements include:
           (not lang) nil)
          ;; In XEmacs 21.5 it may be the one like "Japanese (UTF-8)".
          ((string-match "\\`Japanese" lang)
-          ;; Japanese users prefer iso-2022-jp to euc-japan or
-          ;; shift_jis, however iso-8859-1 should be used when
-          ;; there are only ASCII text and Latin-1 characters.
-          '(iso-8859-1 iso-2022-jp iso-2022-jp-2 shift_jis utf-8))))
+          ;; Japanese users prefer iso-2022-jp to others usually used
+          ;; for `buffer-file-coding-system', however iso-8859-1 should
+          ;; be used when there are only ASCII and Latin-1 characters.
+          '(iso-8859-1 iso-2022-jp utf-8))))
   "Preferred coding systems for encoding outgoing messages.
 
 More than one suitable coding system may be found for some text.
 By default, the coding system with the highest priority is used
 to encode outgoing messages (see `sort-coding-systems').  If this
 variable is set, it overrides the default priority."
-  :version "21.2"
+  :version "24.4"
   :type '(repeat (symbol :tag "Coding system"))
   :group 'mime)
 
@@ -871,6 +866,21 @@ variable is set, it overrides the default priority."
 Setting it to nil is useful on Emacsen supporting Unicode if sending
 mail with multiple parts is preferred to sending a Unicode one.")
 
+(defvar mm-extra-numeric-entities
+  (mapcar
+   (lambda (item)
+     (cons (car item) (mm-ucs-to-char (cdr item))))
+   '((#x80 . #x20AC) (#x82 . #x201A) (#x83 . #x0192) (#x84 . #x201E)
+     (#x85 . #x2026) (#x86 . #x2020) (#x87 . #x2021) (#x88 . #x02C6)
+     (#x89 . #x2030) (#x8A . #x0160) (#x8B . #x2039) (#x8C . #x0152)
+     (#x8E . #x017D) (#x91 . #x2018) (#x92 . #x2019) (#x93 . #x201C)
+     (#x94 . #x201D) (#x95 . #x2022) (#x96 . #x2013) (#x97 . #x2014)
+     (#x98 . #x02DC) (#x99 . #x2122) (#x9A . #x0161) (#x9B . #x203A)
+     (#x9C . #x0153) (#x9E . #x017E) (#x9F . #x0178)))
+  "*Alist of extra numeric entities and characters other than ISO 10646.
+This table is used for decoding extra numeric entities to characters,
+like \"&#128;\" to the euro sign, mainly in html messages.")
+
 ;;; Internal variables:
 
 ;;; Functions:
@@ -908,7 +918,7 @@ mail with multiple parts is preferred to sending a Unicode one.")
       "Set the multibyte flag of the current buffer.
 Only do this if the default value of `enable-multibyte-characters' is
 non-nil.  This is a no-op in XEmacs."
-      (set-buffer-multibyte t)))
+      (set-buffer-multibyte 'to)))
 
   (if (featurep 'xemacs)
       (defalias 'mm-disable-multibyte 'ignore)
@@ -945,7 +955,7 @@ This is a no-op in XEmacs."
 
 (defun mm-charset-after (&optional pos)
   "Return charset of a character in current buffer at position POS.
-If POS is nil, it defauls to the current point.
+If POS is nil, it defaults to the current point.
 If POS is out of range, the value is nil.
 If the charset is `composition', return the actual one."
   (let ((char (char-after pos)) charset)
@@ -966,7 +976,6 @@ If the charset is `composition', return the actual one."
   (if (eq charset 'unknown)
       (error "The message contains non-printable characters, please use attachment"))
   (if (and (fboundp 'coding-system-get) (fboundp 'get-charset-property))
-      ;; This exists in Emacs 20.
       (or
        (and (mm-preferred-coding-system charset)
            (or (coding-system-get
@@ -980,6 +989,7 @@ If the charset is `composition', return the actual one."
     ;; This is for XEmacs.
     (mm-mule-charset-to-mime-charset charset)))
 
+;; `delete-dups' is not available in XEmacs 21.4.
 (if (fboundp 'delete-dups)
     (defalias 'mm-delete-duplicates 'delete-dups)
   (defun mm-delete-duplicates (list)
@@ -1048,11 +1058,10 @@ This affects whether coding conversion should be attempted generally."
                (length (memq (coding-system-base b) priorities)))
           t))))
 
-(eval-when-compile
-  (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"))
+(declare-function latin-unity-massage-name "ext:latin-unity")
+(declare-function latin-unity-maybe-remap "ext:latin-unity")
+(declare-function latin-unity-representations-feasible-region "ext:latin-unity")
+(declare-function latin-unity-representations-present-region "ext:latin-unity")
 
 (defvar latin-unity-coding-systems)
 (defvar latin-unity-ucs-list)
@@ -1231,6 +1240,7 @@ better ways to do a similar thing.  The previous version of this macro
 bound the default value of `enable-multibyte-characters' to nil while
 evaluating FORMS but it is no longer done.  So, some programs assuming
 it if any may malfunction."
+  (declare (obsolete nil "25.1") (indent 0) (debug t))
   (if (featurep 'xemacs)
       `(progn ,@forms)
     (let ((multibyte (make-symbol "multibyte")))
@@ -1241,8 +1251,6 @@ it if any may malfunction."
             (progn ,@forms)
           (when ,multibyte
             (set-buffer-multibyte t)))))))
-(put 'mm-with-unibyte-current-buffer 'lisp-indent-function 0)
-(put 'mm-with-unibyte-current-buffer 'edebug-form-spec '(body))
 
 (defun mm-find-charset-region (b e)
   "Return a list of Emacs charsets in the region B to E."
@@ -1368,13 +1376,12 @@ If INHIBIT is non-nil, inhibit `mm-inhibit-file-name-handlers'."
 ;; It is not a MIME function, but some MIME functions use it.
 (if (and (fboundp 'make-temp-file)
         (ignore-errors
-          (let ((def (symbol-function 'make-temp-file)))
-            (and (byte-code-function-p def)
-                 (setq def (if (fboundp 'compiled-function-arglist)
-                               ;; XEmacs
-                               (eval (list 'compiled-function-arglist def))
-                             (aref def 0)))
-                 (>= (length def) 4)
+          (let ((def (if (fboundp 'compiled-function-arglist) ;; XEmacs
+                         (eval (list 'compiled-function-arglist
+                                     (symbol-function 'make-temp-file)))
+                       (require 'help-fns)
+                       (help-function-arglist 'make-temp-file t))))
+            (and (>= (length def) 4)
                  (eq (nth 3 def) 'suffix)))))
     (defalias 'mm-make-temp-file 'make-temp-file)
   ;; Stolen (and modified for XEmacs) from Emacs 22.
@@ -1497,8 +1504,8 @@ To make this function work with XEmacs, the APEL package is required."
                      (fboundp 'coding-system-to-mime-charset)))
             (coding-system-to-mime-charset coding-system)))))
 
-(eval-when-compile
-  (require 'jka-compr))
+(defvar jka-compr-acceptable-retval-list)
+(declare-function jka-compr-make-temp-name "jka-compr" (&optional local))
 
 (defun mm-decompress-buffer (filename &optional inplace force)
   "Decompress buffer's contents, depending on jka-compr.
@@ -1539,14 +1546,13 @@ decompressed data.  The buffer's multibyteness must be turned off."
                                       prog t (list t err-file) nil args)
                                jka-compr-acceptable-retval-list)
                    (erase-buffer)
-                   (insert (mapconcat
-                            'identity
-                            (delete "" (split-string
-                                        (prog2
-                                            (insert-file-contents err-file)
-                                            (buffer-string)
-                                          (erase-buffer))))
-                            " ")
+                   (insert (mapconcat 'identity
+                                      (split-string
+                                       (prog2
+                                           (insert-file-contents err-file)
+                                           (buffer-string)
+                                         (erase-buffer)) t)
+                                      " ")
                            "\n")
                    (setq err-msg
                          (format "Error while executing \"%s %s < %s\""
@@ -1582,7 +1588,7 @@ gzip, bzip2, etc. are allowed."
   (unless filename
     (setq filename buffer-file-name))
   (save-excursion
-    (let ((decomp (unless ;; No worth to examine charset of tar files.
+    (let ((decomp (unless ;; Not worth it to examine charset of tar files.
                      (and filename
                           (string-match
                            "\\.\\(?:tar\\.[^.]+\\|tbz\\|tgz\\)\\'"
@@ -1594,7 +1600,7 @@ gzip, bzip2, etc. are allowed."
        (insert decomp)
        (setq filename (file-name-sans-extension filename)))
       (goto-char (point-min))
-      (prog1
+      (unwind-protect
          (cond
           ((boundp 'set-auto-coding-function) ;; Emacs
            (if filename