Length-limited line reading
This commit is contained in:
parent
0b60d73f64
commit
3ffa667e89
|
@ -0,0 +1,26 @@
|
||||||
|
#lang racket/base
|
||||||
|
|
||||||
|
(provide read-line-limited)
|
||||||
|
|
||||||
|
;; Uses Internet (CRLF) convention.
|
||||||
|
(define (read-line-limited port limit)
|
||||||
|
(let collect-chars ((acc '())
|
||||||
|
(remaining limit))
|
||||||
|
(let ((ch (read-char port)))
|
||||||
|
(cond
|
||||||
|
((eof-object? ch) (if (null? acc)
|
||||||
|
ch
|
||||||
|
(list->string (reverse acc))))
|
||||||
|
((eqv? ch #\return) (let ((ch (read-char port)))
|
||||||
|
(if (eqv? ch #\linefeed)
|
||||||
|
(list->string (reverse acc))
|
||||||
|
(error 'read-line-limited
|
||||||
|
"Invalid character ~v after #\\return"
|
||||||
|
ch))))
|
||||||
|
((eqv? ch #\newline)
|
||||||
|
;; Is this a good idea?
|
||||||
|
(error 'read-line-limited "Bare #\\linefeed encountered"))
|
||||||
|
((positive? remaining) (collect-chars (cons ch acc) (- remaining 1)))
|
||||||
|
(else (error 'read-line-limited
|
||||||
|
"Line too long (more than ~v bytes before CRLF)"
|
||||||
|
limit))))))
|
|
@ -0,0 +1,23 @@
|
||||||
|
#lang racket/base
|
||||||
|
|
||||||
|
(require "safe-io.rkt")
|
||||||
|
(require rackunit)
|
||||||
|
|
||||||
|
(define (s str)
|
||||||
|
(open-input-string str))
|
||||||
|
|
||||||
|
(check-equal? (read-line-limited (s "") 5) eof)
|
||||||
|
(check-equal? (read-line-limited (s "abc") 5) "abc")
|
||||||
|
(check-equal? (read-line-limited (s "abc\r\ndef") 5) "abc")
|
||||||
|
(check-equal? (read-line-limited (s "abcxy\r\ndef") 5) "abcxy")
|
||||||
|
|
||||||
|
(check-exn #rx"read-line-limited: Invalid character #<eof> after #\\\\return"
|
||||||
|
(lambda () (read-line-limited (s "abc\r") 5)))
|
||||||
|
(check-exn #rx"read-line-limited: Invalid character #\\\\d after #\\\\return"
|
||||||
|
(lambda () (read-line-limited (s "abc\rdef") 5)))
|
||||||
|
|
||||||
|
(check-exn #rx"Bare #\\\\linefeed encountered"
|
||||||
|
(lambda () (read-line-limited (s "abc\ndef") 5)))
|
||||||
|
|
||||||
|
(check-exn #rx"Line too long \\(more than 5 bytes before CRLF\\)"
|
||||||
|
(lambda () (read-line-limited (s "abcxyz\r\ndef") 5)))
|
Loading…
Reference in New Issue