diff options
-rw-r--r-- | doc/ref/api-io.texi | 24 | ||||
-rw-r--r-- | libguile/fports.c | 28 | ||||
-rw-r--r-- | module/ice-9/psyntax-pp.scm | 10 | ||||
-rw-r--r-- | module/ice-9/psyntax.scm | 13 | ||||
-rw-r--r-- | test-suite/tests/coding.test | 4 | ||||
-rw-r--r-- | test-suite/tests/ports.test | 5 |
6 files changed, 40 insertions, 44 deletions
diff --git a/doc/ref/api-io.texi b/doc/ref/api-io.texi index 9c3e1fc27..e994cd74b 100644 --- a/doc/ref/api-io.texi +++ b/doc/ref/api-io.texi @@ -885,8 +885,8 @@ Use binary mode, ensuring that each byte in the file will be read as one Scheme character. To provide this property, the file will be opened with the 8-bit -character encoding "ISO-8859-1", ignoring any coding declaration or port -encoding. @xref{Ports}, for more information on port encodings. +character encoding "ISO-8859-1", ignoring the default port encoding. +@xref{Ports}, for more information on port encodings. Note that while it is possible to read and write binary data as characters or strings, it is usually better to treat bytes as octets, @@ -903,12 +903,20 @@ because of its port encoding ramifications. If a file cannot be opened with the access requested, @code{open-file} throws an exception. -When the file is opened, this procedure will scan for a coding -declaration (@pxref{Character Encoding of Source Files}). If a coding -declaration is found, it will be used to interpret the file. Otherwise, -the port's encoding will be used. To suppress this behavior, open the -file in binary mode and then set the port encoding explicitly using -@code{set-port-encoding!}. +When the file is opened, its encoding is set to the current +@code{%default-port-encoding}, unless the @code{b} flag was supplied. +Sometimes it is desirable to honor Emacs-style coding declarations in +files@footnote{Guile 2.0.0 to 2.0.7 would do this by default. This +behavior was deemed inappropriate and disabled starting from Guile +2.0.8.}. When that is the case, the @code{file-encoding} procedure can +be used as follows (@pxref{Character Encoding of Source Files, +@code{file-encoding}}): + +@example +(let* ((port (open-input-file file)) + (encoding (file-encoding port))) + (set-port-encoding! port (or encoding (port-encoding port)))) +@end example In theory we could create read/write ports which were buffered in one direction only. However this isn't included in the diff --git a/libguile/fports.c b/libguile/fports.c index f6c3c92ca..727fe2778 100644 --- a/libguile/fports.c +++ b/libguile/fports.c @@ -349,8 +349,7 @@ SCM_DEFINE (scm_open_file, "open-file", 2, 0, 0, "@item b\n" "Open the underlying file in binary mode, if supported by the system.\n" "Also, open the file using the binary-compatible character encoding\n" - "\"ISO-8859-1\", ignoring the port's encoding and the coding declaration\n" - "at the top of the input file, if any.\n" + "\"ISO-8859-1\", ignoring the default port encoding.\n" "@item +\n" "Open the port for both input and output. E.g., @code{r+}: open\n" "an existing file for both input and output.\n" @@ -365,11 +364,6 @@ SCM_DEFINE (scm_open_file, "open-file", 2, 0, 0, "Add line-buffering to the port. The port output buffer will be\n" "automatically flushed whenever a newline character is written.\n" "@end table\n" - "When the file is opened, this procedure will scan for a coding\n" - "declaration@pxref{Character Encoding of Source Files}. If present\n" - "will use that encoding for interpreting the file. Otherwise, the\n" - "port's encoding will be used.\n" - "\n" "In theory we could create read/write ports which were buffered\n" "in one direction only. However this isn't included in the\n" "current interfaces. If a file cannot be opened with the access\n" @@ -377,7 +371,7 @@ SCM_DEFINE (scm_open_file, "open-file", 2, 0, 0, #define FUNC_NAME s_scm_open_file { SCM port; - int fdes, flags = 0, use_encoding = 1; + int fdes, flags = 0, binary = 0; unsigned int retries; char *file, *md, *ptr; @@ -412,7 +406,7 @@ SCM_DEFINE (scm_open_file, "open-file", 2, 0, 0, flags = (flags & ~(O_RDONLY | O_WRONLY)) | O_RDWR; break; case 'b': - use_encoding = 0; + binary = 1; #if defined (O_BINARY) flags |= O_BINARY; #endif @@ -451,20 +445,8 @@ SCM_DEFINE (scm_open_file, "open-file", 2, 0, 0, port = scm_i_fdes_to_port (fdes, scm_i_mode_bits (mode), fport_canonicalize_filename (filename)); - if (use_encoding) - { - /* If this file has a coding declaration, use that as the port - encoding. */ - if (SCM_INPUT_PORT_P (port)) - { - char *enc = scm_i_scan_for_encoding (port); - if (enc != NULL) - scm_i_set_port_encoding_x (port, enc); - } - } - else - /* If this is a binary file, use the binary-friendly ISO-8859-1 - encoding. */ + if (binary) + /* Use the binary-friendly ISO-8859-1 encoding. */ scm_i_set_port_encoding_x (port, NULL); scm_dynwind_end (); diff --git a/module/ice-9/psyntax-pp.scm b/module/ice-9/psyntax-pp.scm index 8619d78c6..254f7018b 100644 --- a/module/ice-9/psyntax-pp.scm +++ b/module/ice-9/psyntax-pp.scm @@ -2975,10 +2975,12 @@ (lambda (fn dir k) (let ((p (open-input-file (if (absolute-file-name? fn) fn (in-vicinity dir fn))))) - (let f ((x (read p)) (result '())) - (if (eof-object? x) - (begin (close-input-port p) (reverse result)) - (f (read p) (cons (datum->syntax k x) result)))))))) + (let ((enc (file-encoding p))) + (set-port-encoding! p (let ((t enc)) (if t t "UTF-8"))) + (let f ((x (read p)) (result '())) + (if (eof-object? x) + (begin (close-input-port p) (reverse result)) + (f (read p) (cons (datum->syntax k x) result))))))))) (let ((src (syntax-source x))) (let ((file (if src (assq-ref src 'filename) #f))) (let ((dir (if (string? file) (dirname file) #f))) diff --git a/module/ice-9/psyntax.scm b/module/ice-9/psyntax.scm index b359fc1db..d63861c38 100644 --- a/module/ice-9/psyntax.scm +++ b/module/ice-9/psyntax.scm @@ -2945,10 +2945,15 @@ (lambda (x) (define read-file (lambda (fn dir k) - (let ((p (open-input-file - (if (absolute-file-name? fn) - fn - (in-vicinity dir fn))))) + (let* ((p (open-input-file + (if (absolute-file-name? fn) + fn + (in-vicinity dir fn)))) + (enc (file-encoding p))) + + ;; Choose the input encoding deterministically. + (set-port-encoding! p (or enc "UTF-8")) + (let f ((x (read p)) (result '())) (if (eof-object? x) diff --git a/test-suite/tests/coding.test b/test-suite/tests/coding.test index 4152af86a..0a15d93de 100644 --- a/test-suite/tests/coding.test +++ b/test-suite/tests/coding.test @@ -1,6 +1,6 @@ ;;;; coding.test --- test suite for coding declarations. -*- mode: scheme -*- ;;;; -;;;; Copyright (C) 2011 Free Software Foundation, Inc. +;;;; Copyright (C) 2011, 2013 Free Software Foundation, Inc. ;;;; ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public @@ -40,7 +40,7 @@ ;; relies on the opportunistic filling of the input buffer, which ;; doesn't happen after a seek. (let* ((port (open-input-file name)) - (res (port-encoding port))) + (res (file-encoding port))) (close-port port) res)))) diff --git a/test-suite/tests/ports.test b/test-suite/tests/ports.test index 0dbd3b2b9..5d3c213ad 100644 --- a/test-suite/tests/ports.test +++ b/test-suite/tests/ports.test @@ -270,13 +270,12 @@ (delete-file filename) (string=? line2 binary-test-string))))) -;; open-file honors file coding declarations -(pass-if "file: open-file honors coding declarations" +;; open-file ignores file coding declaration +(pass-if "file: open-file ignores coding declarations" (with-fluids ((%default-port-encoding "UTF-8")) (let* ((filename (test-file)) (port (open-output-file filename)) (test-string "€100")) - (set-port-encoding! port "ISO-8859-15") (write-line ";; coding: iso-8859-15" port) (write-line test-string port) (close-port port) |