Fix my last change.
[gnus] / lisp / mm-util.el
index 998724a..8b9b8c8 100644 (file)
@@ -1,5 +1,5 @@
 ;;; mm-util.el --- Utility functions for MIME things
-;; Copyright (C) 1998-2000 Free Software Foundation, Inc.
+;; Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;;     MORIOKA Tomohiko <morioka@jaist.ac.jp>
     (iso-8859-3 latin-iso8859-3)
     (iso-8859-4 latin-iso8859-4)
     (iso-8859-5 cyrillic-iso8859-5)
-    (koi8-r cyrillic-iso8859-5)
+    ;; Non-mule (X)Emacs uses the last mule-charset for 8bit characters.
+    ;; The fake mule-charset, gnus-koi8-r, tells Gnus that the default 
+    ;; charset is koi8-r, not iso-8859-5.
+    (koi8-r cyrillic-iso8859-5 gnus-koi8-r)
     (iso-8859-6 arabic-iso8859-6)
     (iso-8859-7 greek-iso8859-7)
     (iso-8859-8 hebrew-iso8859-8)
          "Prompt the user for a coding system."
          (completing-read
           prompt (mapcar (lambda (s) (list (symbol-name (car s))))
-                         mm-mime-mule-charset-alist)))))))
+                         mm-mime-mule-charset-alist))))
+     (read-charset
+      . (lambda (prompt)
+         "Return a charset."
+         (intern
+          (completing-read
+           prompt
+           (mapcar (lambda (e) (list (symbol-name (car e))))
+                   mm-mime-mule-charset-alist)
+           nil t)))))))
 
 (eval-and-compile
   (defalias 'mm-char-or-char-int-p
@@ -188,17 +200,20 @@ used as the line break code type of the coding system."
    (t
     nil)))
 
