Gnus -- minor build / warning fixes [OK For Upstream]
[gnus] / lisp / binhex.el
index b2f3bb4..1072f27 100644 (file)
@@ -1,19 +1,16 @@
-;;; binhex.el -- elisp native binhex decode
-;; Copyright (c) 1998 by Shenghuo Zhu <zsh@cs.rochester.edu>
+;;; binhex.el --- decode BinHex-encoded text
+
+;; Copyright (C) 1998-2016 Free Software Foundation, Inc.
 
 ;; Author: Shenghuo Zhu <zsh@cs.rochester.edu>
-;; Create Date: Oct 1, 1998
-;; $Revision: 5.4 $
-;; Time-stamp: <Tue Oct  6 23:48:38 EDT 1998 zsh>
-;; Keywords: binhex
+;; Keywords: binhex news
 
-;; This file is not part of GNU Emacs, but the same permissions
-;; apply.
+;; This file is part of GNU Emacs.
 
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; 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.
+;; the Free Software Foundation, either version 3 of the License, 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
 ;; 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.
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
 ;;; Commentary:
 
+;; BinHex is a binary-to-text encoding scheme similar to uuencode.
+;; The command `binhex-decode-region' decodes BinHex-encoded text, via
+;; the external program "hexbin" if that is available, or an Emacs
+;; Lisp implementation if not.
+
 ;;; Code:
 
-(if (not (fboundp 'char-int))
-    (fset 'char-int 'identity))
+(eval-when-compile (require 'cl))
+
+(eval-and-compile
+  (defalias 'binhex-char-int
+    (if (fboundp 'char-int)
+       'char-int
+      'identity)))
 
-(defvar binhex-decoder-program "hexbin"
-  "*Non-nil value should be a string that names a uu decoder.
+(defgroup binhex nil
+  "Decoding of BinHex (binary-to-hexadecimal) data."
+  :group 'mail
+  :group 'news)
+
+(defcustom binhex-decoder-program "hexbin"
+  "Non-nil value should be a string that names a binhex decoder.
 The program should expect to read binhex 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 'binhex)
+
+(defcustom binhex-decoder-switches '("-d")
+  "List of command line flags passed to the command `binhex-decoder-program'."
+  :group 'binhex
+  :type '(repeat string))
 
