tur/csv
CSV parser and emitter following RFC 4180.
Since: Phase B1
csv/parse-row-with-delim
(csv/parse-row-with-delim [line :cstr delim :int] :int)
parse one delimiter-separated line into a vec of field cstrs.
| line | NUL-terminated delimiter-separated row cstr | |
| delim | delimiter character as ASCII code (e.g., 44 for comma, 9 for tab) |
A heap-allocated vec whose elements are (int64_t)(char*) field cstrs. Both the vec and all field strings are independently heap-allocated. Free with csv/row-free. Returns 0 on invalid delimiter (NUL, quote, CR, LF).
(csv/parse-row-with-delim "a|b|c" 124) ; => vec of 3 fields (csv/parse-row-with-delim "x\ty\tz" 9) ; => vec of 3 fields (csv/parse-row-with-delim "bad" 0) ; => 0
Since: Phase D2
csv/parse-row
(csv/parse-row [line :cstr] :int)
parse one CSV line into a vec of field cstrs.
| line | NUL-terminated CSV row cstr |
A heap-allocated vec whose elements are (int64_t)(char*) field cstrs. Both the vec and all field strings are independently heap-allocated. Free with csv/row-free.
(csv/parse-row "a,\"b,c\",d") ; => vec ["a", "b,c", "d"]
Since: Phase B2
csv/row-free
(csv/row-free [v :int] :void)
free a row vec and all its field strings.
| v | vec pointer returned by csv/parse-row or csv/emit-row (may be 0) |
(csv/row-free my-row)
Since: Phase B2
csv/parse-with-delim
(csv/parse-with-delim [s :cstr delim :int] :int)
parse a multi-line delimiter-separated string into a cons list of row vecs.
| s | NUL-terminated delimiter-separated string (possibly multi-line) | |
| delim | delimiter character as ASCII code (e.g., 44 for comma, 9 for tab) |
A cons list of row vec pointers (each from csv/parse-row-with-delim). Free with csv/free. Returns 0 on invalid delimiter (NUL, quote, CR, LF).
(csv/parse-with-delim "a\tb\n1\t2\n" 9) ; => cons list of 2 rows (csv/parse-with-delim "x;y" 59) ; => cons list of 1 row (csv/parse-with-delim "bad" 0) ; => 0
Since: Phase D2
csv/parse
(csv/parse [s :cstr] :int)
parse a multi-line CSV string into a cons list of row vecs.
| s | NUL-terminated CSV string (possibly multi-line) |
A cons list of row vec pointers (each from csv/parse-row). Free with csv/free.
(csv/parse "a,b\n1,2\n") ; => cons of two row vecs
Since: Phase B2
csv/free
(csv/free [lst :int] :void)
free a cons list of rows returned by csv/parse.
| lst | cons list of row vecs returned by csv/parse |
(csv/free my-csv)
Since: Phase B2
csv/emit-row-with-delim
(csv/emit-row-with-delim [v :int delim :int] :cstr)
serialize a vec of field cstrs to a delimiter-separated line cstr.
| v | vec of (int64_t)(char*) field cstrs | |
| delim | delimiter character as ASCII code (e.g., 44 for comma, 9 for tab) |
A heap-allocated NUL-terminated delimiter-separated line without a trailing newline. The caller must free. Returns 0 on invalid delimiter (NUL, quote, CR, LF).
(csv/emit-row-with-delim my-vec 124) ; => "a|\"b|c\"|d" (pipe-delimited) (csv/emit-row-with-delim (csv/parse-row "a,b") 44) ; => "a,b" (csv/emit-row-with-delim (csv/parse-row "a,b") 0) ; => 0
Since: Phase D2
csv/emit-row
(csv/emit-row [v :int] :cstr)
serialize a vec of field cstrs to a CSV line cstr.
| v | vec of (int64_t)(char*) field cstrs |
A heap-allocated NUL-terminated CSV line without a trailing newline. The caller must free.
(csv/emit-row my-vec) ; => "a,\"b,c\",d"
Since: Phase B2
csv/emit-with-delim
(csv/emit-with-delim [rows :int delim :int] :cstr)
serialize a cons list of row vecs to a full delimiter-separated string.
| rows | cons list of row vecs (as from csv/parse-with-delim) | |
| delim | delimiter character as ASCII code (e.g., 44 for comma, 9 for tab) |
A heap-allocated NUL-terminated delimiter-separated string with newline-separated rows. The caller must free. Returns 0 on invalid delimiter (NUL, quote, CR, LF).
(csv/emit-with-delim my-rows 9) ; => "a\tb\n1\t2\n" (TSV) (csv/emit-with-delim (csv/parse "a,b\n1,2\n") 44) ; => "a,b\n1,2\n" (csv/emit-with-delim (csv/parse "a,b\n") 0) ; => 0
Since: Phase D2
csv/emit
(csv/emit [rows :int] :cstr)
serialize a cons list of row vecs to a full CSV string.
| rows | cons list of row vecs (as from csv/parse) |
A heap-allocated NUL-terminated CSV string with newline-separated rows. The caller must free.
(csv/emit my-rows) ; => "a,b\n1,2\n"
Since: Phase B2
csv/read-file-with-delim
(csv/read-file-with-delim [path :cstr delim :int] :int)
read a delimiter-separated file and parse it into a cons list of row vecs.
| path | NUL-terminated file path cstr | |
| delim | delimiter character as ASCII code (e.g., 44 for comma, 9 for tab) |
A cons list of row vecs (same as csv/parse-with-delim), or 0 on read error or invalid delimiter. Free with csv/free.
(csv/read-file-with-delim "data.tsv" 9) ; => cons list of TSV rows (csv/read-file-with-delim "/nonexistent" 44) ; => 0 (csv/read-file-with-delim "/etc/hosts" 0) ; => 0
Since: Phase D2
csv/read-file
(csv/read-file [path :cstr] :int)
read a CSV file and parse it into a cons list of row vecs.
| path | NUL-terminated file path cstr |
A cons list of row vecs (same as csv/parse), or 0 on read error. Free with csv/free.
(csv/read-file "data.csv") ; => cons list of rows
Since: Phase B2
csv/write-file-with-delim
(csv/write-file-with-delim [path :cstr rows :int delim :int] :int)
serialize a cons list of row vecs to a delimiter-separated file.
| path | NUL-terminated destination path cstr | |
| rows | cons list of row vecs | |
| delim | delimiter character as ASCII code (e.g., 44 for comma, 9 for tab) |
0 on success, -1 on error or invalid delimiter.
(csv/write-file-with-delim "out.tsv" my-rows 9) ; => 0 (TSV file) (csv/write-file-with-delim "/dev/null" (csv/parse "a,b") 44) ; => 0 (csv/write-file-with-delim "/dev/null" (csv/parse "a") 0) ; => -1
Since: Phase D2
csv/write-file
(csv/write-file [path :cstr rows :int] :int)
serialize a cons list of row vecs to a CSV file.
| path | NUL-terminated destination path cstr | |
| rows | cons list of row vecs |
0 on success, -1 on error.
(csv/write-file "out.csv" my-rows) ; => 0
Since: Phase B2