-(defun mm-replace-chars-in-string (string from to)
-  "Replace characters in STRING from FROM to TO."
-  (let ((string (substring string 0))  ;Copy string.
-       (len (length string))
-       (idx 0))
-    ;; Replace all occurrences of FROM with TO.
-    (while (< idx len)
-      (when (= (aref string idx) from)
-       (aset string idx to))
-      (setq idx (1+ idx)))
-    string))
+(if (fboundp 'subst-char-in-string)
+    (defsubst mm-replace-chars-in-string (string from to)
+      (subst-char-in-string from to string))
+  (defun mm-replace-chars-in-string (string from to)
+    "Replace characters in STRING from FROM to TO."
+    (let ((string (substring string 0))        ;Copy string.
+         (len (length string))
+         (idx 0))
+      ;; Replace all occurrences of FROM with TO.
+      (while (< idx len)
+       (when (= (aref string idx) from)
+         (aset string idx to))
+       (setq idx (1+ idx)))
+      string)))
 
 (defsubst mm-enable-multibyte ()
   "Enable multibyte in the current buffer."
@@ -212,6 +227,22 @@ used as the line break code type of the coding system."
   (when (fboundp 'set-buffer-multibyte)
     (set-buffer-multibyte nil)))
 
+(defsubst mm-enable-multibyte-mule4 ()
+  "Enable multibyte in the current buffer.
+Only used in Emacs Mule 4."
+  (when (and (fboundp 'set-buffer-multibyte)
+             (boundp 'enable-multibyte-characters)
+            (default-value 'enable-multibyte-characters)
+            (not (charsetp 'eight-bit-control)))
+    (set-buffer-multibyte t)))
+
+(defsubst mm-disable-multibyte-mule4 ()
+  "Disable multibyte in the current buffer.
+Only used in Emacs Mule 4."
+  (when (and (fboundp 'set-buffer-multibyte)
+            (not (charsetp 'eight-bit-control)))
+    (set-buffer-multibyte nil)))
+
 (defun mm-preferred-coding-system (charset)
   ;; A typo in some Emacs versions.
   (or (get-charset-property charset 'prefered-coding-system)
@@ -222,30 +253,33 @@ used as the line break code type of the coding system."
 If POS is nil, it defauls to the current point.
 If POS is out of range, the value is nil.
 If the charset is `composition', return the actual one."
-  (let ((charset (cond 
-                 ((fboundp 'charset-after)
-                  (charset-after pos))
-                 ((fboundp 'char-charset)
-                  (char-charset (char-after pos)))
-                 ((< (mm-char-int (char-after pos)) 128)
-                  'ascii)
-                 (mail-parse-mule-charset ;; cached mule-charset
-                  mail-parse-mule-charset)
-                 ((boundp 'current-language-environment)
-                  (let ((entry (assoc current-language-environment 
-                                      language-info-alist)))
-                    (setq mail-parse-mule-charset
-                          (or (car (last (assq 'charset entry)))
-                              'latin-iso8859-1))))
-                 (t                       ;; figure out the charset
-                  (setq mail-parse-mule-charset
-                        (or (car (last (assq mail-parse-charset
-                                             mm-mime-mule-charset-alist)))
-                            'latin-iso8859-1))))))
-    (if (eq charset 'composition)
-       (let ((p (or pos (point))))
-         (cadr (find-charset-region p (1+ p))))
-      charset)))
+  (let ((char (char-after pos)) charset)
+    (if (< (mm-char-int char) 128)
+       (setq charset 'ascii)
+      ;; charset-after is fake in some Emacsen.
+      (setq charset (and (fboundp 'char-charset) (char-charset char)))
+      (if (eq charset 'composition)
+         (let ((p (or pos (point))))
+           (cadr (find-charset-region p (1+ p))))
+       (if (and charset (not (memq charset '(ascii eight-bit-control
+                                                   eight-bit-graphic))))
+           charset
+         (or
+          mail-parse-mule-charset ;; cached mule-charset
+          (progn
+            (setq mail-parse-mule-charset
+                  (and (boundp 'current-language-environment)
+                     (car (last 
+                           (assq 'charset 
+                                 (assoc current-language-environment 
+                                        language-info-alist))))))
+            (if (or (not mail-parse-mule-charset)
+                    (eq mail-parse-mule-charset 'ascii))
+                (setq mail-parse-mule-charset
+                      (or (car (last (assq mail-parse-charset
+                                           mm-mime-mule-charset-alist)))
+                          'latin-iso8859-1)))
+            mail-parse-mule-charset)))))))
 
 (defun mm-mime-charset (charset)
   "Return the MIME charset corresponding to the MULE CHARSET."
@@ -287,16 +321,16 @@ If the charset is `composition', return the actual one."
 
 (defsubst mm-multibyte-p ()
   "Say whether multibyte is enabled."
-  (or (string-match "XEmacs\\|Lucid" emacs-version)
-      (and (boundp 'enable-multibyte-characters)
-          enable-multibyte-characters)))
+  (if (boundp 'enable-multibyte-characters)
+      enable-multibyte-characters
+    (featurep 'mule)))
 
 (defmacro mm-with-unibyte-buffer (&rest forms)
   "Create a temporary buffer, and evaluate FORMS there like `progn'.
 See also `with-temp-file' and `with-output-to-string'."
   (let ((temp-buffer (make-symbol "temp-buffer"))
        (multibyte (make-symbol "multibyte")))
-    `(if (or (string-match "XEmacs\\|Lucid" emacs-version)
+    `(if (or (featurep 'xemacs)
             (not (boundp 'enable-multibyte-characters)))
         (with-temp-buffer ,@forms)
        (let ((,multibyte (default-value 'enable-multibyte-characters))
@@ -321,8 +355,9 @@ See also `with-temp-file' and `with-output-to-string'."
 (defmacro mm-with-unibyte-current-buffer (&rest forms)
   "Evaluate FORMS there like `progn' in current buffer."
   (let ((multibyte (make-symbol "multibyte")))
-    `(if (or (string-match "XEmacs\\|Lucid" emacs-version)
-            (not (fboundp 'set-buffer-multibyte)))
+    `(if (or (featurep 'xemacs)
+            (not (fboundp 'set-buffer-multibyte))
+            (charsetp 'eight-bit-control)) ;; For Emacs Mule 4 only.
         (progn
           ,@forms)
        (let ((,multibyte (default-value 'enable-multibyte-characters)))
@@ -331,7 +366,9 @@ See also `with-temp-file' and `with-output-to-string'."
                   (coding-system-for-read mm-binary-coding-system)
                   (coding-system-for-write mm-binary-coding-system))
               (set-buffer-multibyte nil)
+              (setq-default enable-multibyte-characters nil)
               ,@forms)
+          (setq-default enable-multibyte-characters ,multibyte)
           (set-buffer-multibyte ,multibyte))))))
 (put 'mm-with-unibyte-current-buffer 'lisp-indent-function 0)
 (put 'mm-with-unibyte-current-buffer 'edebug-form-spec '(body))
@@ -339,7 +376,7 @@ See also `with-temp-file' and `with-output-to-string'."
 (defmacro mm-with-unibyte (&rest forms)
   "Set default `enable-multibyte-characters' to `nil', eval the FORMS."
   (let ((multibyte (make-symbol "multibyte")))
-    `(if (or (string-match "XEmacs\\|Lucid" emacs-version)
+    `(if (or (featurep 'xemacs)
             (not (boundp 'enable-multibyte-characters)))
         (progn ,@forms)
        (let ((,multibyte (default-value 'enable-multibyte-characters)))
@@ -358,7 +395,8 @@ See also `with-temp-file' and `with-output-to-string'."
         (fboundp 'find-charset-region))
     ;; Remove composition since the base charsets have been included.
     (delq 'composition (find-charset-region b e)))
-   ((not (boundp 'current-language-environment))
+   (t
+    ;; We are in a unibyte buffer or XEmacs non-mule, so we futz around a bit.
     (save-excursion
       (save-restriction
        (narrow-to-region b e)
@@ -366,46 +404,33 @@ See also `with-temp-file' and `with-output-to-string'."
        (skip-chars-forward "\0-\177")
        (if (eobp)
            '(ascii)
-         (delq nil (list 'ascii 
-                         (or (car (last (assq mail-parse-charset
-                                              mm-mime-mule-charset-alist)))
-                             'latin-iso8859-1)))))))
-   (t
-    ;; We are in a unibyte buffer, so we futz around a bit.
-    (save-excursion
-      (save-restriction
-       (narrow-to-region b e)
-       (goto-char (point-min))
-       (let ((entry (assoc current-language-environment 
-                           language-info-alist)))
-         (skip-chars-forward "\0-\177")
-         (if (eobp)
-             '(ascii)
-           (delq nil (list 'ascii 
-                           (or (car (last (assq 'charset entry)))
-                               'latin-iso8859-1))))))))))
-
-(defun mm-read-charset (prompt)
-  "Return a charset."
-  (intern
-   (completing-read
-    prompt
-    (mapcar (lambda (e) (list (symbol-name (car e))))
-           mm-mime-mule-charset-alist)
-    nil t)))
-
-(defun mm-quote-arg (arg)
-  "Return a version of ARG that is safe to evaluate in a shell."
-  (let ((pos 0) new-pos accum)
-    ;; *** bug: we don't handle newline characters properly
-    (while (setq new-pos (string-match "[]*[;!'`\"$\\& \t{} |()<>]" arg pos))
-      (push (substring arg pos new-pos) accum)
-      (push "\\" accum)
-      (push (list (aref arg new-pos)) accum)
-      (setq pos (1+ new-pos)))
-    (if (= pos 0)
-        arg
-      (apply 'concat (nconc (nreverse accum) (list (substring arg pos)))))))
+         (let (charset)
+           (setq charset
+                 (and (boundp 'current-language-environment)
+                      (car (last (assq 'charset 
+                                       (assoc current-language-environment 
+                                              language-info-alist))))))
+           (if (eq charset 'ascii) (setq charset nil))
+           (or charset
+               (setq charset
+                     (car (last (assq mail-parse-charset
+                                      mm-mime-mule-charset-alist)))))
+           (list 'ascii (or charset 'latin-iso8859-1)))))))))
+
+(if (fboundp 'shell-quote-argument)
+    (defalias 'mm-quote-arg 'shell-quote-argument)
+  (defun mm-quote-arg (arg)
+    "Return a version of ARG that is safe to evaluate in a shell."
+    (let ((pos 0) new-pos accum)
+      ;; *** bug: we don't handle newline characters properly
+      (while (setq new-pos (string-match "[]*[;!'`\"$\\& \t{} |()<>]" arg pos))
+       (push (substring arg pos new-pos) accum)
+       (push "\\" accum)
+       (push (list (aref arg new-pos)) accum)
+       (setq pos (1+ new-pos)))
+      (if (= pos 0)
+         arg
+       (apply 'concat (nconc (nreverse accum) (list (substring arg pos))))))))
 
 (defun mm-auto-mode-alist ()
   "Return an `auto-mode-alist' with only the .gz (etc) thingies."