summaryrefslogtreecommitdiffstats
path: root/stream.c
diff options
context:
space:
mode:
Diffstat (limited to 'stream.c')
-rw-r--r--stream.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/stream.c b/stream.c
index 421b70eb..7701ba39 100644
--- a/stream.c
+++ b/stream.c
@@ -5506,6 +5506,46 @@ val get_csv(val source_opt)
return record;
}
+val put_csv(val record, val stream_in)
+{
+ val self = lit("put-csv");
+ val dest = if3(missingp(stream_in), std_output, stream_in);
+ seq_iter_t rec_iter;
+ val field;
+ int comma = 0;
+
+ seq_iter_init(self, &rec_iter, record);
+
+ while (seq_get(&rec_iter, &field)) {
+ val str = tostringp(field);
+ if (comma)
+ put_char(chr(','), dest);
+ comma = 1;
+ if (find(chr('"'), str, nil, nil)) {
+ put_char(chr('"'), dest);
+ put_string(str_esc(lit("\""), chr('"'), str), dest);
+ put_char(chr('"'), dest);
+ } else if (break_str(str, lit(",\n\r"))) {
+ put_char(chr('"'), dest);
+ put_string(str, dest);
+ put_char(chr('"'), dest);
+ } else {
+ put_string(str, dest);
+ }
+ }
+
+ put_char(chr('\n'), dest);
+
+ return nil;
+}
+
+val tocsv(val record)
+{
+ val ss = make_string_output_stream();
+ put_csv(record, ss);
+ return get_string_from_stream(ss);
+}
+
val tmpfile_wrap(void)
{
val self = lit("tmpfile");
@@ -5782,6 +5822,8 @@ void stream_init(void)
reg_varl(intern(lit("indent-code"), user_package), num_fast(indent_code));
reg_varl(intern(lit("indent-foff"), user_package), num_fast(indent_foff));
reg_fun(intern(lit("get-csv"), user_package), func_n1o(get_csv, 0));
+ reg_fun(intern(lit("put-csv"), user_package), func_n2o(put_csv, 1));
+ reg_fun(intern(lit("tocsv"), user_package), func_n1(tocsv));
reg_fun(intern(lit("tmpfile"), user_package), func_n0(tmpfile_wrap));
#if HAVE_MKDTEMP
reg_fun(intern(lit("mkdtemp"), user_package), func_n1(mkdtemp_wrap));