diff options
| author | Stefan Monnier | 2020-04-03 16:45:54 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2020-04-03 16:45:54 -0400 |
| commit | c640be60d918d5a7be4d9d5e717cf159f878d38c (patch) | |
| tree | ad9ab7ec07f3b274f34bdab74aaae748976c397a | |
| parent | 9b995320c853a45d785896fb25f788f9248658f4 (diff) | |
| download | emacs-c640be60d918d5a7be4d9d5e717cf159f878d38c.tar.gz emacs-c640be60d918d5a7be4d9d5e717cf159f878d38c.zip | |
* lisp/arc-mode.el: Use cl-structs rather than vectors
(archive--file-desc, archive--file-summary, archive-arc--file-desc)
(archive-lzh--file-desc, archive-zip--file-desc)
(archive-zoo--file-desc, archive-rar--file-desc)
(archive-7z--file-desc, archive-ar--file-desc): New structs.
(archive-get-descr, archive-mode, archive-summarize-files)
(archive-maybe-copy, archive-extract, archive-*-write-file-member)
(archive-expunge, archive-arc-summarize, archive-arc-rename-entry)
(archive-lzh-summarize, archive-lzh-rename-entry, archive-lzh-ogm)
(archive-zip-summarize, archive-zip-write-file-member)
(archive-zip-chmod-entry, archive-zoo-summarize)
(archive-rar-summarize, archive-7z-summarize, archive-ar-summarize)
(archive-ar-write-file-member): Use struct constructors and accessors
instead of `vector` and `aref`.
(archive-calc-mode): Remove `error` arg which was always non-nil;
adjust all callers.
Rewrite using `string-to-number` and `file-modes-symbolic-to-number`.
| -rw-r--r-- | lisp/arc-mode.el | 343 |
1 files changed, 196 insertions, 147 deletions
diff --git a/lisp/arc-mode.el b/lisp/arc-mode.el index 21b9627e407..4609123dec9 100644 --- a/lisp/arc-mode.el +++ b/lisp/arc-mode.el | |||
| @@ -366,7 +366,7 @@ file. Archive and member name will be added." | |||
| 366 | (defvar archive-file-list-end nil "Position just after last contents line.") | 366 | (defvar archive-file-list-end nil "Position just after last contents line.") |
| 367 | (defvar archive-proper-file-start nil "Position of real archive's start.") | 367 | (defvar archive-proper-file-start nil "Position of real archive's start.") |
| 368 | (defvar archive-read-only nil "Non-nil if the archive is read-only on disk.") | 368 | (defvar archive-read-only nil "Non-nil if the archive is read-only on disk.") |
| 369 | (defvar archive-local-name nil "Name of local copy of remote archive.") | 369 | (defvar-local archive-local-name nil "Name of local copy of remote archive.") |
| 370 | (defvar archive-mode-map | 370 | (defvar archive-mode-map |
| 371 | (let ((map (make-keymap))) | 371 | (let ((map (make-keymap))) |
| 372 | (set-keymap-parent map special-mode-map) | 372 | (set-keymap-parent map special-mode-map) |
| @@ -485,18 +485,23 @@ file. Archive and member name will be added." | |||
| 485 | (defvar archive-superior-buffer nil "In archive members, points to archive.") | 485 | (defvar archive-superior-buffer nil "In archive members, points to archive.") |
| 486 | (put 'archive-superior-buffer 'permanent-local t) | 486 | (put 'archive-superior-buffer 'permanent-local t) |
| 487 | 487 | ||
| 488 | (defvar archive-subfile-mode nil "Non-nil in archive member buffers.") | 488 | (defvar-local archive-subfile-mode nil |
| 489 | (make-variable-buffer-local 'archive-subfile-mode) | 489 | "Non-nil in archive member buffers. |
| 490 | Its value is an `archive--file-desc'.") | ||
| 490 | (put 'archive-subfile-mode 'permanent-local t) | 491 | (put 'archive-subfile-mode 'permanent-local t) |
| 491 | 492 | ||
| 492 | (defvar archive-file-name-coding-system nil) | 493 | (defvar archive-file-name-coding-system nil) |
| 493 | (make-variable-buffer-local 'archive-file-name-coding-system) | 494 | (make-variable-buffer-local 'archive-file-name-coding-system) |
| 494 | (put 'archive-file-name-coding-system 'permanent-local t) | 495 | (put 'archive-file-name-coding-system 'permanent-local t) |
| 495 | 496 | ||
| 497 | (cl-defstruct (archive--file-desc | ||
| 498 | (:constructor nil) | ||
| 499 | (:constructor archive--file-desc | ||
| 500 | (ext-file-name int-file-name case-fiddled mode))) | ||
| 501 | ext-file-name int-file-name case-fiddled mode) | ||
| 502 | |||
| 496 | (defvar archive-files nil | 503 | (defvar archive-files nil |
| 497 | "Vector of file descriptors. | 504 | "Vector of `archive--file-desc' objects.") |
| 498 | Each descriptor is a vector of the form | ||
| 499 | [EXT-FILE-NAME INT-FILE-NAME CASE-FIDDLED MODE ...]") | ||
| 500 | (make-variable-buffer-local 'archive-files) | 505 | (make-variable-buffer-local 'archive-files) |
| 501 | 506 | ||
| 502 | ;; ------------------------------------------------------------------------- | 507 | ;; ------------------------------------------------------------------------- |
| @@ -550,52 +555,16 @@ in which case a second argument, length LEN, should be supplied." | |||
| 550 | (if (zerop (logand 2 mode)) ?- ?w) | 555 | (if (zerop (logand 2 mode)) ?- ?w) |
| 551 | (if (zerop (logand 1 mode)) ?- ?x))) | 556 | (if (zerop (logand 1 mode)) ?- ?x))) |
| 552 | 557 | ||
| 553 | (defun archive-calc-mode (oldmode newmode &optional error) | 558 | (defun archive-calc-mode (oldmode newmode) |
| 554 | "From the integer OLDMODE and the string NEWMODE calculate a new file mode. | 559 | "From the integer OLDMODE and the string NEWMODE calculate a new file mode. |
| 555 | NEWMODE may be an octal number including a leading zero in which case it | 560 | NEWMODE may be an octal number including a leading zero in which case it |
| 556 | will become the new mode.\n | 561 | will become the new mode.\n |
| 557 | NEWMODE may also be a relative specification like \"og-rwx\" in which case | 562 | NEWMODE may also be a relative specification like \"og-rwx\" in which case |
| 558 | OLDMODE will be modified accordingly just like chmod(2) would have done.\n | 563 | OLDMODE will be modified accordingly just like chmod(2) would have done." |
| 559 | If optional third argument ERROR is non-nil an error will be signaled if | 564 | ;; FIXME: Use `file-modes-symbolic-to-number'! |
| 560 | the mode is invalid. If ERROR is nil then nil will be returned." | 565 | (if (string-match "\\`0[0-7]*\\'" newmode) |
| 561 | (cond ((string-match "^0[0-7]*$" newmode) | 566 | (logior (logand oldmode #o177000) (string-to-number newmode 8)) |
| 562 | (let ((result 0) | 567 | (file-modes-symbolic-to-number newmode oldmode))) |
| 563 | (len (length newmode)) | ||
| 564 | (i 1)) | ||
| 565 | (while (< i len) | ||
| 566 | (setq result (+ (ash result 3) (aref newmode i) (- ?0)) | ||
| 567 | i (1+ i))) | ||
| 568 | (logior (logand oldmode 65024) result))) | ||
| 569 | ((string-match "^\\([agou]+\\)\\([---+=]\\)\\([rwxst]+\\)$" newmode) | ||
| 570 | (let ((who 0) | ||
| 571 | (result oldmode) | ||
| 572 | (op (aref newmode (match-beginning 2))) | ||
| 573 | (bits 0) | ||
| 574 | (i (match-beginning 3))) | ||
| 575 | (while (< i (match-end 3)) | ||
| 576 | (let ((rwx (aref newmode i))) | ||
| 577 | (setq bits (logior bits (cond ((= rwx ?r) 292) | ||
| 578 | ((= rwx ?w) 146) | ||
| 579 | ((= rwx ?x) 73) | ||
| 580 | ((= rwx ?s) 3072) | ||
| 581 | ((= rwx ?t) 512))) | ||
| 582 | i (1+ i)))) | ||
| 583 | (while (< who (match-end 1)) | ||
| 584 | (let* ((whoc (aref newmode who)) | ||
| 585 | (whomask (cond ((= whoc ?a) 4095) | ||
| 586 | ((= whoc ?u) 1472) | ||
| 587 | ((= whoc ?g) 2104) | ||
| 588 | ((= whoc ?o) 7)))) | ||
| 589 | (if (= op ?=) | ||
| 590 | (setq result (logand result (lognot whomask)))) | ||
| 591 | (if (= op ?-) | ||
| 592 | (setq result (logand result (lognot (logand whomask bits)))) | ||
| 593 | (setq result (logior result (logand whomask bits))))) | ||
| 594 | (setq who (1+ who))) | ||
| 595 | result)) | ||
| 596 | (t | ||
| 597 | (if error | ||
| 598 | (error "Invalid mode specification: %s" newmode))))) | ||
| 599 | 568 | ||
| 600 | (defun archive-dosdate (date) | 569 | (defun archive-dosdate (date) |
| 601 | "Stringify dos packed DATE record." | 570 | "Stringify dos packed DATE record." |
| @@ -644,7 +613,7 @@ Does not signal an error if optional argument NOERROR is non-nil." | |||
| 644 | (if (and (>= (point) archive-file-list-start) | 613 | (if (and (>= (point) archive-file-list-start) |
| 645 | (< no (length archive-files))) | 614 | (< no (length archive-files))) |
| 646 | (let ((item (aref archive-files no))) | 615 | (let ((item (aref archive-files no))) |
| 647 | (if (vectorp item) | 616 | (if (archive--file-desc-p item) |
| 648 | item | 617 | item |
| 649 | (if (not noerror) | 618 | (if (not noerror) |
| 650 | (error "Entry is not a regular member of the archive")))) | 619 | (error "Entry is not a regular member of the archive")))) |
| @@ -696,10 +665,8 @@ archive. | |||
| 696 | (or (not (file-writable-p (buffer-file-name))) | 665 | (or (not (file-writable-p (buffer-file-name))) |
| 697 | (and archive-subfile-mode | 666 | (and archive-subfile-mode |
| 698 | (string-match file-name-invalid-regexp | 667 | (string-match file-name-invalid-regexp |
| 699 | (aref archive-subfile-mode 0))))) | 668 | (archive--file-desc-ext-file-name |
| 700 | 669 | archive-subfile-mode))))) | |
| 701 | ;; Should we use a local copy when accessing from outside Emacs? | ||
| 702 | (make-local-variable 'archive-local-name) | ||
| 703 | 670 | ||
| 704 | ;; An archive can contain another archive whose name is invalid | 671 | ;; An archive can contain another archive whose name is invalid |
| 705 | ;; on local filesystem. Treat such archives as remote. | 672 | ;; on local filesystem. Treat such archives as remote. |
| @@ -806,27 +773,35 @@ when parsing the archive." | |||
| 806 | (goto-char archive-file-list-start) | 773 | (goto-char archive-file-list-start) |
| 807 | (archive-next-line no))) | 774 | (archive-next-line no))) |
| 808 | 775 | ||
| 776 | (cl-defstruct (archive--file-summary | ||
| 777 | (:constructor nil) | ||
| 778 | (:constructor archive--file-summary (text name-start name-end))) | ||
| 779 | text name-start name-end) | ||
| 780 | |||
| 809 | (defun archive-summarize-files (files) | 781 | (defun archive-summarize-files (files) |
| 810 | "Insert a description of a list of files annotated with proper mouse face." | 782 | "Insert a description of a list of files annotated with proper mouse face." |
| 811 | (setq archive-file-list-start (point-marker)) | 783 | (setq archive-file-list-start (point-marker)) |
| 812 | (setq archive-file-name-indent (if files (aref (car files) 1) 0)) | 784 | ;; Here we assume that they all start at the same column. |
| 785 | (setq archive-file-name-indent | ||
| 786 | ;; FIXME: We assume chars=columns (no double-wide chars and such). | ||
| 787 | (if files (archive--file-summary-name-start (car files)) 0)) | ||
| 813 | ;; We don't want to do an insert for each element since that takes too | 788 | ;; We don't want to do an insert for each element since that takes too |
| 814 | ;; long when the archive -- which has to be moved in memory -- is large. | 789 | ;; long when the archive -- which has to be moved in memory -- is large. |
| 815 | (insert | 790 | (insert |
| 816 | (apply | 791 | (mapconcat |
| 817 | #'concat | 792 | (lambda (fil) |
| 818 | (mapcar | 793 | ;; Using `concat' here copies the text also, so we can add |
| 819 | (lambda (fil) | 794 | ;; properties without problems. |
| 820 | ;; Using `concat' here copies the text also, so we can add | 795 | (let ((text (concat (archive--file-summary-text fil) "\n"))) |
| 821 | ;; properties without problems. | 796 | (add-text-properties |
| 822 | (let ((text (concat (aref fil 0) "\n"))) | 797 | (archive--file-summary-name-start fil) |
| 823 | (add-text-properties | 798 | (archive--file-summary-name-end fil) |
| 824 | (aref fil 1) (aref fil 2) | 799 | '(mouse-face highlight |
| 825 | '(mouse-face highlight | 800 | help-echo "mouse-2: extract this file into a buffer") |
| 826 | help-echo "mouse-2: extract this file into a buffer") | 801 | text) |
| 827 | text) | 802 | text)) |
| 828 | text)) | 803 | files |
| 829 | files))) | 804 | "")) |
| 830 | (setq archive-file-list-end (point-marker))) | 805 | (setq archive-file-list-end (point-marker))) |
| 831 | 806 | ||
| 832 | (defun archive-alternate-display () | 807 | (defun archive-alternate-display () |
| @@ -880,7 +855,8 @@ using `make-temp-file', and the generated name is returned." | |||
| 880 | ;; "foo.zip:bar.zip", which is invalid on DOS/Windows. | 855 | ;; "foo.zip:bar.zip", which is invalid on DOS/Windows. |
| 881 | ;; So use the actual name if available. | 856 | ;; So use the actual name if available. |
| 882 | (archive-name | 857 | (archive-name |
| 883 | (or (and archive-subfile-mode (aref archive-subfile-mode 0)) | 858 | (or (and archive-subfile-mode (archive--file-desc-ext-file-name |
| 859 | archive-subfile-mode)) | ||
| 884 | archive))) | 860 | archive))) |
| 885 | (setq archive-local-name | 861 | (setq archive-local-name |
| 886 | (archive-unique-fname archive-name archive-tmpdir)) | 862 | (archive-unique-fname archive-name archive-tmpdir)) |
| @@ -989,8 +965,8 @@ using `make-temp-file', and the generated name is returned." | |||
| 989 | (if event (posn-set-point (event-end event))) | 965 | (if event (posn-set-point (event-end event))) |
| 990 | (let* ((view-p (eq other-window-p 'view)) | 966 | (let* ((view-p (eq other-window-p 'view)) |
| 991 | (descr (archive-get-descr)) | 967 | (descr (archive-get-descr)) |
| 992 | (ename (aref descr 0)) | 968 | (ename (archive--file-desc-ext-file-name descr)) |
| 993 | (iname (aref descr 1)) | 969 | (iname (archive--file-desc-int-file-name descr)) |
| 994 | (archive-buffer (current-buffer)) | 970 | (archive-buffer (current-buffer)) |
| 995 | (arcdir default-directory) | 971 | (arcdir default-directory) |
| 996 | (archive (buffer-file-name)) | 972 | (archive (buffer-file-name)) |
| @@ -1234,7 +1210,7 @@ using `make-temp-file', and the generated name is returned." | |||
| 1234 | t) | 1210 | t) |
| 1235 | 1211 | ||
| 1236 | (defun archive-*-write-file-member (archive descr command) | 1212 | (defun archive-*-write-file-member (archive descr command) |
| 1237 | (let* ((ename (aref descr 0)) | 1213 | (let* ((ename (archive--file-desc-ext-file-name descr)) |
| 1238 | (tmpfile (expand-file-name ename archive-tmpdir)) | 1214 | (tmpfile (expand-file-name ename archive-tmpdir)) |
| 1239 | (top (directory-file-name (file-name-as-directory archive-tmpdir))) | 1215 | (top (directory-file-name (file-name-as-directory archive-tmpdir))) |
| 1240 | (default-directory (file-name-as-directory top))) | 1216 | (default-directory (file-name-as-directory top))) |
| @@ -1251,9 +1227,10 @@ using `make-temp-file', and the generated name is returned." | |||
| 1251 | ;; further processing clobbers it (we restore it in | 1227 | ;; further processing clobbers it (we restore it in |
| 1252 | ;; archive-write-file-member, above). | 1228 | ;; archive-write-file-member, above). |
| 1253 | (setq archive-member-coding-system last-coding-system-used) | 1229 | (setq archive-member-coding-system last-coding-system-used) |
| 1254 | (if (aref descr 3) | 1230 | (if (archive--file-desc-mode descr) |
| 1255 | ;; Set the file modes, but make sure we can read it. | 1231 | ;; Set the file modes, but make sure we can read it. |
| 1256 | (set-file-modes tmpfile (logior ?\400 (aref descr 3)))) | 1232 | (set-file-modes tmpfile |
| 1233 | (logior ?\400 (archive--file-desc-mode descr)))) | ||
| 1257 | (setq ename | 1234 | (setq ename |
| 1258 | (encode-coding-string ename archive-file-name-coding-system)) | 1235 | (encode-coding-string ename archive-file-name-coding-system)) |
| 1259 | (let* ((coding-system-for-write 'no-conversion) | 1236 | (let* ((coding-system-for-write 'no-conversion) |
| @@ -1357,7 +1334,7 @@ Use \\[archive-unmark-all-files] to remove all marks." | |||
| 1357 | "Change the protection bits associated with all marked or this member. | 1334 | "Change the protection bits associated with all marked or this member. |
| 1358 | The new protection bits can either be specified as an octal number or | 1335 | The new protection bits can either be specified as an octal number or |
| 1359 | as a relative change like \"g+rw\" as for chmod(2)." | 1336 | as a relative change like \"g+rw\" as for chmod(2)." |
| 1360 | (interactive "sNew mode (octal or relative): ") | 1337 | (interactive "sNew mode (octal or symbolic): ") |
| 1361 | (if archive-read-only (error "Archive is read-only")) | 1338 | (if archive-read-only (error "Archive is read-only")) |
| 1362 | (let ((func (archive-name "chmod-entry"))) | 1339 | (let ((func (archive-name "chmod-entry"))) |
| 1363 | (if (fboundp func) | 1340 | (if (fboundp func) |
| @@ -1396,7 +1373,9 @@ as a relative change like \"g+rw\" as for chmod(2)." | |||
| 1396 | (goto-char archive-file-list-start) | 1373 | (goto-char archive-file-list-start) |
| 1397 | (while (< (point) archive-file-list-end) | 1374 | (while (< (point) archive-file-list-end) |
| 1398 | (if (= (following-char) ?D) | 1375 | (if (= (following-char) ?D) |
| 1399 | (setq files (cons (aref (archive-get-descr) 0) files))) | 1376 | (setq files (cons (archive--file-desc-ext-file-name |
| 1377 | (archive-get-descr)) | ||
| 1378 | files))) | ||
| 1400 | (forward-line 1))) | 1379 | (forward-line 1))) |
| 1401 | (setq files (nreverse files)) | 1380 | (setq files (nreverse files)) |
| 1402 | (and files | 1381 | (and files |
| @@ -1460,6 +1439,14 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 1460 | ;; ------------------------------------------------------------------------- | 1439 | ;; ------------------------------------------------------------------------- |
| 1461 | ;;; Section: Arc Archives | 1440 | ;;; Section: Arc Archives |
| 1462 | 1441 | ||
| 1442 | (cl-defstruct (archive-arc--file-desc | ||
| 1443 | (:include archive--file-desc) | ||
| 1444 | (:constructor nil) | ||
| 1445 | (:constructor archive-arc--file-desc | ||
| 1446 | (ext-file-name int-file-name case-fiddled mode | ||
| 1447 | pos))) | ||
| 1448 | pos) | ||
| 1449 | |||
| 1463 | (defun archive-arc-summarize () | 1450 | (defun archive-arc-summarize () |
| 1464 | (let ((p 1) | 1451 | (let ((p 1) |
| 1465 | (totalsize 0) | 1452 | (totalsize 0) |
| @@ -1486,11 +1473,13 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 1486 | ifnname))) | 1473 | ifnname))) |
| 1487 | (setq maxlen (max maxlen fnlen) | 1474 | (setq maxlen (max maxlen fnlen) |
| 1488 | totalsize (+ totalsize ucsize) | 1475 | totalsize (+ totalsize ucsize) |
| 1489 | visual (cons (vector text | 1476 | visual (cons (archive--file-summary |
| 1490 | (- (length text) (length ifnname)) | 1477 | text |
| 1491 | (length text)) | 1478 | (- (length text) (length ifnname)) |
| 1479 | (length text)) | ||
| 1492 | visual) | 1480 | visual) |
| 1493 | files (cons (vector efnname ifnname fiddle nil (1- p)) | 1481 | files (cons (archive-arc--file-desc |
| 1482 | efnname ifnname fiddle nil (1- p)) | ||
| 1494 | files) | 1483 | files) |
| 1495 | p (+ p 29 csize)))) | 1484 | p (+ p 29 csize)))) |
| 1496 | (goto-char (point-min)) | 1485 | (goto-char (point-min)) |
| @@ -1519,12 +1508,21 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 1519 | (save-restriction | 1508 | (save-restriction |
| 1520 | (save-excursion | 1509 | (save-excursion |
| 1521 | (widen) | 1510 | (widen) |
| 1522 | (goto-char (+ archive-proper-file-start (aref descr 4) 2)) | 1511 | (goto-char (+ archive-proper-file-start 2 |
| 1512 | (archive-arc--file-desc-pos descr))) | ||
| 1523 | (delete-char 13) | 1513 | (delete-char 13) |
| 1524 | (arc-insert-unibyte name))))) | 1514 | (arc-insert-unibyte name))))) |
| 1525 | ;; ------------------------------------------------------------------------- | 1515 | ;; ------------------------------------------------------------------------- |
| 1526 | ;;; Section: Lzh Archives | 1516 | ;;; Section: Lzh Archives |
| 1527 | 1517 | ||
| 1518 | (cl-defstruct (archive-lzh--file-desc | ||
| 1519 | (:include archive--file-desc) | ||
| 1520 | (:constructor nil) | ||
| 1521 | (:constructor archive-lzh--file-desc | ||
| 1522 | (ext-file-name int-file-name case-fiddled mode | ||
| 1523 | pos))) | ||
| 1524 | pos) | ||
| 1525 | |||
| 1528 | (defun archive-lzh-summarize (&optional start) | 1526 | (defun archive-lzh-summarize (&optional start) |
| 1529 | (let ((p (or start 1)) ;; 1 for .lzh, something further on for .exe | 1527 | (let ((p (or start 1)) ;; 1 for .lzh, something further on for .exe |
| 1530 | (totalsize 0) | 1528 | (totalsize 0) |
| @@ -1639,11 +1637,13 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 1639 | prname))) | 1637 | prname))) |
| 1640 | (setq maxlen (max maxlen width) | 1638 | (setq maxlen (max maxlen width) |
| 1641 | totalsize (+ totalsize ucsize) | 1639 | totalsize (+ totalsize ucsize) |
| 1642 | visual (cons (vector text | 1640 | visual (cons (archive--file-summary |
| 1643 | (- (length text) (length prname)) | 1641 | text |
| 1644 | (length text)) | 1642 | (- (length text) (length prname)) |
| 1643 | (length text)) | ||
| 1645 | visual) | 1644 | visual) |
| 1646 | files (cons (vector prname ifnname fiddle mode (1- p)) | 1645 | files (cons (archive-lzh--file-desc |
| 1646 | prname ifnname fiddle mode (1- p)) | ||
| 1647 | files)) | 1647 | files)) |
| 1648 | (cond ((= hdrlvl 1) | 1648 | (cond ((= hdrlvl 1) |
| 1649 | (setq p (+ p hsize 2 csize))) | 1649 | (setq p (+ p hsize 2 csize))) |
| @@ -1689,7 +1689,8 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 1689 | (save-restriction | 1689 | (save-restriction |
| 1690 | (save-excursion | 1690 | (save-excursion |
| 1691 | (widen) | 1691 | (widen) |
| 1692 | (let* ((p (+ archive-proper-file-start (aref descr 4))) | 1692 | (let* ((p (+ archive-proper-file-start |
| 1693 | (archive-lzh--file-desc-pos descr))) | ||
| 1693 | (oldhsize (get-byte p)) | 1694 | (oldhsize (get-byte p)) |
| 1694 | (oldfnlen (get-byte (+ p 21))) | 1695 | (oldfnlen (get-byte (+ p 21))) |
| 1695 | (newfnlen (length newname)) | 1696 | (newfnlen (length newname)) |
| @@ -1709,7 +1710,7 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 1709 | (save-restriction | 1710 | (save-restriction |
| 1710 | (widen) | 1711 | (widen) |
| 1711 | (dolist (fil files) | 1712 | (dolist (fil files) |
| 1712 | (let* ((p (+ archive-proper-file-start (aref fil 4))) | 1713 | (let* ((p (+ archive-proper-file-start (archive-lzh--file-desc-pos fil))) |
| 1713 | (hsize (get-byte p)) | 1714 | (hsize (get-byte p)) |
| 1714 | (fnlen (get-byte (+ p 21))) | 1715 | (fnlen (get-byte (+ p 21))) |
| 1715 | (p2 (+ p 22 fnlen)) | 1716 | (p2 (+ p 22 fnlen)) |
| @@ -1726,7 +1727,7 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 1726 | (delete-char 1) | 1727 | (delete-char 1) |
| 1727 | (arc-insert-unibyte (archive-lzh-resum (1+ p) hsize))) | 1728 | (arc-insert-unibyte (archive-lzh-resum (1+ p) hsize))) |
| 1728 | (message "Member %s does not have %s field" | 1729 | (message "Member %s does not have %s field" |
| 1729 | (aref fil 1) errtxt))))))) | 1730 | (archive--file-desc-int-file-name fil) errtxt))))))) |
| 1730 | 1731 | ||
| 1731 | (defun archive-lzh-chown-entry (newuid files) | 1732 | (defun archive-lzh-chown-entry (newuid files) |
| 1732 | (archive-lzh-ogm newuid files "an uid" 10)) | 1733 | (archive-lzh-ogm newuid files "an uid" 10)) |
| @@ -1736,8 +1737,7 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 1736 | 1737 | ||
| 1737 | (defun archive-lzh-chmod-entry (newmode files) | 1738 | (defun archive-lzh-chmod-entry (newmode files) |
| 1738 | (archive-lzh-ogm | 1739 | (archive-lzh-ogm |
| 1739 | ;; This should work even though newmode will be dynamically accessed. | 1740 | (lambda (old) (archive-calc-mode old newmode)) |
| 1740 | (lambda (old) (archive-calc-mode old newmode t)) | ||
| 1741 | files "a unix-style mode" 8)) | 1741 | files "a unix-style mode" 8)) |
| 1742 | 1742 | ||
| 1743 | ;; ------------------------------------------------------------------------- | 1743 | ;; ------------------------------------------------------------------------- |
| @@ -1770,6 +1770,14 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 1770 | ;; ------------------------------------------------------------------------- | 1770 | ;; ------------------------------------------------------------------------- |
| 1771 | ;;; Section: Zip Archives | 1771 | ;;; Section: Zip Archives |
| 1772 | 1772 | ||
| 1773 | (cl-defstruct (archive-zip--file-desc | ||
| 1774 | (:include archive--file-desc) | ||
| 1775 | (:constructor nil) | ||
| 1776 | (:constructor archive-zip--file-desc | ||
| 1777 | (ext-file-name int-file-name case-fiddled mode | ||
| 1778 | pos+len))) | ||
| 1779 | pos+len) | ||
| 1780 | |||
| 1773 | (defun archive-zip-summarize () | 1781 | (defun archive-zip-summarize () |
| 1774 | (goto-char (- (point-max) (- 22 18))) | 1782 | (goto-char (- (point-max) (- 22 18))) |
| 1775 | (search-backward-regexp "[P]K\005\006") | 1783 | (search-backward-regexp "[P]K\005\006") |
| @@ -1832,14 +1840,15 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 1832 | ifnname))) | 1840 | ifnname))) |
| 1833 | (setq maxlen (max maxlen width) | 1841 | (setq maxlen (max maxlen width) |
| 1834 | totalsize (+ totalsize ucsize) | 1842 | totalsize (+ totalsize ucsize) |
| 1835 | visual (cons (vector text | 1843 | visual (cons (archive--file-summary |
| 1836 | (- (length text) (length ifnname)) | 1844 | text |
| 1837 | (length text)) | 1845 | (- (length text) (length ifnname)) |
| 1846 | (length text)) | ||
| 1838 | visual) | 1847 | visual) |
| 1839 | files (cons (if isdir | 1848 | files (cons (if isdir |
| 1840 | nil | 1849 | nil |
| 1841 | (vector efnname ifnname fiddle mode | 1850 | (archive-zip--file-desc efnname ifnname fiddle mode |
| 1842 | (list (1- p) lheader))) | 1851 | (list (1- p) lheader))) |
| 1843 | files) | 1852 | files) |
| 1844 | p (+ p 46 fnlen exlen fclen)))) | 1853 | p (+ p 46 fnlen exlen fclen)))) |
| 1845 | (goto-char (point-min)) | 1854 | (goto-char (point-min)) |
| @@ -1884,17 +1893,19 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 1884 | (archive-*-write-file-member | 1893 | (archive-*-write-file-member |
| 1885 | archive | 1894 | archive |
| 1886 | descr | 1895 | descr |
| 1887 | (if (aref descr 2) archive-zip-update-case archive-zip-update))) | 1896 | (if (archive--file-desc-case-fiddled descr) |
| 1897 | archive-zip-update-case archive-zip-update))) | ||
| 1888 | 1898 | ||
| 1889 | (defun archive-zip-chmod-entry (newmode files) | 1899 | (defun archive-zip-chmod-entry (newmode files) |
| 1890 | (save-restriction | 1900 | (save-restriction |
| 1891 | (save-excursion | 1901 | (save-excursion |
| 1892 | (widen) | 1902 | (widen) |
| 1893 | (dolist (fil files) | 1903 | (dolist (fil files) |
| 1894 | (let* ((p (+ archive-proper-file-start (car (aref fil 4)))) | 1904 | (let* ((p (+ archive-proper-file-start |
| 1905 | (car (archive-zip--file-desc-pos+len fil)))) | ||
| 1895 | (creator (get-byte (+ p 5))) | 1906 | (creator (get-byte (+ p 5))) |
| 1896 | (oldmode (aref fil 3)) | 1907 | (oldmode (archive--file-desc-mode fil)) |
| 1897 | (newval (archive-calc-mode oldmode newmode t)) | 1908 | (newval (archive-calc-mode oldmode newmode)) |
| 1898 | (inhibit-read-only t)) | 1909 | (inhibit-read-only t)) |
| 1899 | (cond ((memq creator '(2 3)) ; Unix | 1910 | (cond ((memq creator '(2 3)) ; Unix |
| 1900 | (goto-char (+ p 40)) | 1911 | (goto-char (+ p 40)) |
| @@ -1911,6 +1922,14 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 1911 | ;; ------------------------------------------------------------------------- | 1922 | ;; ------------------------------------------------------------------------- |
| 1912 | ;;; Section: Zoo Archives | 1923 | ;;; Section: Zoo Archives |
| 1913 | 1924 | ||
| 1925 | (cl-defstruct (archive-zoo--file-desc | ||
| 1926 | (:include archive--file-desc) | ||
| 1927 | (:constructor nil) | ||
| 1928 | (:constructor archive-zoo--file-desc | ||
| 1929 | (ext-file-name int-file-name case-fiddled mode | ||
| 1930 | pos))) | ||
| 1931 | pos) | ||
| 1932 | |||
| 1914 | (defun archive-zoo-summarize () | 1933 | (defun archive-zoo-summarize () |
| 1915 | (let ((p (1+ (archive-l-e 25 4))) | 1934 | (let ((p (1+ (archive-l-e 25 4))) |
| 1916 | (maxlen 8) | 1935 | (maxlen 8) |
| @@ -1952,11 +1971,15 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 1952 | ifnname))) | 1971 | ifnname))) |
| 1953 | (setq maxlen (max maxlen width) | 1972 | (setq maxlen (max maxlen width) |
| 1954 | totalsize (+ totalsize ucsize) | 1973 | totalsize (+ totalsize ucsize) |
| 1955 | visual (cons (vector text | 1974 | visual (cons (archive--file-summary |
| 1956 | (- (length text) (length ifnname)) | 1975 | text |
| 1957 | (length text)) | 1976 | (- (length text) (length ifnname)) |
| 1977 | (length text)) | ||
| 1958 | visual) | 1978 | visual) |
| 1959 | files (cons (vector efnname ifnname fiddle nil (1- p)) | 1979 | ;; FIXME: Keep size/date(/mode?) in the desc! |
| 1980 | files (cons (archive-zoo--file-desc | ||
| 1981 | ;; FIXME: The `pos' field seems unused! | ||
| 1982 | efnname ifnname fiddle nil (1- p)) | ||
| 1960 | files) | 1983 | files) |
| 1961 | p next))) | 1984 | p next))) |
| 1962 | (goto-char (point-min)) | 1985 | (goto-char (point-min)) |
| @@ -1980,6 +2003,14 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 1980 | ;; ------------------------------------------------------------------------- | 2003 | ;; ------------------------------------------------------------------------- |
| 1981 | ;;; Section: Rar Archives | 2004 | ;;; Section: Rar Archives |
| 1982 | 2005 | ||
| 2006 | (cl-defstruct (archive-rar--file-desc | ||
| 2007 | (:include archive--file-desc) | ||
| 2008 | (:constructor nil) | ||
| 2009 | (:constructor archive-rar--file-desc | ||
| 2010 | (ext-file-name int-file-name case-fiddled mode | ||
| 2011 | size ratio date time))) | ||
| 2012 | size ratio date time) | ||
| 2013 | |||
| 1983 | (defun archive-rar-summarize (&optional file) | 2014 | (defun archive-rar-summarize (&optional file) |
| 1984 | ;; File is used internally for `archive-rar-exe-summarize'. | 2015 | ;; File is used internally for `archive-rar-exe-summarize'. |
| 1985 | (unless file (setq file buffer-file-name)) | 2016 | (unless file (setq file buffer-file-name)) |
| @@ -2005,11 +2036,11 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 2005 | (size (match-string 1))) | 2036 | (size (match-string 1))) |
| 2006 | (if (> (length name) maxname) (setq maxname (length name))) | 2037 | (if (> (length name) maxname) (setq maxname (length name))) |
| 2007 | (if (> (length size) maxsize) (setq maxsize (length size))) | 2038 | (if (> (length size) maxsize) (setq maxsize (length size))) |
| 2008 | (push (vector name name nil nil | 2039 | (push (archive-rar--file-desc name name nil nil |
| 2009 | ;; Size, Ratio. | 2040 | ;; Size, Ratio. |
| 2010 | size (match-string 2) | 2041 | size (match-string 2) |
| 2011 | ;; Date, Time. | 2042 | ;; Date, Time. |
| 2012 | (match-string 4) (match-string 5)) | 2043 | (match-string 4) (match-string 5)) |
| 2013 | files)))) | 2044 | files)))) |
| 2014 | (setq files (nreverse files)) | 2045 | (setq files (nreverse files)) |
| 2015 | (goto-char (point-min)) | 2046 | (goto-char (point-min)) |
| @@ -2019,18 +2050,20 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 2019 | (column (length sep))) | 2050 | (column (length sep))) |
| 2020 | (insert (format format " Date " "Time " "Size" "Ratio" "Filename") "\n") | 2051 | (insert (format format " Date " "Time " "Size" "Ratio" "Filename") "\n") |
| 2021 | (insert sep (make-string maxname ?-) "\n") | 2052 | (insert sep (make-string maxname ?-) "\n") |
| 2022 | (archive-summarize-files (mapcar (lambda (desc) | 2053 | (archive-summarize-files |
| 2023 | (let ((text | 2054 | (mapcar (lambda (desc) |
| 2024 | (format format | 2055 | (let ((text |
| 2025 | (aref desc 6) | 2056 | (format format |
| 2026 | (aref desc 7) | 2057 | (archive-rar--file-desc-date desc) |
| 2027 | (aref desc 4) | 2058 | (archive-rar--file-desc-time desc) |
| 2028 | (aref desc 5) | 2059 | (archive-rar--file-desc-size desc) |
| 2029 | (aref desc 1)))) | 2060 | (archive-rar--file-desc-ratio desc) |
| 2030 | (vector text | 2061 | (archive--file-desc-int-file-name desc)))) |
| 2031 | column | 2062 | (archive--file-summary |
| 2032 | (length text)))) | 2063 | text |
| 2033 | files)) | 2064 | column |
| 2065 | (length text)))) | ||
| 2066 | files)) | ||
| 2034 | (insert sep (make-string maxname ?-) "\n") | 2067 | (insert sep (make-string maxname ?-) "\n") |
| 2035 | (apply #'vector files)))) | 2068 | (apply #'vector files)))) |
| 2036 | 2069 | ||
| @@ -2078,6 +2111,14 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 2078 | ;; ------------------------------------------------------------------------- | 2111 | ;; ------------------------------------------------------------------------- |
| 2079 | ;;; Section: 7z Archives | 2112 | ;;; Section: 7z Archives |
| 2080 | 2113 | ||
| 2114 | (cl-defstruct (archive-7z--file-desc | ||
| 2115 | (:include archive--file-desc) | ||
| 2116 | (:constructor nil) | ||
| 2117 | (:constructor archive-7z--file-desc | ||
| 2118 | (ext-file-name int-file-name case-fiddled mode | ||
| 2119 | time user group size))) | ||
| 2120 | time user group size) | ||
| 2121 | |||
| 2081 | (defun archive-7z-summarize () | 2122 | (defun archive-7z-summarize () |
| 2082 | (let ((maxname 10) | 2123 | (let ((maxname 10) |
| 2083 | (maxsize 5) | 2124 | (maxsize 5) |
| @@ -2100,7 +2141,7 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 2100 | (match-string 1))))) | 2141 | (match-string 1))))) |
| 2101 | (if (> (length name) maxname) (setq maxname (length name))) | 2142 | (if (> (length name) maxname) (setq maxname (length name))) |
| 2102 | (if (> (length size) maxsize) (setq maxsize (length size))) | 2143 | (if (> (length size) maxsize) (setq maxsize (length size))) |
| 2103 | (push (vector name name nil nil time nil nil size) | 2144 | (push (archive-7z--file-desc name name nil nil time nil nil size) |
| 2104 | files)))) | 2145 | files)))) |
| 2105 | (setq files (nreverse files)) | 2146 | (setq files (nreverse files)) |
| 2106 | (goto-char (point-min)) | 2147 | (goto-char (point-min)) |
| @@ -2109,16 +2150,16 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 2109 | (column (length sep))) | 2150 | (column (length sep))) |
| 2110 | (insert (format format "Size " "Date Time " " Filename") "\n") | 2151 | (insert (format format "Size " "Date Time " " Filename") "\n") |
| 2111 | (insert sep (make-string maxname ?-) "\n") | 2152 | (insert sep (make-string maxname ?-) "\n") |
| 2112 | (archive-summarize-files (mapcar (lambda (desc) | 2153 | (archive-summarize-files |
| 2113 | (let ((text | 2154 | (mapcar (lambda (desc) |
| 2114 | (format format | 2155 | (let ((text |
| 2115 | (aref desc 7) | 2156 | (format format |
| 2116 | (aref desc 4) | 2157 | (archive-7z--file-desc-size desc) |
| 2117 | (aref desc 1)))) | 2158 | (archive-7z--file-desc-time desc) |
| 2118 | (vector text | 2159 | (archive--file-desc-int-file-name desc)))) |
| 2119 | column | 2160 | (archive--file-summary |
| 2120 | (length text)))) | 2161 | text column (length text)))) |
| 2121 | files)) | 2162 | files)) |
| 2122 | (insert sep (make-string maxname ?-) "\n") | 2163 | (insert sep (make-string maxname ?-) "\n") |
| 2123 | (apply #'vector files)))) | 2164 | (apply #'vector files)))) |
| 2124 | 2165 | ||
| @@ -2142,6 +2183,14 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 2142 | ;; not the GNU nor the BSD extensions. As it turns out, this is sufficient | 2183 | ;; not the GNU nor the BSD extensions. As it turns out, this is sufficient |
| 2143 | ;; for .deb packages. | 2184 | ;; for .deb packages. |
| 2144 | 2185 | ||
| 2186 | (cl-defstruct (archive-ar--file-desc | ||
| 2187 | (:include archive--file-desc) | ||
| 2188 | (:constructor nil) | ||
| 2189 | (:constructor archive-ar--file-desc | ||
| 2190 | (ext-file-name int-file-name case-fiddled mode | ||
| 2191 | time user group size))) | ||
| 2192 | time user group size) | ||
| 2193 | |||
| 2145 | (autoload 'tar-grind-file-mode "tar-mode") | 2194 | (autoload 'tar-grind-file-mode "tar-mode") |
| 2146 | 2195 | ||
| 2147 | (defconst archive-ar-file-header-re | 2196 | (defconst archive-ar-file-header-re |
| @@ -2193,8 +2242,8 @@ NAME is expected to be the 16-bytes part of an ar record." | |||
| 2193 | (if (> (length group) maxgroup) (setq maxgroup (length group))) | 2242 | (if (> (length group) maxgroup) (setq maxgroup (length group))) |
| 2194 | (if (> (length mode) maxmode) (setq maxmode (length mode))) | 2243 | (if (> (length mode) maxmode) (setq maxmode (length mode))) |
| 2195 | (if (> (length size) maxsize) (setq maxsize (length size))) | 2244 | (if (> (length size) maxsize) (setq maxsize (length size))) |
| 2196 | (push (vector extname extname nil mode | 2245 | (push (archive-ar--file-desc extname extname nil mode |
| 2197 | time user group size) | 2246 | time user group size) |
| 2198 | files))) | 2247 | files))) |
| 2199 | (setq files (nreverse files)) | 2248 | (setq files (nreverse files)) |
| 2200 | (goto-char (point-min)) | 2249 | (goto-char (point-min)) |
| @@ -2210,19 +2259,18 @@ NAME is expected to be the 16-bytes part of an ar record." | |||
| 2210 | " Date " "Filename") | 2259 | " Date " "Filename") |
| 2211 | "\n") | 2260 | "\n") |
| 2212 | (insert sep (make-string maxname ?-) "\n") | 2261 | (insert sep (make-string maxname ?-) "\n") |
| 2213 | (archive-summarize-files (mapcar (lambda (desc) | 2262 | (archive-summarize-files |
| 2214 | (let ((text | 2263 | (mapcar (lambda (desc) |
| 2215 | (format format | 2264 | (let ((text |
| 2216 | (aref desc 3) | 2265 | (format format |
| 2217 | (aref desc 5) | 2266 | (archive--file-desc-mode desc) |
| 2218 | (aref desc 6) | 2267 | (archive-ar--file-desc-user desc) |
| 2219 | (aref desc 7) | 2268 | (archive-ar--file-desc-group desc) |
| 2220 | (aref desc 4) | 2269 | (archive-ar--file-desc-size desc) |
| 2221 | (aref desc 1)))) | 2270 | (archive-ar--file-desc-time desc) |
| 2222 | (vector text | 2271 | (archive--file-desc-int-file-name desc)))) |
| 2223 | column | 2272 | (archive--file-summary text column (length text)))) |
| 2224 | (length text)))) | 2273 | files)) |
| 2225 | files)) | ||
| 2226 | (insert sep (make-string maxname ?-) "\n") | 2274 | (insert sep (make-string maxname ?-) "\n") |
| 2227 | (apply #'vector files)))) | 2275 | (apply #'vector files)))) |
| 2228 | 2276 | ||
| @@ -2259,7 +2307,8 @@ NAME is expected to be the 16-bytes part of an ar record." | |||
| 2259 | archive | 2307 | archive |
| 2260 | (let ((d (copy-sequence descr))) | 2308 | (let ((d (copy-sequence descr))) |
| 2261 | ;; FIXME: Crude conversion from string modes to a number. | 2309 | ;; FIXME: Crude conversion from string modes to a number. |
| 2262 | (cl-callf (lambda (s) (if (string-match "x" s) ?\555 ?\444)) (aref d 3)) | 2310 | (cl-callf (lambda (s) (if (string-match "x" s) ?\555 ?\444)) |
| 2311 | (archive--file-desc-mode d)) | ||
| 2263 | d) | 2312 | d) |
| 2264 | '("ar" "r"))) | 2313 | '("ar" "r"))) |
| 2265 | 2314 | ||