X-Git-Url: https://cgit.sxemacs.org/?a=blobdiff_plain;f=lisp%2Fuudecode.el;h=01c2db310dc51c38ba5c246d6356553b0c153290;hb=e405b22c6b46721607c5e6c712a4705c23dee751;hp=b44e3c9550d5d0b6ddfed79ccf729e45d1309c52;hpb=58f65e756466ad2567d583dd00299d17511394e3;p=gnus diff --git a/lisp/uudecode.el b/lisp/uudecode.el index b44e3c955..01c2db310 100644 --- a/lisp/uudecode.el +++ b/lisp/uudecode.el @@ -1,12 +1,12 @@ ;;; uudecode.el -- elisp native uudecode -;; Copyright (c) 1998 by Shenghuo Zhu + +;; Copyright (c) 1998, 1999, 2000, 2001, 2003, 2004 +;; Free Software Foundation, Inc. ;; Author: Shenghuo Zhu -;; $Revision: 5.3 $ -;; Keywords: uudecode +;; Keywords: uudecode 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 ;; it under the terms of the GNU General Public License as published by @@ -25,21 +25,34 @@ ;;; 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)) +(eval-when-compile (require 'cl)) + +(eval-and-compile + (defalias 'uudecode-char-int + (if (fboundp 'char-int) + 'char-int + 'identity))) -(defvar uudecode-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.") - -(defvar uudecode-decoder-switches nil - "*List of command line flags passed to the command named by uudecode-decoder-program.") +input and write the converted data to its standard output." + :type 'string + :group 'gnus-extract) + +(defcustom uudecode-decoder-switches nil + "*List of command line flags passed to `uudecode-decoder-program'." + :group 'gnus-extract + :type '(repeat string)) + +(defcustom uudecode-use-external + (executable-find uudecode-decoder-program) + "*Use external uudecode program." + :version "22.1" + :group 'gnus-extract + :type 'boolean) (defconst uudecode-alphabet "\040-\140") @@ -55,15 +68,15 @@ input and write the converted data to its standard output.") (defvar uudecode-temporary-file-directory (cond ((fboundp 'temp-directory) (temp-directory)) ((boundp 'temporary-file-directory) temporary-file-directory) - ("/tmp/"))) + ("/tmp"))) ;;;###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." + "Uudecode region between START and END using external program. +If FILE-NAME is non-nil, save the result to FILE-NAME. The program +used is specified by `uudecode-decoder-program'." (interactive "r\nP") - (let ((cbuf (current-buffer)) tempfile firstline work-buffer status) + (let ((cbuf (current-buffer)) tempfile firstline status) (save-excursion (goto-char start) (when (re-search-forward uudecode-begin-line nil t) @@ -71,26 +84,30 @@ If FILE-NAME is non-nil, save the result to FILE-NAME." (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 uudecode-temporary-file-directory - (make-temp-name "uu"))))) - (let ((cdir default-directory) default-process-coding-system) + (setq tempfile (if file-name + (expand-file-name file-name) + (if (fboundp 'make-temp-file) + (let ((temporary-file-directory + uudecode-temporary-file-directory)) + (make-temp-file "uu")) + (expand-file-name + (make-temp-name "uu") + uudecode-temporary-file-directory)))) + (let ((cdir default-directory) + default-process-coding-system) (unwind-protect - (progn - (set-buffer (setq work-buffer - (generate-new-buffer " *uudecode-work*"))) - (buffer-disable-undo work-buffer) + (with-temp-buffer (insert "begin 600 " (file-name-nondirectory tempfile) "\n") (insert-buffer-substring cbuf firstline end) (cd (file-name-directory tempfile)) (apply 'call-process-region (point-min) (point-max) - uudecode-decoder-program + uudecode-decoder-program nil nil nil @@ -103,102 +120,97 @@ If FILE-NAME is non-nil, save the result to FILE-NAME." (let (format-alist) (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)) - ))) - -(if (string-match "XEmacs" emacs-version) - (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))))) + (ignore-errors (or file-name (delete-file tempfile)))))) ;;;###autoload - -(defun uudecode-decode-region (start end &optional file-name) - "uudecode region between START and END. +(defun uudecode-decode-region-internal (start end &optional file-name) + "Uudecode region between START and END without using an external program. If FILE-NAME is non-nil, save the result to FILE-NAME." (interactive "r\nP") - (let ((work-buffer nil) - (done nil) + (let ((done nil) (counter 0) (remain 0) (bits 0) - (lim 0) inputpos + (lim 0) inputpos result (non-data-chars (concat "^" uudecode-alphabet))) - (unwind-protect - (save-excursion + (save-excursion + (goto-char start) + (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 + (match-string 1)))))) + (forward-line 1) + (skip-chars-forward non-data-chars end) + (while (not done) + (setq inputpos (point)) + (setq remain 0 bits 0 counter 0) + (cond + ((> (skip-chars-forward uudecode-alphabet end) 0) + (setq lim (point)) + (setq remain + (logand (- (uudecode-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 + (- + (uudecode-char-int (char-after inputpos)) 32) + 63))) + (if (/= counter 0) (setq remain (1- remain))) + (setq counter (1+ counter) + inputpos (1+ inputpos)) + (cond ((= counter 4) + (setq result (cons + (concat + (char-to-string (lsh bits -16)) + (char-to-string (logand (lsh bits -8) 255)) + (char-to-string (logand bits 255))) + result)) + (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) + (setq result (cons + (concat + (char-to-string (logand (lsh bits -16) 255)) + (char-to-string (logand (lsh bits -8) 255))) + result))) + ((= counter 2) + (setq result (cons + (char-to-string (logand (lsh bits -10) 255)) + result)))) + (skip-chars-forward non-data-chars end)) + (if file-name + (let (default-enable-multibyte-characters) + (with-temp-file file-name + (insert (apply 'concat (nreverse result))))) + (or (markerp end) (setq end (set-marker (make-marker) end))) (goto-char start) - (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 - (match-string 1)))))) - (setq work-buffer (generate-new-buffer " *uudecode-work*")) - (buffer-disable-undo work-buffer) - (forward-line 1) - (skip-chars-forward non-data-chars end) - (while (not done) - (setq inputpos (point)) - (setq remain 0 bits 0 counter 0) - (cond - ((> (skip-chars-forward uudecode-alphabet end) 0) - (setq lim (point)) - (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 - (- - (char-int (char-after inputpos)) 32) 63))) - (if (/= counter 0) (setq remain (1- remain))) - (setq counter (1+ counter) - inputpos (1+ inputpos)) - (cond ((= counter 4) - (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) - (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 - (set-buffer work-buffer) - (write-file file-name)) - (or (markerp end) (setq end (set-marker (make-marker) end))) - (goto-char start) - (insert-buffer-substring work-buffer) - (delete-region (point) end)))) - (and work-buffer (kill-buffer work-buffer))))) + (insert (apply 'concat (nreverse result))) + (delete-region (point) end)))))) + +;;;###autoload +(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." + (if uudecode-use-external + (uudecode-decode-region-external start end file-name) + (uudecode-decode-region-internal start end file-name))) (provide 'uudecode) +;;; arch-tag: e1f09ed5-62b4-4677-9f13-4e81c4fe8ce3 ;;; uudecode.el ends here