-(defvar binhex-decoder-switches '("-d")
-  "*List of command line flags passed to the command named by binhex-decoder-program.")
+(defcustom binhex-use-external
+  (executable-find binhex-decoder-program)
+  "Use external binhex program."
+  :version "22.1"
+  :group 'binhex
+  :type 'boolean)
 
 (defconst binhex-alphabet-decoding-alist
   '(( ?\! . 0) ( ?\" . 1) ( ?\# . 2) ( ?\$ . 3) ( ?\% . 4) ( ?\& . 5)
@@ -58,23 +79,27 @@ input and write the converted data to its standard output.")
 
 ;;;###autoload
 (defconst binhex-begin-line
-  "^:...............................................................$")
+  "^:...............................................................$"
+  "Regular expression matching the start of a BinHex encoded region.")
 (defconst binhex-body-line
   "^[^:]...............................................................$")
-(defconst binhex-end-line ":$")
+(defconst binhex-end-line ":$")                ; unused
 
 (defvar binhex-temporary-file-directory
   (cond ((fboundp 'temp-directory) (temp-directory))
        ((boundp 'temporary-file-directory) temporary-file-directory)
        ("/tmp/")))
 
-(if (string-match "XEmacs" emacs-version)
-    (defalias 'binhex-insert-char 'insert-char)
-  (defun binhex-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)))))
+(eval-and-compile
+  (defalias 'binhex-insert-char
+    (if (featurep 'xemacs)
+       'insert-char
+      (lambda (char &optional count ignored buffer)
+       "Insert COUNT copies of CHARACTER into BUFFER."
+       (if (or (null buffer) (eq buffer (current-buffer)))
+           (insert-char char count)
+         (with-current-buffer buffer
+           (insert-char char count)))))))
 
 (defvar binhex-crc-table
   [0  4129  8258  12387  16516  20645  24774  28903
@@ -133,14 +158,14 @@ input and write the converted data to its standard output.")
 (defun binhex-string-big-endian (string)
   (let ((ret 0) (i 0) (len (length string)))
     (while (< i len)
-      (setq ret (+ (lsh ret 8) (char-int (aref string i)))
+      (setq ret (+ (lsh ret 8) (binhex-char-int (aref string i)))
            i (1+ i)))
     ret))
 
 (defun binhex-string-little-endian (string)
   (let ((ret 0) (i 0) (shift 0) (len (length string)))
     (while (< i len)
-      (setq ret (+ ret (lsh (char-int (aref string i)) shift))
+      (setq ret (+ ret (lsh (binhex-char-int (aref string i)) shift))
            i (1+ i)
            shift (+ shift 8)))
     ret))
@@ -150,11 +175,11 @@ input and write the converted data to its standard output.")
     (let ((pos (point-min)) len)
       (vector
        (prog1
-          (setq len (char-int (char-after pos)))
+          (setq len (binhex-char-int (char-after pos)))
         (setq pos (1+ pos)))
        (buffer-substring pos (setq pos (+ pos len)))
        (prog1
-          (setq len (char-int (char-after pos)))
+          (setq len (binhex-char-int (char-after pos)))
         (setq pos (1+ pos)))
        (buffer-substring pos (setq pos (+ pos 4)))
        (buffer-substring pos (setq pos (+ pos 4)))
@@ -183,8 +208,9 @@ input and write the converted data to its standard output.")
    (t
     (binhex-insert-char (setq binhex-last-char char) 1 ignored buffer))))
 
-(defun binhex-decode-region (start end &optional header-only)
-  "Binhex decode region between START and END.
+;;;###autoload
+(defun binhex-decode-region-internal (start end &optional header-only)
+  "Binhex decode region between START and END without using an external program.
 If HEADER-ONLY is non-nil only decode header and return filename."
   (interactive "r")
   (let ((work-buffer nil)
@@ -199,15 +225,9 @@ If HEADER-ONLY is non-nil only decode header and return filename."
        (save-excursion
          (goto-char start)
          (when (re-search-forward binhex-begin-line end t)
-           (if (boundp 'enable-multibyte-characters)
-               (let ((multibyte
-                      (default-value 'enable-multibyte-characters)))
-                 (setq-default enable-multibyte-characters nil)
-                 (setq work-buffer
-                       (generate-new-buffer " *binhex-work*"))
-                 (setq-default enable-multibyte-characters multibyte))
-             (setq work-buffer (generate-new-buffer " *binhex-work*")))
-           (buffer-disable-undo work-buffer)
+            (setq work-buffer (generate-new-buffer " *binhex-work*"))
+           (unless (featurep 'xemacs)
+             (with-current-buffer work-buffer (set-buffer-multibyte nil)))
            (beginning-of-line)
            (setq bits 0 counter 0)
            (while tmp
@@ -233,14 +253,13 @@ If HEADER-ONLY is non-nil only decode header and return filename."
                    (setq file-name-length (char-after (point-min))
                          data-fork-start (+ (point-min)
                                             file-name-length 22))))
-             (if (and (null header)
-                      (with-current-buffer work-buffer
-                        (>= (buffer-size) data-fork-start)))
-                 (progn
-                   (binhex-verify-crc work-buffer
-                                      1 data-fork-start)
-                   (setq header (binhex-header work-buffer))
-                   (if header-only (setq tmp nil counter 0))))
+             (when (and (null header)
+                        (with-current-buffer work-buffer
+                          (>= (buffer-size) data-fork-start)))
+               (binhex-verify-crc work-buffer
+                                  (point-min) data-fork-start)
+               (setq header (binhex-header work-buffer))
+               (when header-only (setq tmp nil counter 0)))
              (setq tmp (and tmp (not (eq inputpos end)))))
            (cond
             ((= counter 3)
@@ -251,26 +270,28 @@ If HEADER-ONLY is non-nil only decode header and return filename."
             ((= counter 2)
              (binhex-push-char (logand (lsh bits -10) 255) 1 nil
                                work-buffer))))
-      (if header-only nil
-       (binhex-verify-crc work-buffer
-                          data-fork-start
-                          (+ data-fork-start (aref header 6) 2))
-       (or (markerp end) (setq end (set-marker (make-marker) end)))
-       (goto-char start)
-       (insert-buffer-substring work-buffer
-                                data-fork-start (+ data-fork-start
-                                                   (aref header 6)))
-       (delete-region (point) end)))
+         (if header-only nil
+           (binhex-verify-crc work-buffer
+                              data-fork-start
+                              (+ data-fork-start (aref header 6) 2))
+           (or (markerp end) (setq end (set-marker (make-marker) end)))
+           (goto-char start)
+           (insert-buffer-substring work-buffer
+                                    data-fork-start (+ data-fork-start
+                                                       (aref header 6)))
+           (delete-region (point) end)))
       (and work-buffer (kill-buffer work-buffer)))
     (if header (aref header 1))))
 
+;;;###autoload
 (defun binhex-decode-region-external (start end)
-  "Binhex decode region between START and END using external decoder"
+  "Binhex decode region between START and END using external decoder."
   (interactive "r")
-  (let ((cbuf (current-buffer)) firstline work-buffer status
-       (file-name (concat binhex-temporary-file-directory
-                          (binhex-decode-region start end t)
-                          ".data")))
+  (let ((cbuf (current-buffer)) firstline work-buffer
+       (file-name (expand-file-name
+                   (concat (binhex-decode-region-internal start end t)
+                           ".data")
+                   binhex-temporary-file-directory)))
     (save-excursion
       (goto-char start)
       (when (re-search-forward binhex-begin-line nil t)
@@ -299,10 +320,16 @@ If HEADER-ONLY is non-nil only decode header and return filename."
                (insert-file-contents-literally file-name)))
          (error "Can not binhex")))
       (and work-buffer (kill-buffer work-buffer))
-      (condition-case ()
-         (if file-name (delete-file file-name))
-       (error))
-      )))
+      (ignore-errors
+       (if file-name (delete-file file-name))))))
+
+;;;###autoload
+(defun binhex-decode-region (start end)
+  "Binhex decode region between START and END."
+  (interactive "r")
+  (if binhex-use-external
+      (binhex-decode-region-external start end)
+    (binhex-decode-region-internal start end)))
 
 (provide 'binhex)