add csv-num-rows

This commit is contained in:
Alex Shinn 2024-11-08 16:25:13 +09:00
parent f28168a2a6
commit bf7187f324
3 changed files with 53 additions and 3 deletions

View file

@ -77,7 +77,10 @@ Paris,48°5124″N,2°2103″E"))
(latitude "48°5124″N")
(longitude "2°2103″E")))
((csv->sxml 'city '(name latitude longitude))
(open-input-string city-csv))))
(open-input-string city-csv)))
(test 3 (csv-num-rows default-csv-grammar (open-input-string city-csv)))
(test 0 (csv-num-rows default-csv-grammar (open-input-string "")))
(test 1 (csv-num-rows default-csv-grammar (open-input-string "x"))))
(test "1997,Ford,E350\n"
(csv->string '("1997" "Ford" "E350")))
(test "1997,Ford,E350,\"Super, luxurious truck\"\n"

View file

@ -210,6 +210,52 @@
(write-char ch out)
(lp))))))
(define (csv-skip-quoted in grammar)
(let lp ()
(let ((ch (read-char in)))
(cond
((eof-object? ch)
(error "unterminated csv quote"))
((eqv? ch (csv-grammar-quote-char grammar))
(when (and (csv-grammar-quote-doubling-escapes? grammar)
(eqv? ch (peek-char in)))
(read-char in)
(lp)))
((eqv? ch (csv-grammar-escape-char grammar))
(read-char in)
(lp))
(else
(lp))))))
;;> Returns the number of rows in the input.
(define csv-num-rows
(opt-lambda ((grammar default-csv-grammar)
(in (current-input-port)))
(let lp ((num-rows 0))
(let ((ch (read-char in)))
(cond
((eof-object? ch) num-rows)
((eqv? ch (csv-grammar-quote-char grammar))
(csv-skip-quoted in grammar)
(lp num-rows))
((eqv? ch (csv-grammar-record-separator grammar))
(lp (+ num-rows 1)))
((and (eqv? ch #\return)
(memq (csv-grammar-record-separator grammar) '(crlf lax)))
(cond
((eqv? (peek-char in) #\newline)
(read-char in)
(lp (+ num-rows 1)))
((eq? (csv-grammar-record-separator grammar) 'lax)
(lp (+ num-rows 1)))
(else
(lp num-rows))))
((and (eqv? ch #\newline)
(eq? (csv-grammar-record-separator grammar) 'lax))
(lp (+ num-rows 1)))
(else
(lp num-rows)))))))
;;> \section{CSV Readers}
;;> A CSV reader reads a single record, returning some representation

View file

@ -4,7 +4,8 @@
(export csv-grammar csv-parser csv-grammar?
default-csv-grammar default-tsv-grammar
csv-read->list csv-read->vector csv-read->fixed-vector
csv-read->sxml
csv-read->sxml csv-num-rows
csv-fold csv-map csv->list csv-for-each csv->sxml
csv-writer csv-write)
csv-writer csv-write
csv-skip-line)
(include "csv.scm"))