Changes dealing with encoded files:
authorChris Hanson <org/chris-hanson/cph>
Wed, 13 Sep 1995 23:01:05 +0000 (23:01 +0000)
committerChris Hanson <org/chris-hanson/cph>
Wed, 13 Sep 1995 23:01:05 +0000 (23:01 +0000)
1. Appending to an encoded file works by reading the file into a
   temporary buffer, appending the text, and writing it back out.

2. Line translation is handled for encoded files the same way it is
   for unencoded files.

3. Doing I/O to non-encoded files, if the file doesn't exist, an
   encoded file is used in its place if available.

v7/src/edwin/dos.scm
v7/src/edwin/filcom.scm
v7/src/edwin/fileio.scm
v7/src/edwin/os2.scm
v7/src/edwin/process.scm
v7/src/edwin/unix.scm

index d0c574dc02c32427f88e90c46556601f8b13c87b..ca1ffc8080205cd90066fa17e88846aa4800b1be 100644 (file)
@@ -1,6 +1,6 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Id: dos.scm,v 1.26 1995/07/11 23:10:41 cph Exp $
+;;;    $Id: dos.scm,v 1.27 1995/09/13 23:00:53 cph Exp $
 ;;;
 ;;;    Copyright (c) 1992-95 Massachusetts Institute of Technology
 ;;;
@@ -319,8 +319,8 @@ Includes the new backup.  Must be > 0."
             pathname))))
 
 (define (os/read-file-methods) '())
-
 (define (os/write-file-methods) '())
+(define (os/alternate-pathnames group pathname) group pathname '())
 \f
 ;;;; Dired customization
 
index 3d54f4d23da245b30054f7a9a5eee34a3df3c006..af5dc97c4c5790c78800b761c2d2924c4ed98822 100644 (file)
@@ -1,6 +1,6 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Id: filcom.scm,v 1.186 1995/07/11 23:19:30 cph Exp $
+;;;    $Id: filcom.scm,v 1.187 1995/09/13 23:00:55 cph Exp $
 ;;;
 ;;;    Copyright (c) 1986, 1989-95 Massachusetts Institute of Technology
 ;;;
@@ -131,10 +131,17 @@ invocation."
                            (ref-variable find-file-not-found-hooks buffer)
                            (cdr hooks)))
                          ((or (null? hooks)
-                              ((car hooks) buffer)))))
+                              ((car hooks) buffer))))
+                     (maybe-change-buffer-name! buffer pathname))
                  (after-find-file buffer error? warn?))
                buffer))))))
 
