summaryrefslogtreecommitdiffstats
path: root/stdlib
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2025-01-21 07:33:39 -0800
committerKaz Kylheku <kaz@kylheku.com>2025-01-21 07:33:39 -0800
commit09dca7b4aabbb22b6febbc5ec1f328abc2fc6a86 (patch)
tree844f362061aadb111cf6e3f0d51cdd4a6dc354c2 /stdlib
parent6824735d879f42572778b40c323828f533b87248 (diff)
downloadtxr-09dca7b4aabbb22b6febbc5ec1f328abc2fc6a86.tar.gz
txr-09dca7b4aabbb22b6febbc5ec1f328abc2fc6a86.tar.bz2
txr-09dca7b4aabbb22b6febbc5ec1f328abc2fc6a86.zip
get-csv: simplify implementation by CR-LF folding.
* stdlib/csv.tl (get-csv): Pre-process the input by a small state machine that maps CR-LF sequences to LF. Then we don't have to recognize #\return anywhere in the state machine and can delete the cr and qcr states, as well as all the code recognizing #\return and branching to those states.
Diffstat (limited to 'stdlib')
-rw-r--r--stdlib/csv.tl37
1 files changed, 7 insertions, 30 deletions
diff --git a/stdlib/csv.tl b/stdlib/csv.tl
index 9b03f3ce..c56d2520 100644
--- a/stdlib/csv.tl
+++ b/stdlib/csv.tl
@@ -28,16 +28,21 @@
(defun get-csv (: (stream *stdin*))
(if (stringp stream)
(upd stream make-string-input-stream))
- (enumlet (rfield qfield cr qcr quot)
+ (enumlet (rfield qfield quot)
(let ((record (vec))
(field (str 0))
(state rfield)
(done nil))
(while (not done)
(let ((ch (get-char stream)))
+ (when (eq ch #\return)
+ (let ((ch2 (get-char stream)))
+ (if (eq ch2 #\newline)
+ (set ch ch2)
+ (if ch2
+ (unget-char ch2 stream)))))
(caseql* state
(rfield (caseql* ch
- (#\return (set state cr))
(#\newline (vec-push record field)
(set done t))
(#\, (vec-push record field)
@@ -52,36 +57,9 @@
(t (string-extend field ch))))
(qfield (caseql* ch
(#\" (set state quot))
- (#\return (set state qcr))
(nil (vec-push record field)
(set done t))
(t (string-extend field ch))))
- (cr (caseql* ch
- (#\newline (vec-push record field)
- (set done t))
- (#\return (string-extend field ch))
- (#\, (string-extend field #\return)
- (vec-push record field)
- (set field (str 0)
- state rfield))
- (nil (string-extend field #\return)
- (vec-push record field)
- (set done t))
- (t (string-extend field #\return)
- (string-extend field ch)
- (set state rfield))))
- (qcr (caseql* ch
- (#\newline (string-extend field ch)
- (set state qfield))
- (#\return (string-extend field ch))
- (nil (string-extend field #\return)
- (vec-push record field)
- (set done t))
- (#\" (string-extend field #\return)
- (set state quot))
- (t (string-extend field #\return)
- (string-extend field ch)
- (set state qfield))))
(quot (caseql* ch
(#\, (vec-push record field)
(set field (str 0)
@@ -90,7 +68,6 @@
(set state qfield))
(#\newline (vec-push record field)
(set done t))
- (#\return (set state cr))
(nil (vec-push record field)
(set done t))
(t (string-extend field ch)