Synch with `t-gnus-6_14'.
[elisp/gnus.git-] / lisp / uudecode.el
index 2be3e6a..fa55b88 100644 (file)
@@ -1,79 +1,92 @@
 ;;; uudecode.el -- elisp native uudecode
-;; Copyright (c) 1998 by Shenghuo Zhu <zsh@cs.rochester.edu>
+;; Copyright (c) 1998,99 Free Software Foundation, Inc.
 
 ;; Author: Shenghuo Zhu <zsh@cs.rochester.edu>
-;; $Revision: 1.1 $
-;; Keywords: uudecode
+;; Keywords: uudecode news
+
+;; This file is a part of GNU Emacs.
 
-;; This file is part of GNU Emacs.
-;;
 ;; 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)
 ;; any later version.
-;;
+
 ;; GNU Emacs is distributed in the hope that it will be useful,
 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 ;; GNU General Public License for more details.
-;;
+
 ;; 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.
 
-;; Commentary:
+;;; Commentary:
+
 ;;     Lots of codes are stolen from mm-decode.el, gnus-uu.el and
 ;;     base64.el
 
 ;;; Code:
 
 (if (not (fboundp 'char-int))
-    (fset 'char-int 'identity))
+    (defalias 'char-int 'identity))
 
-(defvar uu-decoder-program "uudecode"
+(defcustom uudecode-decoder-program "uudecode"
   "*Non-nil value should be a string that names a uu decoder.
 The program should expect to read uu data on its standard
-input and write the converted data to its standard output.")
+input and write the converted data to its standard output."
+  :type 'string
+  :group 'gnus-extract)
 
-(defvar uu-decoder-switches nil
-  "*List of command line flags passed to the command named by uu-decoder-program.")
+(defcustom uudecode-decoder-switches nil
+  "*List of command line flags passed to `uudecode-decoder-program'."
+  :group 'gnus-extract
+  :type '(repeat string))
 
-(defvar uu-alphabet "\040-\140")
+(defconst uudecode-alphabet "\040-\140")
 
-(defvar uu-begin-string "^begin[ \t]+[0-7][0-7][0-7][ \t]+\\(.*\\)$")
-(defvar uu-end-string "^end[ \t]*$")
+(defconst uudecode-begin-line "^begin[ \t]+[0-7][0-7][0-7][ \t]+\\(.*\\)$")
+(defconst uudecode-end-line "^end[ \t]*$")
 
