]> code.delx.au - gnu-emacs/blobdiff - lisp/gnus/mm-util.el
Update copyright notices of all files in the gnus directory.
[gnu-emacs] / lisp / gnus / mm-util.el
index 3be6444f18f2e73b52caa6aa5d09f4b0fc69022f..c8f59ec263ff2f42fbd551497ae0e35f32f8f22c 100644 (file)
@@ -1,6 +1,7 @@
 ;;; mm-util.el --- Utility functions for Mule and low level things
-;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-;;   Free Software Foundation, Inc.
+
+;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+;;   2005, 2006 Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;;     MORIOKA Tomohiko <morioka@jaist.ac.jp>
@@ -18,8 +19,8 @@
 
 ;; 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.
 
 ;;; Commentary:
 
                    mm-mime-mule-charset-alist)
            nil t))))
      (subst-char-in-string
-      . (lambda (from to string) ;; stolen (and renamed) from nnheader.el
-         "Replace characters in STRING from FROM to TO."
-         (let ((string (substring string 0)) ;Copy string.
+      . (lambda (from to string &optional inplace)
+         ;; stolen (and renamed) from nnheader.el
+         "Replace characters in STRING from FROM to TO.
+         Unless optional argument INPLACE is non-nil, return a new string."
+         (let ((string (if inplace string (copy-sequence string)))
                (len (length string))
                (idx 0))
            ;; Replace all occurrences of FROM with TO.
            string)))
      (string-as-unibyte . identity)
      (string-make-unibyte . identity)
+     ;; string-as-multibyte often doesn't really do what you think it does.
+     ;; Example:
+     ;;    (aref (string-as-multibyte "\201") 0) -> 129 (aka ?\201)
+     ;;    (aref (string-as-multibyte "\300") 0) -> 192 (aka ?\300)
+     ;;    (aref (string-as-multibyte "\300\201") 0) -> 192 (aka ?\300)
+     ;;    (aref (string-as-multibyte "\300\201") 1) -> 129 (aka ?\201)
+     ;; but
+     ;;    (aref (string-as-multibyte "\201\300") 0) -> 2240
+     ;;    (aref (string-as-multibyte "\201\300") 1) -> <error>
+     ;; Better use string-to-multibyte or encode-coding-string.
+     ;; If you really need string-as-multibyte somewhere it's usually
+     ;; because you're using the internal emacs-mule representation (maybe
+     ;; because you're using string-as-unibyte somewhere), which is
+     ;; generally a problem in itself.
+     ;; Here is an approximate equivalence table to help think about it:
+     ;; (string-as-multibyte s)   ~= (decode-coding-string s 'emacs-mule)
+     ;; (string-to-multibyte s)   ~= (decode-coding-string s 'binary)
+     ;; (string-make-multibyte s) ~= (decode-coding-string s locale-coding-system)
      (string-as-multibyte . identity)
+     (string-to-multibyte
+      . (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 "")))
      (multibyte-string-p . ignore)
      ;; It is not a MIME function, but some MIME functions use it.
      (make-temp-file . (lambda (prefix &optional dir-flag)
@@ -153,7 +180,7 @@ In XEmacs, also return non-nil if CS is a coding system object.
 If CS is available, return CS itself in Emacs, and return a coding
 system object in XEmacs."
   (if (fboundp 'find-coding-system)
-      (find-coding-system cs)
+      (and cs (find-coding-system cs))
     (if (fboundp 'coding-system-p)
        (when (coding-system-p cs)
          cs)
@@ -541,14 +568,21 @@ If the charset is `composition', return the actual one."
     ;; This is for XEmacs.
     (mm-mule-charset-to-mime-charset charset)))
 
-(defun mm-delete-duplicates (list)
-  "Simple substitute for CL `delete-duplicates', testing with `equal'."
-  (let (result head)
-    (while list
-      (setq head (car list))
-      (setq list (delete head list))
-      (setq result (cons head result)))
-    (nreverse result)))
+(if (fboundp 'delete-dups)
+    (defalias 'mm-delete-duplicates 'delete-dups)
+  (defun mm-delete-duplicates (list)
+    "Destructively remove `equal' duplicates from LIST.
+Store the result in LIST and return it.  LIST must be a proper list.
+Of several `equal' occurrences of an element in LIST, the first
+one is kept.
+
+This is a compatibility function for Emacsen without `delete-dups'."
+    ;; Code from `subr.el' in Emacs 22:
+    (let ((tail list))
+      (while tail
+       (setcdr tail (delete (car tail) (cdr tail)))
+       (setq tail (cdr tail))))
+    list))
 
 ;; Fixme:  This is used in places when it should be testing the
 ;; default multibyteness.  See mm-default-multibyte-p.
@@ -740,6 +774,17 @@ charset, and a longer list means no appropriate charset."
     (if (and (memq 'iso-2022-jp-2 charsets)
             (memq 'iso-2022-jp-2 hack-charsets))
        (setq charsets (delq 'iso-2022-jp charsets)))
+    ;; Attempt to reduce the number of charsets if utf-8 is available.
+    (if (and (featurep 'xemacs)
+            (> (length charsets) 1)
+            (mm-coding-system-p 'utf-8))
+       (let ((mm-coding-system-priorities
+              (cons 'utf-8 mm-coding-system-priorities)))
+         (setq charsets
+               (mm-delete-duplicates
+                (mapcar 'mm-mime-charset
+                        (delq 'ascii
+                              (mm-find-charset-region b e)))))))
     charsets))
 
 (defmacro mm-with-unibyte-buffer (&rest forms)
@@ -863,22 +908,28 @@ to advanced Emacs features, such as file-name-handlers, format decoding,
 `find-file-hooks', etc.
 If INHIBIT is non-nil, inhibit `mm-inhibit-file-name-handlers'.
   This function ensures that none of these modifications will take place."
-  (let ((format-alist nil)
-       (auto-mode-alist (if inhibit nil (mm-auto-mode-alist)))
-       (default-major-mode 'fundamental-mode)
-       (enable-local-variables nil)
-       (after-insert-file-functions nil)
-       (enable-local-eval nil)
-       (find-file-hooks nil)
-       (inhibit-file-name-operation (if inhibit
-                                        'insert-file-contents
-                                      inhibit-file-name-operation))
-       (inhibit-file-name-handlers
-        (if inhibit
-            (append mm-inhibit-file-name-handlers
-                    inhibit-file-name-handlers)
-          inhibit-file-name-handlers)))
-    (insert-file-contents filename visit beg end replace)))
+  (let* ((format-alist nil)
+        (auto-mode-alist (if inhibit nil (mm-auto-mode-alist)))
+        (default-major-mode 'fundamental-mode)
+        (enable-local-variables nil)
+        (after-insert-file-functions nil)
+        (enable-local-eval nil)
+        (inhibit-file-name-operation (if inhibit
+                                         'insert-file-contents
+                                       inhibit-file-name-operation))
+        (inhibit-file-name-handlers
+         (if inhibit
+             (append mm-inhibit-file-name-handlers
+                     inhibit-file-name-handlers)
+           inhibit-file-name-handlers))
+        (ffh (if (boundp 'find-file-hook)
+                 'find-file-hook
+               'find-file-hooks))
+        (val (symbol-value ffh)))
+    (set ffh nil)
+    (unwind-protect
+       (insert-file-contents filename visit beg end replace)
+      (set ffh val))))
 
 (defun mm-append-to-file (start end filename &optional codesys inhibit)
   "Append the contents of the region to the end of file FILENAME.
@@ -936,7 +987,7 @@ If INHIBIT is non-nil, inhibit `mm-inhibit-file-name-handlers'."
     (defun mm-detect-coding-region (start end)
       "Like `detect-coding-region' except returning the best one."
       (let ((coding-systems
-            (detect-coding-region (point) (point-max))))
+            (detect-coding-region start end)))
        (or (car-safe coding-systems)
            coding-systems)))
   (defun mm-detect-coding-region (start end)
@@ -960,5 +1011,5 @@ If INHIBIT is non-nil, inhibit `mm-inhibit-file-name-handlers'."
 
 (provide 'mm-util)
 
-;;; arch-tag: 94dc5388-825d-4fd1-bfa5-2100aa351238
+;; arch-tag: 94dc5388-825d-4fd1-bfa5-2100aa351238
 ;;; mm-util.el ends here