0
votes

Using guile 1.8 or guile 2, the following code reads past EOF, seemingly for a few extra lines, then stops. The effect this has in the larger program of which this is an extract is to seemingly corrupt the previously read data. Am I using read-line or testing for eof-object incorrectly?

(use-modules (ice-9 rdelim))

(define f
  (lambda (p)
    (let loop ((line (read-line p)))
      (format #t "line: ~a\n" line)
      (if (not (eof-object? (peek-char p)))
      (begin
        (let ((m (string-match "^[ \t]*#" line)))
          (if m
          (begin
              (format #t "comment: ~a\n" (match:string m))
              (loop (read-line p))
            )))
        (format #t "read next line\n")
        (loop (read-line p)))))))

(define main
  (lambda ()
    (let ((h (open-input-file "test")))
      (f h))))

Here is a minimal sample dummy input file:

1
2
3
# comment line
4
5
1
2
3
# comment line
4
5
1
2
3
# comment line
4
5

It needs to be more than a few lines long for the problem to manifest. Apologies for the length of the code example, but the issue only arises when the code gets to this amount of complexity (albeit small).

1
The main problem seems to be the fact that you're reading two lines per iteration when you find a comment, see my answer for a different way to structure the solution. - Óscar López

1 Answers

3
votes

I suggest a rewrite of the procedure, it doesn't seem the correct way to read a file and loop over its lines. Please try this one:

(define (f)
  (let loop ((line (read-line)))
    (if (not (eof-object? line))
        (begin
          (format #t "line: ~a\n" line)
          (let ((m (string-match "^[ \t]*#" line)))
            (if m (format #t "comment: ~a\n" line)))
          (format #t "read next line\n")
          (loop (read-line))))))

(define (main)
  (with-input-from-file "test" f))

With your sample input, calling (main) prints on the console the following output, which hopefully is what you expected:

line: 1
read next line
line: 2
read next line
line: 3
read next line
line: # comment line
comment: # comment line
read next line
line: 4
read next line
line: 5
read next line
line: 1
read next line
line: 2
read next line
line: 3
read next line
line: # comment line
comment: # comment line
read next line
line: 4
read next line
line: 5
read next line
line: 1
read next line
line: 2
read next line
line: 3
read next line
line: # comment line
comment: # comment line
read next line
line: 4
read next line
line: 5
read next line