aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii1998-07-26 13:57:08 +0000
committerEli Zaretskii1998-07-26 13:57:08 +0000
commiteb93d233fde91d33d2ccc44f939867d7d63d0ccf (patch)
tree68a19bdd631c364626d59135cb028cb632d718eb
parent5074194e46b6b76d400889cfc1811b2a8ce42c2d (diff)
downloademacs-eb93d233fde91d33d2ccc44f939867d7d63d0ccf.tar.gz
emacs-eb93d233fde91d33d2ccc44f939867d7d63d0ccf.zip
(archive-summarize): Set buffer unibyte before
calling archive-XXX-summarize. (archive-file-name-handler): New function to make the caller behave as if the extracted file existed. (archive-set-buffer-as-visiting-file): New function to simulate file visiting. Uses archive-file-name-handler to make dos-w32 systems preserve the coding-system of the extracted files. (archive-extract): Bind coding-system-for-write to file-name-coding-system, coding-system-for-read to 'no-conversion. Call archive-set-buffer-as-visiting-file after a member file is inserted in the current buffer. (archive-extract-by-stdout): Don't bind coding-system-for-read and inherit-process-coding-system. (archive-*-write-file-member): Give an encoded file name to external archive program. (archive-rename-entry): Likewise. (archive-mode-revert): Set buffer unibyte before calling revert-buffer. (archive-arc-rename-entry, archive-zip-chmod-entry): Set buffer unibyte before handling binary archive data. (archive-lzh-rename-entry, archive-lzh-ogm, archive-zip-chmod-entry): Likewise. (archive-lzh-summarize): Set local variable efnname to the decoded file name. If default-enable-multibyte-characters is non-nil, set buffer multibyte before inserting summary lines.
-rw-r--r--lisp/arc-mode.el140
1 files changed, 97 insertions, 43 deletions
diff --git a/lisp/arc-mode.el b/lisp/arc-mode.el
index 8f3ebd1f439..ca5d6185337 100644
--- a/lisp/arc-mode.el
+++ b/lisp/arc-mode.el
@@ -690,6 +690,7 @@ is visible (and the real data of the buffer is hidden).
690Optional argument SHUT-UP, if non-nil, means don't print messages 690Optional argument SHUT-UP, if non-nil, means don't print messages
691when parsing the archive." 691when parsing the archive."
692 (widen) 692 (widen)
693 (set-buffer-multibyte nil)
693 (let (buffer-read-only) 694 (let (buffer-read-only)
694 (or shut-up 695 (or shut-up
695 (message "Parsing archive file...")) 696 (message "Parsing archive file..."))
@@ -827,6 +828,41 @@ using `make-temp-name', and the generated name is returned."
827;; ------------------------------------------------------------------------- 828;; -------------------------------------------------------------------------
828;; Section: Member extraction 829;; Section: Member extraction
829 830
831(defun archive-file-name-handler (op &rest args)
832 (or (eq op 'file-exists-p)
833 (let ((file-name-handler-alist nil))
834 (apply op args))))
835
836(defun archive-set-buffer-as-visiting-file (filename)
837 "Set the current buffer as if it were visiting FILENAME."
838 (save-excursion
839 (goto-char (point-min))
840 (let ((coding
841 (or coding-system-for-read
842 (and set-auto-coding-function
843 (funcall set-auto-coding-function
844 (- (point-max) (point-min))))
845 ;; dos-w32.el defines find-operation-coding-system for
846 ;; DOS/Windows systems which preserves the coding-system
847 ;; of existing files. We want it to act here as if the
848 ;; extracted file existed.
849 (let ((file-name-handler-alist
850 '(("" . archive-file-name-handler))))
851 (car (find-operation-coding-system 'insert-file-contents
852 filename t))))))
853 (if (and (not coding-system-for-read)
854 (not enable-multibyte-characters))
855 (setq coding
856 (coding-system-change-text-conversion coding 'raw-text)))
857 (if (and coding
858 (not (eq coding 'no-conversion)))
859 (decode-coding-region (point-min) (point-max) coding)
860 (setq last-coding-system-used coding))
861 (set-buffer-modified-p nil)
862 (kill-local-variable 'buffer-file-coding-system)
863 (after-insert-file-set-buffer-file-coding-system (- (point-max)
864 (point-min))))))
865
830(defun archive-mouse-extract (event) 866(defun archive-mouse-extract (event)
831 "Extract a file whose name you click on." 867 "Extract a file whose name you click on."
832 (interactive "e") 868 (interactive "e")
@@ -876,27 +912,26 @@ using `make-temp-name', and the generated name is returned."
876 (setq archive-subfile-mode descr) 912 (setq archive-subfile-mode descr)
877 (if (and 913 (if (and
878 (null 914 (null
879 (condition-case err 915 (let (;; We may have to encode file name arguement for
880 (if (fboundp extractor) 916 ;; external programs.
881 (funcall extractor archive ename) 917 (coding-system-for-write file-name-coding-system)
882 (archive-*-extract archive ename 918 ;; We read an archive member by no-conversion at
883 (symbol-value extractor))) 919 ;; first, then decode appropriately by calling
884 (error 920 ;; archive-set-buffer-as-visiting-file later.
885 (ding (message "%s" (error-message-string err))) 921 (coding-system-for-read 'no-conversion))
886 nil))) 922 (condition-case err
923 (if (fboundp extractor)
924 (funcall extractor archive ename)
925 (archive-*-extract archive ename
926 (symbol-value extractor)))
927 (error
928 (ding (message "%s" (error-message-string err)))
929 nil))))
887 just-created) 930 just-created)
888 (progn 931 (progn
889 (set-buffer-modified-p nil) 932 (set-buffer-modified-p nil)
890 (kill-buffer buffer)) 933 (kill-buffer buffer))
891 ;; If Emacs were to visit the file we've extracted, it would make 934 (archive-set-buffer-as-visiting-file ename)
892 ;; the buffer be unibyte if the detected coding-system is
893 ;; no-conversion or raw-text-*. We want the same behavior here
894 ;; as if we were visiting the file, even though some extractors
895 ;; read the file's contents from a pipe.
896 (if (or (eq last-coding-system-used 'no-conversion)
897 ;; type 5 is raw-text
898 (eq (coding-system-type last-coding-system-used) 5))
899 (set-buffer-multibyte nil))
900 (goto-char (point-min)) 935 (goto-char (point-min))
901 (rename-buffer bufname) 936 (rename-buffer bufname)
902 (setq buffer-read-only read-only-p) 937 (setq buffer-read-only read-only-p)
@@ -955,17 +990,12 @@ using `make-temp-name', and the generated name is returned."
955 success)) 990 success))
956 991
957(defun archive-extract-by-stdout (archive name command) 992(defun archive-extract-by-stdout (archive name command)
958 ;; We need the coding system of the output of the extract program, 993 (apply 'call-process
959 ;; including the EOL encoding, be decoded dynamically, since what 994 (car command)
960 ;; the extract program outputs is the contents of some file. 995 nil
961 (let ((coding-system-for-read (or coding-system-for-read 'undecided)) 996 t
962 (inherit-process-coding-system t)) 997 nil
963 (apply 'call-process 998 (append (cdr command) (list archive name))))
964 (car command)
965 nil
966 t
967 nil
968 (append (cdr command) (list archive name)))))
969 999
970(defun archive-extract-other-window () 1000(defun archive-extract-other-window ()
971 "In archive mode, find this member in another window." 1001 "In archive mode, find this member in another window."
@@ -1068,6 +1098,7 @@ using `make-temp-name', and the generated name is returned."
1068 (if (aref descr 3) 1098 (if (aref descr 3)
1069 ;; Set the file modes, but make sure we can read it. 1099 ;; Set the file modes, but make sure we can read it.
1070 (set-file-modes tmpfile (logior ?\400 (aref descr 3)))) 1100 (set-file-modes tmpfile (logior ?\400 (aref descr 3))))
1101 (setq ename (encode-coding-string ename file-name-coding-system))
1071 (let ((exitcode (apply 'call-process 1102 (let ((exitcode (apply 'call-process
1072 (car command) 1103 (car command)
1073 nil 1104 nil
@@ -1245,7 +1276,9 @@ as a relative change like \"g+rw\" as for chmod(2)"
1245 (descr (archive-get-descr))) 1276 (descr (archive-get-descr)))
1246 (if (fboundp func) 1277 (if (fboundp func)
1247 (progn 1278 (progn
1248 (funcall func (buffer-file-name) newname descr) 1279 (funcall func (buffer-file-name)
1280 (encode-coding-string newname file-name-coding-system)
1281 descr)
1249 (archive-resummarize)) 1282 (archive-resummarize))
1250 (error "Renaming is not supported for this archive type")))) 1283 (error "Renaming is not supported for this archive type"))))
1251 1284
@@ -1255,6 +1288,7 @@ as a relative change like \"g+rw\" as for chmod(2)"
1255 (setq archive-files nil) 1288 (setq archive-files nil)
1256 (let ((revert-buffer-function nil) 1289 (let ((revert-buffer-function nil)
1257 (coding-system-for-read 'no-conversion)) 1290 (coding-system-for-read 'no-conversion))
1291 (set-buffer-multibyte nil)
1258 (revert-buffer t t)) 1292 (revert-buffer t t))
1259 (archive-mode) 1293 (archive-mode)
1260 (goto-char archive-file-list-start) 1294 (goto-char archive-file-list-start)
@@ -1327,6 +1361,7 @@ This doesn't recover lost files, it just undoes changes in the buffer itself."
1327 (save-restriction 1361 (save-restriction
1328 (save-excursion 1362 (save-excursion
1329 (widen) 1363 (widen)
1364 (set-buffer-multibyte nil)
1330 (goto-char (+ archive-proper-file-start (aref descr 4) 2)) 1365 (goto-char (+ archive-proper-file-start (aref descr 4) 2))
1331 (delete-char 13) 1366 (delete-char 13)
1332 (insert name))))) 1367 (insert name)))))
@@ -1348,9 +1383,13 @@ This doesn't recover lost files, it just undoes changes in the buffer itself."
1348 (moddate (archive-l-e (+ p 17) 2)) 1383 (moddate (archive-l-e (+ p 17) 2))
1349 (hdrlvl (char-after (+ p 20))) 1384 (hdrlvl (char-after (+ p 20)))
1350 (fnlen (char-after (+ p 21))) 1385 (fnlen (char-after (+ p 21)))
1351 (efnname (buffer-substring (+ p 22) (+ p 22 fnlen))) 1386 (efnname (let ((str (buffer-substring (+ p 22) (+ p 22 fnlen))))
1387 (if file-name-coding-system
1388 (decode-coding-string str file-name-coding-system)
1389 (string-as-multibyte str))))
1352 (fiddle (string= efnname (upcase efnname))) 1390 (fiddle (string= efnname (upcase efnname)))
1353 (ifnname (if fiddle (downcase efnname) efnname)) 1391 (ifnname (if fiddle (downcase efnname) efnname))
1392 (width (string-width ifnname))
1354 (p2 (+ p 22 fnlen)) 1393 (p2 (+ p 22 fnlen))
1355 (creator (if (>= (- hsize fnlen) 24) (char-after (+ p2 2)) 0)) 1394 (creator (if (>= (- hsize fnlen) 24) (char-after (+ p2 2)) 0))
1356 mode modestr uid gid text path prname 1395 mode modestr uid gid text path prname
@@ -1395,7 +1434,7 @@ This doesn't recover lost files, it just undoes changes in the buffer itself."
1395 (archive-dosdate moddate) 1434 (archive-dosdate moddate)
1396 (archive-dostime modtime) 1435 (archive-dostime modtime)
1397 ifnname))) 1436 ifnname)))
1398 (setq maxlen (max maxlen fnlen) 1437 (setq maxlen (max maxlen width)
1399 totalsize (+ totalsize ucsize) 1438 totalsize (+ totalsize ucsize)
1400 visual (cons (vector text 1439 visual (cons (vector text
1401 (- (length text) (length ifnname)) 1440 (- (length text) (length ifnname))
@@ -1405,6 +1444,7 @@ This doesn't recover lost files, it just undoes changes in the buffer itself."
1405 files) 1444 files)
1406 p (+ p hsize 2 csize)))) 1445 p (+ p hsize 2 csize))))
1407 (goto-char (point-min)) 1446 (goto-char (point-min))
1447 (set-buffer-multibyte default-enable-multibyte-characters)
1408 (let ((dash (concat (if archive-alternate-display 1448 (let ((dash (concat (if archive-alternate-display
1409 "- -------- ----- ----- " 1449 "- -------- ----- ----- "
1410 "- ---------- -------- ----------- -------- ") 1450 "- ---------- -------- ----------- -------- ")
@@ -1443,6 +1483,7 @@ This doesn't recover lost files, it just undoes changes in the buffer itself."
1443 (save-restriction 1483 (save-restriction
1444 (save-excursion 1484 (save-excursion
1445 (widen) 1485 (widen)
1486 (set-buffer-multibyte nil)
1446 (let* ((p (+ archive-proper-file-start (aref descr 4))) 1487 (let* ((p (+ archive-proper-file-start (aref descr 4)))
1447 (oldhsize (char-after p)) 1488 (oldhsize (char-after p))
1448 (oldfnlen (char-after (+ p 21))) 1489 (oldfnlen (char-after (+ p 21)))
@@ -1462,6 +1503,7 @@ This doesn't recover lost files, it just undoes changes in the buffer itself."
1462 (save-restriction 1503 (save-restriction
1463 (save-excursion 1504 (save-excursion
1464 (widen) 1505 (widen)
1506 (set-buffer-multibyte nil)
1465 (while files 1507 (while files
1466 (let* ((fil (car files)) 1508 (let* ((fil (car files))
1467 (p (+ archive-proper-file-start (aref fil 4))) 1509 (p (+ archive-proper-file-start (aref fil 4)))
@@ -1516,7 +1558,10 @@ This doesn't recover lost files, it just undoes changes in the buffer itself."
1516 (exlen (archive-l-e (+ p 30) 2)) 1558 (exlen (archive-l-e (+ p 30) 2))
1517 (fclen (archive-l-e (+ p 32) 2)) 1559 (fclen (archive-l-e (+ p 32) 2))
1518 (lheader (archive-l-e (+ p 42) 4)) 1560 (lheader (archive-l-e (+ p 42) 4))
1519 (efnname (buffer-substring (+ p 46) (+ p 46 fnlen))) 1561 (efnname (let ((str (buffer-substring (+ p 46) (+ p 46 fnlen))))
1562 (if file-name-coding-system
1563 (decode-coding-string str file-name-coding-system)
1564 (string-as-multibyte str))))
1520 (isdir (and (= ucsize 0) 1565 (isdir (and (= ucsize 0)
1521 (string= (file-name-nondirectory efnname) ""))) 1566 (string= (file-name-nondirectory efnname) "")))
1522 (mode (cond ((memq creator '(2 3)) ; Unix + VMS 1567 (mode (cond ((memq creator '(2 3)) ; Unix + VMS
@@ -1533,13 +1578,14 @@ This doesn't recover lost files, it just undoes changes in the buffer itself."
1533 (not (not (memq creator '(0 2 4 5 9)))) 1578 (not (not (memq creator '(0 2 4 5 9))))
1534 (string= (upcase efnname) efnname))) 1579 (string= (upcase efnname) efnname)))
1535 (ifnname (if fiddle (downcase efnname) efnname)) 1580 (ifnname (if fiddle (downcase efnname) efnname))
1581 (width (string-width ifnname))
1536 (text (format " %10s %8d %-11s %-8s %s" 1582 (text (format " %10s %8d %-11s %-8s %s"
1537 modestr 1583 modestr
1538 ucsize 1584 ucsize
1539 (archive-dosdate moddate) 1585 (archive-dosdate moddate)
1540 (archive-dostime modtime) 1586 (archive-dostime modtime)
1541 ifnname))) 1587 ifnname)))
1542 (setq maxlen (max maxlen fnlen) 1588 (setq maxlen (max maxlen width)
1543 totalsize (+ totalsize ucsize) 1589 totalsize (+ totalsize ucsize)
1544 visual (cons (vector text 1590 visual (cons (vector text
1545 (- (length text) (length ifnname)) 1591 (- (length text) (length ifnname))
@@ -1581,6 +1627,7 @@ This doesn't recover lost files, it just undoes changes in the buffer itself."
1581 (save-restriction 1627 (save-restriction
1582 (save-excursion 1628 (save-excursion
1583 (widen) 1629 (widen)
1630 (set-buffer-multibyte nil)
1584 (while files 1631 (while files
1585 (let* ((fil (car files)) 1632 (let* ((fil (car files))
1586 (p (+ archive-proper-file-start (car (aref fil 4)))) 1633 (p (+ archive-proper-file-start (car (aref fil 4))))
@@ -1619,23 +1666,30 @@ This doesn't recover lost files, it just undoes changes in the buffer itself."
1619 (lfnlen (if (= dirtype 2) (char-after (+ p 56)) 0)) 1666 (lfnlen (if (= dirtype 2) (char-after (+ p 56)) 0))
1620 (ldirlen (if (= dirtype 2) (char-after (+ p 57)) 0)) 1667 (ldirlen (if (= dirtype 2) (char-after (+ p 57)) 0))
1621 (fnlen (or (string-match "\0" namefld) 13)) 1668 (fnlen (or (string-match "\0" namefld) 13))
1622 (efnname (concat 1669 (efnname (let ((str
1623 (if (> ldirlen 0) 1670 (concat
1624 (concat (buffer-substring 1671 (if (> ldirlen 0)
1625 (+ p 58 lfnlen) (+ p 58 lfnlen ldirlen -1)) 1672 (concat (buffer-substring
1626 "/") 1673 (+ p 58 lfnlen)
1627 "") 1674 (+ p 58 lfnlen ldirlen -1))
1628 (if (> lfnlen 0) 1675 "/")
1629 (buffer-substring (+ p 58) (+ p 58 lfnlen -1)) 1676 "")
1630 (substring namefld 0 fnlen)))) 1677 (if (> lfnlen 0)
1678 (buffer-substring (+ p 58)
1679 (+ p 58 lfnlen -1))
1680 (substring namefld 0 fnlen)))))
1681 (if file-name-coding-system
1682 (decode-coding-string str file-name-coding-system)
1683 (string-as-multibyte str))))
1631 (fiddle (and (= lfnlen 0) (string= efnname (upcase efnname)))) 1684 (fiddle (and (= lfnlen 0) (string= efnname (upcase efnname))))
1632 (ifnname (if fiddle (downcase efnname) efnname)) 1685 (ifnname (if fiddle (downcase efnname) efnname))
1686 (width (string-width ifnname))
1633 (text (format " %8d %-11s %-8s %s" 1687 (text (format " %8d %-11s %-8s %s"
1634 ucsize 1688 ucsize
1635 (archive-dosdate moddate) 1689 (archive-dosdate moddate)
1636 (archive-dostime modtime) 1690 (archive-dostime modtime)
1637 ifnname))) 1691 ifnname)))
1638 (setq maxlen (max maxlen (length ifnname)) 1692 (setq maxlen (max maxlen (length width))
1639 totalsize (+ totalsize ucsize) 1693 totalsize (+ totalsize ucsize)
1640 visual (cons (vector text 1694 visual (cons (vector text
1641 (- (length text) (length ifnname)) 1695 (- (length text) (length ifnname))