diff options
| author | Richard M. Stallman | 1999-12-25 23:00:57 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1999-12-25 23:00:57 +0000 |
| commit | e073a3561ba285bdbdb8588ebe53c643d6a97d54 (patch) | |
| tree | b3b829037f6756eefcd2006513a5d5d66cb2e21b /lisp | |
| parent | f21b06b7628a1b9e84692064938c0d2694e662a2 (diff) | |
| download | emacs-e073a3561ba285bdbdb8588ebe53c643d6a97d54.tar.gz emacs-e073a3561ba285bdbdb8588ebe53c643d6a97d54.zip | |
(jka-compr-info-file-magic-bytes): New function.
(jka-compr-compression-info-list): Add new elt to each vector.
(jka-compr-write-region): Don't compress the data if it is already compressed.
(jka-compr-really-do-compress): New variable.
(jka-compr-insert-file-contents): Set jka-compr-really-do-compress if visiting.
(jka-compr-write-region): Set jka-compr-really-do-compress
if visiting. Test it when deciding to compress.
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/jka-compr.el | 219 |
1 files changed, 124 insertions, 95 deletions
diff --git a/lisp/jka-compr.el b/lisp/jka-compr.el index 234fb8375d8..a3fae5b05bc 100644 --- a/lisp/jka-compr.el +++ b/lisp/jka-compr.el | |||
| @@ -126,32 +126,32 @@ for `jka-compr-compression-info-list')." | |||
| 126 | ;;[regexp | 126 | ;;[regexp |
| 127 | ;; compr-message compr-prog compr-args | 127 | ;; compr-message compr-prog compr-args |
| 128 | ;; uncomp-message uncomp-prog uncomp-args | 128 | ;; uncomp-message uncomp-prog uncomp-args |
| 129 | ;; can-append auto-mode-flag] | 129 | ;; can-append auto-mode-flag strip-extension-flag file-magic-bytes] |
| 130 | '(["\\.Z\\(~\\|\\.~[0-9]+~\\)?\\'" | 130 | '(["\\.Z\\(~\\|\\.~[0-9]+~\\)?\\'" |
| 131 | "compressing" "compress" ("-c") | 131 | "compressing" "compress" ("-c") |
| 132 | "uncompressing" "uncompress" ("-c") | 132 | "uncompressing" "uncompress" ("-c") |
| 133 | nil t] | 133 | nil t "\037\235"] |
| 134 | ;; Formerly, these had an additional arg "-c", but that fails with | 134 | ;; Formerly, these had an additional arg "-c", but that fails with |
| 135 | ;; "Version 0.1pl2, 29-Aug-97." (RedHat 5.1 GNU/Linux) and | 135 | ;; "Version 0.1pl2, 29-Aug-97." (RedHat 5.1 GNU/Linux) and |
| 136 | ;; "Version 0.9.0b, 9-Sept-98". | 136 | ;; "Version 0.9.0b, 9-Sept-98". |
| 137 | ["\\.bz2\\'" | 137 | ["\\.bz2\\'" |
| 138 | "bzip2ing" "bzip2" nil | 138 | "bzip2ing" "bzip2" nil |
| 139 | "bunzip2ing" "bzip2" ("-d") | 139 | "bunzip2ing" "bzip2" ("-d") |
| 140 | nil t] | 140 | nil t "BZh"] |
| 141 | ["\\.tgz\\'" | 141 | ["\\.tgz\\'" |
| 142 | "zipping" "gzip" ("-c" "-q") | 142 | "zipping" "gzip" ("-c" "-q") |
| 143 | "unzipping" "gzip" ("-c" "-q" "-d") | 143 | "unzipping" "gzip" ("-c" "-q" "-d") |
| 144 | t nil] | 144 | t nil "\037\213"] |
| 145 | ["\\.gz\\(~\\|\\.~[0-9]+~\\)?\\'" | 145 | ["\\.gz\\(~\\|\\.~[0-9]+~\\)?\\'" |
| 146 | "zipping" "gzip" ("-c" "-q") | 146 | "zipping" "gzip" ("-c" "-q") |
| 147 | "unzipping" "gzip" ("-c" "-q" "-d") | 147 | "unzipping" "gzip" ("-c" "-q" "-d") |
| 148 | t t]) | 148 | t t "\037\213"]) |
| 149 | 149 | ||
| 150 | "List of vectors that describe available compression techniques. | 150 | "List of vectors that describe available compression techniques. |
| 151 | Each element, which describes a compression technique, is a vector of | 151 | Each element, which describes a compression technique, is a vector of |
| 152 | the form [REGEXP COMPRESS-MSG COMPRESS-PROGRAM COMPRESS-ARGS | 152 | the form [REGEXP COMPRESS-MSG COMPRESS-PROGRAM COMPRESS-ARGS |
| 153 | UNCOMPRESS-MSG UNCOMPRESS-PROGRAM UNCOMPRESS-ARGS | 153 | UNCOMPRESS-MSG UNCOMPRESS-PROGRAM UNCOMPRESS-ARGS |
| 154 | APPEND-FLAG EXTENSION], where: | 154 | APPEND-FLAG STRIP-EXTENSION-FLAG FILE-MAGIC-CHARS], where: |
| 155 | 155 | ||
| 156 | regexp is a regexp that matches filenames that are | 156 | regexp is a regexp that matches filenames that are |
| 157 | compressed with this format | 157 | compressed with this format |
| @@ -173,9 +173,12 @@ APPEND-FLAG EXTENSION], where: | |||
| 173 | append-flag is non-nil if this compression technique can be | 173 | append-flag is non-nil if this compression technique can be |
| 174 | appended | 174 | appended |
| 175 | 175 | ||
| 176 | auto-mode flag non-nil means strip the regexp from file names | 176 | strip-extension-flag non-nil means strip the regexp from file names |
| 177 | before attempting to set the mode. | 177 | before attempting to set the mode. |
| 178 | 178 | ||
| 179 | file-magic-chars is a string of characters that you would find | ||
| 180 | at the beginning of a file compressed in this way. | ||
| 181 | |||
| 179 | Because of the way `call-process' is defined, discarding the stderr output of | 182 | Because of the way `call-process' is defined, discarding the stderr output of |
| 180 | a program adds the overhead of starting a shell each time the program is | 183 | a program adds the overhead of starting a shell each time the program is |
| 181 | invoked." | 184 | invoked." |
| @@ -204,6 +207,10 @@ invoked." | |||
| 204 | (defvar jka-compr-file-name-handler-entry | 207 | (defvar jka-compr-file-name-handler-entry |
| 205 | nil | 208 | nil |
| 206 | "The entry in `file-name-handler-alist' used by the jka-compr I/O functions.") | 209 | "The entry in `file-name-handler-alist' used by the jka-compr I/O functions.") |
| 210 | |||
| 211 | (defvar jka-compr-really-do-compress nil | ||
| 212 | "Non-nil in a buffer whose visited file was uncompressed on visiting it.") | ||
| 213 | (put 'jka-compr-really-do-compress 'permanent-local t) | ||
| 207 | 214 | ||
| 208 | ;;; Functions for accessing the return value of jka-compr-get-compression-info | 215 | ;;; Functions for accessing the return value of jka-compr-get-compression-info |
| 209 | (defun jka-compr-info-regexp (info) (aref info 0)) | 216 | (defun jka-compr-info-regexp (info) (aref info 0)) |
| @@ -215,6 +222,7 @@ invoked." | |||
| 215 | (defun jka-compr-info-uncompress-args (info) (aref info 6)) | 222 | (defun jka-compr-info-uncompress-args (info) (aref info 6)) |
| 216 | (defun jka-compr-info-can-append (info) (aref info 7)) | 223 | (defun jka-compr-info-can-append (info) (aref info 7)) |
| 217 | (defun jka-compr-info-strip-extension (info) (aref info 8)) | 224 | (defun jka-compr-info-strip-extension (info) (aref info 8)) |
| 225 | (defun jka-compr-info-file-magic-bytes (info) (aref info 9)) | ||
| 218 | 226 | ||
| 219 | 227 | ||
| 220 | (defun jka-compr-get-compression-info (filename) | 228 | (defun jka-compr-get-compression-info (filename) |
| @@ -366,96 +374,116 @@ There should be no more than seven characters after the final `/'." | |||
| 366 | (defun jka-compr-write-region (start end file &optional append visit) | 374 | (defun jka-compr-write-region (start end file &optional append visit) |
| 367 | (let* ((filename (expand-file-name file)) | 375 | (let* ((filename (expand-file-name file)) |
| 368 | (visit-file (if (stringp visit) (expand-file-name visit) filename)) | 376 | (visit-file (if (stringp visit) (expand-file-name visit) filename)) |
| 369 | (info (jka-compr-get-compression-info visit-file))) | 377 | (info (jka-compr-get-compression-info visit-file)) |
| 370 | 378 | (magic (and info (jka-compr-info-file-magic-bytes info)))) | |
| 371 | (if info | 379 | |
| 372 | 380 | ;; If we uncompressed this file when visiting it, | |
| 373 | (let ((can-append (jka-compr-info-can-append info)) | 381 | ;; then recompress it when writing it |
| 374 | (compress-program (jka-compr-info-compress-program info)) | 382 | ;; even if the contents look compressed already. |
| 375 | (compress-message (jka-compr-info-compress-message info)) | 383 | (if (and jka-compr-really-do-compress |
| 376 | (uncompress-program (jka-compr-info-uncompress-program info)) | 384 | (eq start 1) |
| 377 | (uncompress-message (jka-compr-info-uncompress-message info)) | 385 | (eq end (1+ (buffer-size)))) |
| 378 | (compress-args (jka-compr-info-compress-args info)) | 386 | (setq magic nil)) |
| 379 | (uncompress-args (jka-compr-info-uncompress-args info)) | 387 | |
| 380 | (base-name (file-name-nondirectory visit-file)) | 388 | (if (and info |
| 381 | temp-file temp-buffer | 389 | ;; If the contents to be written out |
| 382 | ;; we need to leave `last-coding-system-used' set to its | 390 | ;; are properly compressed already, |
| 383 | ;; value after calling write-region the first time, so | 391 | ;; don't try to compress them over again. |
| 384 | ;; that `basic-save-buffer' sees the right value. | 392 | (not (and magic |
| 385 | (coding-system-used last-coding-system-used)) | 393 | (equal (if (stringp start) |
| 386 | 394 | (substring start 0 (min (length start) | |
| 387 | (setq temp-buffer (get-buffer-create " *jka-compr-wr-temp*")) | 395 | (length magic))) |
| 388 | (with-current-buffer temp-buffer | 396 | (buffer-substring start |
| 389 | (widen) (erase-buffer)) | 397 | (min end |
| 390 | 398 | (+ start (length magic))))) | |
| 391 | (if (and append | 399 | magic)))) |
| 392 | (not can-append) | 400 | (let ((can-append (jka-compr-info-can-append info)) |
| 393 | (file-exists-p filename)) | 401 | (compress-program (jka-compr-info-compress-program info)) |
| 394 | 402 | (compress-message (jka-compr-info-compress-message info)) | |
| 395 | (let* ((local-copy (file-local-copy filename)) | 403 | (uncompress-program (jka-compr-info-uncompress-program info)) |
| 396 | (local-file (or local-copy filename))) | 404 | (uncompress-message (jka-compr-info-uncompress-message info)) |
| 397 | 405 | (compress-args (jka-compr-info-compress-args info)) | |
| 398 | (setq temp-file local-file)) | 406 | (uncompress-args (jka-compr-info-uncompress-args info)) |
| 399 | 407 | (base-name (file-name-nondirectory visit-file)) | |
| 400 | (setq temp-file (jka-compr-make-temp-name))) | 408 | temp-file temp-buffer |
| 401 | 409 | ;; we need to leave `last-coding-system-used' set to its | |
| 402 | (and | 410 | ;; value after calling write-region the first time, so |
| 403 | compress-message | 411 | ;; that `basic-save-buffer' sees the right value. |
| 404 | (message "%s %s..." compress-message base-name)) | 412 | (coding-system-used last-coding-system-used)) |
| 405 | 413 | ||
| 406 | (jka-compr-run-real-handler 'write-region | 414 | (setq temp-buffer (get-buffer-create " *jka-compr-wr-temp*")) |
| 407 | (list start end temp-file t 'dont)) | 415 | (with-current-buffer temp-buffer |
| 408 | ;; save value used by the real write-region | 416 | (widen) (erase-buffer)) |
| 409 | (setq coding-system-used last-coding-system-used) | 417 | |
| 410 | 418 | (if (and append | |
| 411 | ;; Here we must read the output of compress program as is | 419 | (not can-append) |
| 412 | ;; without any code conversion. | 420 | (file-exists-p filename)) |
| 413 | (let ((coding-system-for-read 'no-conversion)) | 421 | |
| 414 | (jka-compr-call-process compress-program | 422 | (let* ((local-copy (file-local-copy filename)) |
| 415 | (concat compress-message | 423 | (local-file (or local-copy filename))) |
| 416 | " " base-name) | 424 | |
| 417 | temp-file | 425 | (setq temp-file local-file)) |
| 418 | temp-buffer | 426 | |
| 419 | nil | 427 | (setq temp-file (jka-compr-make-temp-name))) |
| 420 | compress-args)) | 428 | |
| 421 | 429 | (and | |
| 422 | (with-current-buffer temp-buffer | 430 | compress-message |
| 423 | (let ((coding-system-for-write 'no-conversion)) | 431 | (message "%s %s..." compress-message base-name)) |
| 424 | (if (memq system-type '(ms-dos windows-nt)) | 432 | |
| 425 | (setq buffer-file-type t) ) | 433 | (jka-compr-run-real-handler 'write-region |
| 426 | (jka-compr-run-real-handler 'write-region | 434 | (list start end temp-file t 'dont)) |
| 427 | (list (point-min) (point-max) | 435 | ;; save value used by the real write-region |
| 428 | filename | 436 | (setq coding-system-used last-coding-system-used) |
| 429 | (and append can-append) 'dont)) | 437 | |
| 430 | (erase-buffer)) ) | 438 | ;; Here we must read the output of compress program as is |
| 431 | 439 | ;; without any code conversion. | |
| 432 | (jka-compr-delete-temp-file temp-file) | 440 | (let ((coding-system-for-read 'no-conversion)) |
| 441 | (jka-compr-call-process compress-program | ||
| 442 | (concat compress-message | ||
| 443 | " " base-name) | ||
| 444 | temp-file | ||
| 445 | temp-buffer | ||
| 446 | nil | ||
| 447 | compress-args)) | ||
| 448 | |||
| 449 | (with-current-buffer temp-buffer | ||
| 450 | (let ((coding-system-for-write 'no-conversion)) | ||
| 451 | (if (memq system-type '(ms-dos windows-nt)) | ||
| 452 | (setq buffer-file-type t) ) | ||
| 453 | (jka-compr-run-real-handler 'write-region | ||
| 454 | (list (point-min) (point-max) | ||
| 455 | filename | ||
| 456 | (and append can-append) 'dont)) | ||
| 457 | (erase-buffer)) ) | ||
| 458 | |||
| 459 | (jka-compr-delete-temp-file temp-file) | ||
| 433 | 460 | ||
| 434 | (and | 461 | (and |
| 435 | compress-message | 462 | compress-message |
| 436 | (message "%s %s...done" compress-message base-name)) | 463 | (message "%s %s...done" compress-message base-name)) |
| 437 | 464 | ||
| 438 | (cond | 465 | (cond |
| 439 | ((eq visit t) | 466 | ((eq visit t) |
| 440 | (setq buffer-file-name filename) | 467 | (setq buffer-file-name filename) |
| 441 | (set-visited-file-modtime)) | 468 | (setq jka-compr-really-do-compress t) |
| 442 | ((stringp visit) | 469 | (set-visited-file-modtime)) |
| 443 | (setq buffer-file-name visit) | 470 | ((stringp visit) |
| 444 | (let ((buffer-file-name filename)) | 471 | (setq buffer-file-name visit) |
| 445 | (set-visited-file-modtime)))) | 472 | (let ((buffer-file-name filename)) |
| 446 | 473 | (set-visited-file-modtime)))) | |
| 447 | (and (or (eq visit t) | 474 | |
| 448 | (eq visit nil) | 475 | (and (or (eq visit t) |
| 449 | (stringp visit)) | 476 | (eq visit nil) |
| 450 | (message "Wrote %s" visit-file)) | 477 | (stringp visit)) |
| 451 | 478 | (message "Wrote %s" visit-file)) | |
| 452 | ;; ensure `last-coding-system-used' has an appropriate value | 479 | |
| 453 | (setq last-coding-system-used coding-system-used) | 480 | ;; ensure `last-coding-system-used' has an appropriate value |
| 454 | 481 | (setq last-coding-system-used coding-system-used) | |
| 455 | nil) | 482 | |
| 483 | nil) | ||
| 456 | 484 | ||
| 457 | (jka-compr-run-real-handler 'write-region | 485 | (jka-compr-run-real-handler 'write-region |
| 458 | (list start end filename append visit))))) | 486 | (list start end filename append visit))))) |
| 459 | 487 | ||
| 460 | 488 | ||
| 461 | (defun jka-compr-insert-file-contents (file &optional visit beg end replace) | 489 | (defun jka-compr-insert-file-contents (file &optional visit beg end replace) |
| @@ -562,6 +590,7 @@ There should be no more than seven characters after the final `/'." | |||
| 562 | (progn | 590 | (progn |
| 563 | (unlock-buffer) | 591 | (unlock-buffer) |
| 564 | (setq buffer-file-name filename) | 592 | (setq buffer-file-name filename) |
| 593 | (setq jka-compr-really-do-compress t) | ||
| 565 | (set-visited-file-modtime))) | 594 | (set-visited-file-modtime))) |
| 566 | 595 | ||
| 567 | (and | 596 | (and |