Skip to content

Commit

Permalink
add csv-num-rows
Browse files Browse the repository at this point in the history
  • Loading branch information
ashinn committed Nov 8, 2024
1 parent f28168a commit bf7187f
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 3 deletions.
5 changes: 4 additions & 1 deletion lib/chibi/csv-test.sld
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,10 @@ Paris,48°51′24″N,2°21′03″E"))
(latitude "48°51′24″N")
(longitude "2°21′03″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"
Expand Down
46 changes: 46 additions & 0 deletions lib/chibi/csv.scm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 3 additions & 2 deletions lib/chibi/csv.sld
Original file line number Diff line number Diff line change
Expand Up @@ -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"))

0 comments on commit bf7187f

Please sign in to comment.