chicken-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Chicken-users] read-lines bug and a suggested bug fix


From: Tony Sidaway
Subject: [Chicken-users] read-lines bug and a suggested bug fix
Date: Tue, 30 Jan 2007 17:04:20 +0000

(read-lines [port [MAX]]) is supposed to read up to MAX lines from the port.

Here's an oddity:

$ cat test-read-lines.scm
(define lines-per-read 5)
(let loop ((lst (read-lines (current-input-port) lines-per-read)))
 (if (null? lst)
     '()
     (begin
       (map (lambda (x)(display x)(newline)) lst)
       (loop (read-lines (current-input-port) lines-per-read)))))

$ cat test-read-lines.input
Line 1
Line 2
Line 3
Line 4
Line 5
Line 6
Line 7
Line 8
Line 9
Line 10
(etc)

$ csc test-read-lines.scm
$  ./test-read-lines <test-read-lines.input >test-read-lines.output
$ diff test-read-lines.input test-read-lines.output
6d5
< Line 6
12d10
< Line 12
18d15
< Line 18
24d20
< Line 24
30d25
< Line 30

Thus (read-lines) appears to silently consume the line following the
final successful read.

Let's look at the definition of (read-lines).  It's in extras.scm.

There's some mucking about to read the parameters and whatnot, but the
core of the procedure is this:

       (define (doread port)
         (do ([ln (read-line port) (read-line port)]
              [lns '() (cons ln lns)]
              [n (or max 1000000) (fx- n 1)] )
             ((or (eof-object? ln) (eq? n 0)) (reverse lns)) ) )

The body of the iteration is as follows:
 Evaluate to #f unless ln is the eof object or n is 0.
 Evaluate to the reverse of lns if ln is the eof object of n is 0.

The problem appears to be that if n is 0 and ln (which is bound to the
value of (read-line port)) is not the eof-object, its value is
discarded.

To fix this bug, the case where n is 0 and lns is not the eof-object
could be treated  separately by evaluating (reverse (cons ln lns))
instead of (reverse lns) in that case.

Thus I suggest that the last line of the procedure  (doread) above
could be replaced by:

           ((if (eof-object? ln) (reverse lns)(or (eq? n 0)(reverse
(cons ln lns)))))




reply via email to

[Prev in Thread] Current Thread [Next in Thread]