-(defvar uu-body-line
+(defconst uudecode-body-line
   (let ((i 61) (str "^M"))
     (while (> (setq i (1- i)) 0)
       (setq str (concat str "[^a-z]")))
     (concat str ".?$")))
 
-(defvar uu-temporary-file-directory "/tmp/")
+(defvar uudecode-temporary-file-directory
+  (cond ((fboundp 'temp-directory) (temp-directory))
+       ((boundp 'temporary-file-directory) temporary-file-directory)
+       ("/tmp")))
 
-(defun uu-decode-region-external (start end &optional file-name)
-  "Decode uuencoded files using an external program."
+;;;###autoload
+(defun uudecode-decode-region-external (start end &optional file-name)
+  "Uudecode region between START and END with external decoder.
+
+If FILE-NAME is non-nil, save the result to FILE-NAME."
   (interactive "r\nP")
-  (let ((cbuf (current-buffer)) tempfile firstline work-buffer status) 
+  (let ((cbuf (current-buffer)) tempfile firstline work-buffer status)
     (save-excursion
       (goto-char start)
-      (when (re-search-forward uu-begin-string nil t)
+      (when (re-search-forward uudecode-begin-line nil t)
        (forward-line 1)
        (setq firstline (point))
        (cond ((null file-name))
              ((stringp file-name))
-             (t 
-              (setq file-name (read-file-name "File to Name:" 
-                                              nil nil nil 
+             (t
+              (setq file-name (read-file-name "File to Name:"
+                                              nil nil nil
                                               (match-string 1)))))
-       (setq tempfile (expand-file-name
-                       (or file-name (concat uu-temporary-file-directory
-                                             (make-temp-name "uu")))))
+       (setq tempfile (if file-name
+                          (expand-file-name file-name)
+                        (make-temp-name
+                         ;; /tmp/uu...
+                         (expand-file-name
+                          "uu" uudecode-temporary-file-directory))))
        (let ((cdir default-directory) default-process-coding-system)
          (unwind-protect
              (progn
-               (set-buffer (setq work-buffer 
+               (set-buffer (setq work-buffer
                                  (generate-new-buffer " *uudecode-work*")))
                (buffer-disable-undo work-buffer)
                (insert "begin 600 " (file-name-nondirectory tempfile) "\n")
@@ -82,11 +95,11 @@ input and write the converted data to its standard output.")
                (apply 'call-process-region
                       (point-min)
                       (point-max)
-                      uu-decoder-program 
+                      uudecode-decoder-program
                       nil
                       nil
                       nil
-                      uu-decoder-switches))
+                      uudecode-decoder-switches))
            (cd cdir) (set-buffer cbuf)))
        (if (file-exists-p tempfile)
            (unless file-name
@@ -96,27 +109,21 @@ input and write the converted data to its standard output.")
                (insert-file-contents-literally tempfile)))
          (message "Can not uudecode")))
       (and work-buffer (kill-buffer work-buffer))
-      (condition-case ()
-         (or file-name (delete-file tempfile))
-       (error)))))
-
-(defun uu-insert-char (char &optional count ignored buffer)
-  (condition-case nil
-      (progn
-       (insert-char char count ignored buffer)
-       (fset 'uu-insert-char 'insert-char))
-    (wrong-number-of-arguments
-     (fset 'uu-insert-char 'uu-xemacs-insert-char)
-     (uu-insert-char char count ignored buffer))))
-
-(defun uu-xemacs-insert-char (char &optional count ignored buffer)
-  (if (or (null buffer) (eq buffer (current-buffer)))
-      (insert-char char count)
-    (save-excursion
-      (set-buffer buffer)
-      (insert-char char count))))
+      (ignore-errors (or file-name (delete-file tempfile))))))
+
+(if (featurep 'xemacs)
+    (defalias 'uudecode-insert-char 'insert-char)
+  (defun uudecode-insert-char (char &optional count ignored buffer)
+    (if (or (null buffer) (eq buffer (current-buffer)))
+       (insert-char char count)
+      (with-current-buffer buffer
+       (insert-char char count)))))
+
+;;;###autoload
 
-(defun uu-decode-region (start end &optional file-name)
+(defun uudecode-decode-region (start end &optional file-name)
+  "Uudecode region between START and END.
+If FILE-NAME is non-nil, save the result to FILE-NAME."
   (interactive "r\nP")
   (let ((work-buffer nil)
        (done nil)
@@ -124,17 +131,17 @@ input and write the converted data to its standard output.")
        (remain 0)
        (bits 0)
        (lim 0) inputpos
-       (non-data-chars (concat "^" uu-alphabet)))
+       (non-data-chars (concat "^" uudecode-alphabet)))
     (unwind-protect
        (save-excursion
          (goto-char start)
-         (when (re-search-forward uu-begin-string nil t)
+         (when (re-search-forward uudecode-begin-line nil t)
            (cond ((null file-name))
                  ((stringp file-name))
-                 (t 
-                  (setq file-name (expand-file-name 
-                                   (read-file-name "File to Name:" 
-                                                   nil nil nil 
+                 (t
+                  (setq file-name (expand-file-name
+                                   (read-file-name "File to Name:"
+                                                   nil nil nil
                                                    (match-string 1))))))
            (setq work-buffer (generate-new-buffer " *uudecode-work*"))
            (buffer-disable-undo work-buffer)
@@ -144,44 +151,45 @@ input and write the converted data to its standard output.")
              (setq inputpos (point))
              (setq remain 0 bits 0 counter 0)
              (cond
-              ((> (skip-chars-forward uu-alphabet end) 0)
+              ((> (skip-chars-forward uudecode-alphabet end) 0)
                (setq lim (point))
-               (setq remain 
+               (setq remain
                      (logand (- (char-int (char-after inputpos)) 32) 63))
                (setq inputpos (1+ inputpos))
                (if (= remain 0) (setq done t))
                (while (and (< inputpos lim) (> remain 0))
-                 (setq bits (+ bits 
-                               (logand 
-                                (- 
+                 (setq bits (+ bits
+                               (logand
+                                (-
                                  (char-int (char-after inputpos)) 32) 63)))
                  (if (/= counter 0) (setq remain (1- remain)))
                  (setq counter (1+ counter)
                        inputpos (1+ inputpos))
                  (cond ((= counter 4)
-                        (uu-insert-char (lsh bits -16) 1 nil work-buffer)
-                        (uu-insert-char (logand (lsh bits -8) 255) 1 nil
-                                        work-buffer)
-                        (uu-insert-char (logand bits 255) 1 nil
-                                        work-buffer)
+                        (uudecode-insert-char
+                         (lsh bits -16) 1 nil work-buffer)
+                        (uudecode-insert-char
+                         (logand (lsh bits -8) 255) 1 nil work-buffer)
+                        (uudecode-insert-char (logand bits 255) 1 nil
+                                              work-buffer)
                         (setq bits 0 counter 0))
                        (t (setq bits (lsh bits 6)))))))
              (cond
-                (done)
-                ((> 0 remain)
-                 (error "uucode line ends unexpectly")
-                 (setq done t))
-                ((and (= (point) end) (not done))
-                 (error "uucode ends unexpectly")
-                 (setq done t))
-                ((= counter 3)
-                 (uu-insert-char (logand (lsh bits -16) 255) 1 nil 
-                                 work-buffer)
-                 (uu-insert-char (logand (lsh bits -8) 255) 1 nil
-                                 work-buffer))
-                ((= counter 2)
-                 (uu-insert-char (logand (lsh bits -10) 255) 1 nil 
-                                 work-buffer)))
+              (done)
+              ((> 0 remain)
+               (error "uucode line ends unexpectly")
+               (setq done t))
+              ((and (= (point) end) (not done))
+               ;;(error "uucode ends unexpectly")
+               (setq done t))
+              ((= counter 3)
+               (uudecode-insert-char (logand (lsh bits -16) 255) 1 nil
+                                     work-buffer)
+               (uudecode-insert-char (logand (lsh bits -8) 255) 1 nil
+                                     work-buffer))
+              ((= counter 2)
+               (uudecode-insert-char (logand (lsh bits -10) 255) 1 nil
+                                     work-buffer)))
              (skip-chars-forward non-data-chars end))
            (if file-name
                (save-excursion