+(define (maybe-change-buffer-name! buffer pathname)
+  (let ((name (pathname->buffer-name pathname))
+       (name* (pathname->buffer-name (buffer-pathname buffer))))
+    (if (not (string=? name name*))
+       (rename-buffer buffer (new-buffer-name name*)))))
+
 (define (after-find-file buffer error? warn?)
   (let ((pathname (or (buffer-truename buffer) (buffer-pathname buffer))))
     (let ((buffer-read-only?
index 551ced68c9bdc6ecfeb097c000db1a66cc4d40d5..76639092cbe78ce5a6bef1bf6a46525b27809c2e 100644 (file)
@@ -1,6 +1,6 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Id: fileio.scm,v 1.128 1995/09/13 03:57:14 cph Exp $
+;;;    $Id: fileio.scm,v 1.129 1995/09/13 23:00:58 cph Exp $
 ;;;
 ;;;    Copyright (c) 1986, 1989-95 Massachusetts Institute of Technology
 ;;;
 
 (declare (usual-integrations))
 \f
+;;;; Special File I/O Methods
+
+(define (r/w-file-methods? objects)
+  (and (list? objects)
+       (for-all? objects
+        (lambda (object)
+          (and (pair? object)
+               (procedure? (car object))
+               (procedure? (cdr object)))))))
+
+(define-variable read-file-methods
+  "List of alternate methods to be used for reading a file into a buffer.
+Each method is a pair of a predicate and a procedure.  The methods are
+tried, in order, until one of the predicates is satisfied, at which
+point the corresponding procedure is used to read the file.  If none
+of the predicates is satisfied, the file is read in the usual way."
+  (os/read-file-methods)
+  r/w-file-methods?)
+
+(define-variable write-file-methods
+  "List of alternate methods to be used for writing a file into a buffer.
+Each method is a pair of a predicate and a procedure.  The methods are
+tried, in order, until one of the predicates is satisfied, at which
+point the corresponding procedure is used to write the file.  If none
+of the predicates is satisfied, the file is written in the usual way."
+  (os/write-file-methods)
+  r/w-file-methods?)
+
+(define (read-file-method group pathname)
+  (let loop ((methods (ref-variable read-file-methods group)))
+    (and (not (null? methods))
+        (if ((caar methods) group pathname)
+            (cdar methods)
+            (loop (cdr methods))))))
+
+(define (write-file-method group pathname)
+  (let loop ((methods (ref-variable write-file-methods group)))
+    (and (not (null? methods))
+        (if ((caar methods) group pathname)
+            (cdar methods)
+            (loop (cdr methods))))))
+
+(define (get-pathname-or-alternate group pathname)
+  (if (file-exists? pathname)
+      pathname
+      (let loop ((alternates (os/alternate-pathnames group pathname)))
+       (cond ((null? alternates)
+              pathname)
+             ((file-exists? (car alternates))
+              (car alternates))
+             (else
+              (loop (cdr alternates)))))))
+\f
 ;;;; Input
 
 (define (read-buffer buffer pathname visit?)
   (set-buffer-writable! buffer)
   (let ((truename false)
-       (file-error false))
+       (file-error false)
+       (group (buffer-group buffer)))
     ;; Set modified so that file supercession check isn't done.
-    (set-group-modified?! (buffer-group buffer) true)
+    (set-group-modified?! group true)
     (region-delete! (buffer-unclipped-region buffer))
+    (set! pathname (get-pathname-or-alternate group pathname))
     (call-with-current-continuation
      (lambda (continuation)
        (bind-condition-handler (list condition-type:file-error)
             (continuation unspecific))
         (lambda ()
           (set! truename (->truename pathname))
-          (if truename
-              (begin
-                (%insert-file (buffer-start buffer) truename visit?)
-                (if visit?
-                    (set-buffer-modification-time!
-                     buffer
-                     (file-modification-time truename)))))))))
+          (%insert-file (buffer-start buffer) truename visit?)
+          (if visit?
+              (set-buffer-modification-time!
+               buffer
+               (file-modification-time truename)))))))
     (set-buffer-point! buffer (buffer-start buffer))
     (if visit?
        (begin
         condition
         (editor-error "File " (->namestring filename) " not found"))
      (lambda ()
-       (->truename filename)))
+       (->truename (get-pathname-or-alternate (mark-group mark) filename))))
    false))
 \f
 (define-variable read-file-message
   false
   boolean?)
 
