larcenists / larceny

Larceny Scheme implementation
Other
202 stars 32 forks source link

Question: will read-line handle "\r\n" and "\r"? #748

Closed ghost closed 8 years ago

ghost commented 8 years ago

This is a simple test (using Larceny v0.98):

(import (scheme base)
        (scheme file)
        (scheme write))

(when (file-exists? "test.txt")
  (delete-file "test.txt"))

(define out (open-output-file "test.txt"))
(display "abc\r\ndef" out)
(close-output-port out)

(define in (open-input-file "test.txt"))
(write (read-line in)) (newline)
(write (read-line in)) (newline)
(close-input-port in)

(delete-file "test.txt")

Run larceny -r7rs -program test.ss, it prints:

"abc\r"
"def"

If change (display "abc\r\ndef" out) to (display "abc\rdef" out), it prints:

"abc\rdef"
#<EOF>

The R7RS says:

For the purpose of this procedure, an end of line consists of either a linefeed character, a carriage return character, or a sequence of a carriage return character followed by a linefeed character.

Will Larceny follow this definition?

WillClinger commented 8 years ago

You have discovered an ambiguity in the R7RS specification of read-line. There are three things that count as an end of line:

  1. a linefeed character
  2. a carriage return character
  3. a sequence of carriage return characters followed by a linefeed character

According to item 2, implementations of the R7RS are supposed to behave as follows:

> (define p (open-input-string "abc\r\r\rdef\n"))
> (read-line p)
"abc"
> (read-line p)
""
> (read-line p)
""
> (read-line p)
"def"

According to item 3, however, an implementation of R7RS might choose instead to behave as

> (define p (open-input-string "abc\r\r\rdef\n"))
> (read-line p)
"abc"
> (read-line p)
"def"

Larceny v0.98 doesn't behave in either of those ways, so Larceny v0.98 is incorrect.

Larceny will indeed be changed to implement one of the behaviors allowed by the R7RS. I haven't yet decided which behavior Larceny will implement.

WillClinger commented 8 years ago

Fixed by changeset 6f0ce4455c48bb2b346cd750203146714f2c0ec9