-(define-variable read-file-methods
-  "List of procedures to be called before reading a file into a buffer.
-The procedures are called in order; if one of them returns true the file
-is considered already read and the rest are not called.
-Each procedure is called with three arguments:
- the pathname of the file to be read,
- the mark at which the file's contents should be inserted, and
- a flag that is true iff the buffer being filled is visiting the file."
-  (os/read-file-methods)
-  list?)
-
 (define-variable translate-file-data-on-input
   "If true (the default), end-of-line translation is done on file input."
   #t
@@ -118,13 +160,12 @@ Each procedure is called with three arguments:
 (define (%insert-file mark truename visit?)
   (let ((do-it
         (lambda ()
-          (let loop ((methods (ref-variable read-file-methods mark)))
-            (cond ((null? methods)
-                   (group-insert-file! (mark-group mark)
-                                       (mark-index mark)
-                                       truename))
-                  ((not ((car methods) truename mark visit?))
-                   (loop (cdr methods))))))))
+          (let ((method (read-file-method (mark-group mark) truename)))
+            (if method
+                (method truename mark visit?)
+                (group-insert-file! (mark-group mark)
+                                    (mark-index mark)
+                                    truename))))))
     (if (ref-variable read-file-message)
        (let ((msg
               (string-append "Reading file \""
@@ -406,17 +447,6 @@ and the rest are not called."
   '()
   list?)
 
-(define-variable write-file-methods
-  "List of procedures to be called before writing a region to a file.
-The procedures are called in order; if one of them returns true the file
-is considered already written and the rest are not called.
-Each procedure is called with three arguments:
- the region that should be written to the file,
- the pathname of the file to be written, and
- a flag that is true iff the buffer being written is visiting the file."
-  (os/write-file-methods)
-  list?)
-
 (define-variable enable-emacs-write-file-message
   "If true, generate Emacs-style message when writing files.
 Otherwise, a message is written both before and after long file writes."
@@ -525,42 +555,62 @@ Otherwise, a message is written both before and after long file writes."
   (write-region* region pathname message? true))
 
 (define (write-region* region pathname message? append?)
-  (let ((translation
-        (and (ref-variable translate-file-data-on-output
-                           (region-group region))
-             (pathname-newline-translation pathname)))
-       (filename (->namestring pathname))
-       (group (region-group region))
+  (let ((group (region-group region))
        (start (region-start-index region))
-       (end (region-end-index region)))
-    (let ((do-it
-          (if append?
-              (lambda ()
-                (group-append-to-file translation group start end filename))
-              (lambda ()
-                (let ((visit? (eq? 'VISIT message?)))
-                  (let loop
-                      ((methods (ref-variable write-file-methods group)))
-                    (cond ((null? methods)
-                           (group-write-to-file translation group start end
-                                                filename))
-                          ((not ((car methods) region pathname visit?))
-                           (loop (cdr methods))))))))))
-      (cond ((not message?)
-            (do-it))
-           ((or (ref-variable enable-emacs-write-file-message)
-                (<= (- end start) 50000))
-            (do-it)
-            (message "Wrote " filename))
-           (else
-            (let ((msg (string-append "Writing file " filename "...")))
-              (message msg)
+       (end (region-end-index region))
+       (pathname (get-pathname-or-alternate (region-group region) pathname)))
+    (let ((translation
+          (and (ref-variable translate-file-data-on-output group)
+               (pathname-newline-translation pathname)))
+         (filename (->namestring pathname)))
+      (let ((do-it
+            (let ((method (write-file-method group pathname)))
+              (if append?
+                  (lambda ()
+                    (if method
+                        (let ((rmethod (read-file-method group pathname)))
+                          (if (not rmethod)
+                              (error "Can't append: no read method:"
+                                     pathname))
+                          (call-with-temporary-buffer " append region"
+                            (lambda (buffer)
+                              (let ((vcopy
+                                     (lambda (v)
+                                       (define-variable-local-value! buffer v
+                                         (variable-local-value group v)))))
+                                (vcopy
+                                 (ref-variable-object
+                                  translate-file-data-on-input))
+                                (vcopy
+                                 (ref-variable-object
+                                  translate-file-data-on-output)))
+                              (rmethod pathname (buffer-start buffer) #f)
+                              (insert-region (region-start region)
+                                             (region-end region)
+                                             (buffer-end buffer))
+                              (method (buffer-region buffer) pathname #f))))
+                        (group-append-to-file translation group start end
+                                              filename)))
+                  (lambda ()
+                    (if method
+                        (method region pathname (eq? 'VISIT message?))
+                        (group-write-to-file translation group start end
+                                             filename)))))))
+       (cond ((not message?)
+              (do-it))
+             ((or (ref-variable enable-emacs-write-file-message)
+                  (<= (- end start) 50000))
               (do-it)
-              (message msg "done")))))
-    ;; This isn't the correct truename on systems that support version
-    ;; numbers.  For those systems, the truename must be supplied by
-    ;; the operating system after the channel is closed.
-    filename))
+              (message "Wrote " filename))
+             (else
+              (let ((msg (string-append "Writing file " filename "...")))
+                (message msg)
+                (do-it)
+                (message msg "done")))))
+      ;; This isn't the correct truename on systems that support version
+      ;; numbers.  For those systems, the truename must be supplied by
+      ;; the operating system after the channel is closed.
+      filename)))
 \f
 (define (group-write-to-file translation group start end filename)
   (let ((channel (file-open-output-channel filename)))
index 1e0ae6b07ce61d1f0d84b5ad1f285b65394ece72..51ae729386a9022eecab726f30f0810c801f0b79 100644 (file)
@@ -1,6 +1,6 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Id: os2.scm,v 1.20 1995/07/24 22:08:39 cph Exp $
+;;;    $Id: os2.scm,v 1.21 1995/09/13 23:01:01 cph Exp $
 ;;;
 ;;;    Copyright (c) 1994-95 Massachusetts Institute of Technology
 ;;;
@@ -620,9 +620,24 @@ Includes the new backup.  Must be > 0."
 \f
 ;;;; Compressed Files
 
-(define (os/read-file-methods) (list maybe-read-compressed-file))
-
-(define (os/write-file-methods) (list maybe-write-compressed-file))
+(define (os/read-file-methods)
+  `((,read/write-compressed-file?
+     . ,(lambda (pathname mark visit?)
+         visit?
+         (read-compressed-file "gzip -d" pathname mark)))))
+
+(define (os/write-file-methods)
+  `((,read/write-compressed-file?
+     . ,(lambda (region pathname visit?)
+         visit?
+         (write-compressed-file "gzip" region pathname)))))
+
+(define (os/alternate-pathnames group pathname)
+  (if (and (ref-variable enable-compressed-files group)
+          (os2/fs-long-filenames? pathname)
+          (not (equal? "gz" (pathname-type pathname))))
+      (list (string-append (->namestring pathname) ".gz"))
+      '()))
 
 (define-variable enable-compressed-files
   "If true, compressed files are automatically uncompressed when read,
@@ -631,13 +646,9 @@ filename suffix \".gz\"."
   #t
   boolean?)
 
-(define (maybe-read-compressed-file pathname mark visit?)
-  visit?
-  (and (ref-variable enable-compressed-files mark)
-       (equal? "gz" (pathname-type pathname))
-       (begin
-        (read-compressed-file "gzip -d" pathname mark)
-        #t)))
+(define (read/write-compressed-file? group pathname)
+  (and (ref-variable enable-compressed-files group)
+       (equal? "gz" (pathname-type pathname))))
 
 (define (read-compressed-file program pathname mark)
   (let ((do-it
@@ -666,14 +677,6 @@ filename suffix \".gz\"."
          (do-it)
          (append-message "done")))))
 
-(define (maybe-write-compressed-file region pathname visit?)
-  visit?
-  (and (ref-variable enable-compressed-files (region-start region))
-       (equal? "gz" (pathname-type pathname))
-       (begin
-        (write-compressed-file "gzip" region pathname)
-        #t)))
-
 (define (write-compressed-file program region pathname)
   (if (not (equal? '(EXITED . 0)
                   (shell-command region
index 8112c28314cbcd197f09eb8032c3c7ab826cf055..b5719feaaa26c2ee5ae4cf88a5e4d2639dc0c68e 100644 (file)
@@ -1,6 +1,6 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Id: process.scm,v 1.37 1995/04/10 16:50:04 cph Exp $
+;;;    $Id: process.scm,v 1.38 1995/09/13 23:01:03 cph Exp $
 ;;;
 ;;;    Copyright (c) 1991-95 Massachusetts Institute of Technology
 ;;;
@@ -581,6 +581,19 @@ after the listing is made.)"
          (cons status reason))))))
 \f
 (define (synchronous-process-wait process input-region output-mark)
+  ;; Initialize the subprocess line-translation appropriately.
+  ;; Buffers that disable translation should have it disabled for
+  ;; subprocess I/O as well as normal file I/O, since subprocesses are
+  ;; used for reading and writing compressed files and such.
+  (subprocess-i/o-port process
+                      (and (or (not output-mark)
+                               (ref-variable translate-file-data-on-input
+                                             output-mark))
+                           'DEFAULT)
+                      (and (or (not input-region)
+                               (ref-variable translate-file-data-on-output
+                                             (region-start input-region)))
+                           'DEFAULT))
   (if input-region
       (call-with-protected-continuation
        (lambda (continuation)
index 4d893c8046725a217869e8a97cc348fe59cdbd14..e012b6ac3787bc2caced35682ed4c95aab737172 100644 (file)
@@ -1,6 +1,6 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Id: unix.scm,v 1.52 1995/07/11 23:10:49 cph Exp $
+;;;    $Id: unix.scm,v 1.53 1995/09/13 23:01:05 cph Exp $
 ;;;
 ;;;    Copyright (c) 1989-95 Massachusetts Institute of Technology
 ;;;
@@ -371,12 +371,43 @@ Includes the new backup.  Must be > 0."
        (string-find-next-char filename #\#)))
 
 (define (os/read-file-methods)
-  (list maybe-read-compressed-file
-       maybe-read-encrypted-file))
+  `((,read/write-compressed-file?
+     . ,(lambda (pathname mark visit?)
+         visit?
+         (let ((type (pathname-type pathname)))
+           (cond ((equal? "gz" type)
+                  (read-compressed-file "gzip -d" pathname mark))
+                 ((equal? "Z" type)
+                  (read-compressed-file "uncompress" pathname mark))))))
+    (,read/write-encrypted-file?
+     . ,(lambda (pathname mark visit?)
+         visit?
+         (read-encrypted-file pathname mark)))))
 
 (define (os/write-file-methods)
-  (list maybe-write-compressed-file
-       maybe-write-encrypted-file))
+  `((,read/write-compressed-file?
+     . ,(lambda (region pathname visit?)
+         visit?
+         (let ((type (pathname-type pathname)))
+           (cond ((equal? "gz" type)
+                  (write-compressed-file "gzip" region pathname))
+                 ((equal? "Z" type)
+                  (write-compressed-file "compress" region pathname))))))
+    (,read/write-encrypted-file?
+     . ,(lambda (region pathname visit?)
+         visit?
+         (write-encrypted-file region pathname)))))
+
+(define (os/alternate-pathnames group pathname)
+  (let ((filename (->namestring pathname)))
+    `(,@(if (ref-variable enable-compressed-files group)
+           (map (lambda (suffix) (string-append filename "." suffix))
+                unix/compressed-file-suffixes)
+           '())
+      ,@(if (ref-variable enable-encrypted-files group)
+           (map (lambda (suffix) (string-append filename "." suffix))
+                unix/encrypted-file-suffixes)
+           '()))))
 \f
 ;;;; Compressed Files
 
@@ -387,27 +418,21 @@ of the filename suffixes \".gz\" or \".Z\"."
   true
   boolean?)
 
-(define (maybe-read-compressed-file pathname mark visit?)
-  visit?
-  (and (ref-variable enable-compressed-files mark)
-       (let ((type (pathname-type pathname)))
-        (cond ((equal? "gz" type)
-               (read-compressed-file "gunzip" pathname mark)
-               #t)
-              ((equal? "Z" type)
-               (read-compressed-file "uncompress" pathname mark)
-               #t)
-              (else
-               #f)))))
+(define (read/write-compressed-file? group pathname)
+  (and (ref-variable enable-compressed-files group)
+       (member (pathname-type pathname) unix/compressed-file-suffixes)))
+
+(define unix/compressed-file-suffixes
+  '("gz" "Z"))
 
 (define (read-compressed-file program pathname mark)
   (let ((do-it
         (lambda ()
           (if (not (equal? '(EXITED . 0)
-                           (shell-command false
+                           (shell-command #f
                                           mark
                                           (directory-pathname pathname)
-                                          false
+                                          #f
                                           (string-append
                                            program
                                            " < "
@@ -427,25 +452,12 @@ of the filename suffixes \".gz\" or \".Z\"."
          (do-it)
          (append-message "done")))))
 
-(define (maybe-write-compressed-file region pathname visit?)
-  visit?
-  (and (ref-variable enable-compressed-files (region-start region))
-       (let ((type (pathname-type pathname)))
-        (cond ((equal? "gz" type)
-               (write-compressed-file "gzip" region pathname)
-               #t)
-              ((equal? "Z" type)
-               (write-compressed-file "compress" region pathname)
-               #t)
-              (else
-               #f)))))
-
 (define (write-compressed-file program region pathname)
   (if (not (equal? '(EXITED . 0)
                   (shell-command region
-                                 false
+                                 #f
                                  (directory-pathname pathname)
-                                 false
+                                 #f
                                  (string-append program
                                                 " > "
                                                 (file-namestring pathname)))))
@@ -465,13 +477,12 @@ filename suffix \".KY\"."
   true
   boolean?)
 
-(define (maybe-read-encrypted-file pathname mark visit?)
-  visit?
-  (and (ref-variable enable-encrypted-files mark)
-       (equal? "KY" (pathname-type pathname))
-       (begin
-        (read-encrypted-file pathname mark)
-        true)))
+(define (read/write-encrypted-file? group pathname)
+  (and (ref-variable enable-encrypted-files group)
+       (member (pathname-type pathname) unix/encrypted-file-suffixes)))
+
+(define unix/encrypted-file-suffixes
+  '("KY"))
 
 (define (read-encrypted-file pathname mark)
   (let ((the-encrypted-file
@@ -497,14 +508,6 @@ filename suffix \".KY\"."
        (ref-variable-object auto-save-default)
       #f)))
 
-(define (maybe-write-encrypted-file region pathname visit?)
-  visit?
-  (and (ref-variable enable-encrypted-files (region-start region))
-       (equal? "KY" (pathname-type pathname))
-       (begin
-        (write-encrypted-file region pathname)
-        true)))
-
 (define (write-encrypted-file region pathname)
   (let* ((password 
          (prompt-for-confirmed-password))