[q-lang-cvs] q-csv csv.c,1.13,1.14 csv.q,1.13,1.14
Brought to you by:
agraef
From: RER <ed...@us...> - 2008-01-24 22:26:25
|
Update of /cvsroot/q-lang/q-csv In directory sc8-pr-cvs16.sourceforge.net:/tmp/cvs-serv10914 Modified Files: csv.c csv.q Log Message: csv.c line terminator fix and csv.q clean up Index: csv.c =================================================================== RCS file: /cvsroot/q-lang/q-csv/csv.c,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** csv.c 23 Jan 2008 16:05:04 -0000 1.13 --- csv.c 24 Jan 2008 22:26:07 -0000 1.14 *************** *** 26,32 **** #define BSIZE 512 ! #define FORCEQUOTE 0 ! #define AUTOQUOTE 1 ! #define NOQUOTE 2 /* fread_block reads embbeded '\n's. --- 26,32 ---- #define BSIZE 512 ! enum {FORCEQUOTE, AUTOQUOTE, NOQUOTE}; ! enum {CSV_DELIMITER, CSV_ESCAPE, CSV_QUOTE, CSV_QUOTING, CSV_LINETERMINATOR, ! CSV_SKIPSPACE}; /* fread_block reads embbeded '\n's. *************** *** 35,39 **** FUNCTION (csv, fread_csvstr, argc, argv) ! { FILE *fp; char *bf, *tb, *qt_s, *s; --- 35,39 ---- FUNCTION (csv, fread_csvstr, argc, argv) ! { FILE *fp; char *bf, *tb, *qt_s, *s; *************** *** 54,59 **** if (n + BSIZE > sz) { if (!(tb = realloc(bf, sz <<= 1))) { ! free(bf); ! return __ERROR; } s = (bf = tb) + n; --- 54,59 ---- if (n + BSIZE > sz) { if (!(tb = realloc(bf, sz <<= 1))) { ! free(bf); ! return __ERROR; } s = (bf = tb) + n; *************** *** 71,81 **** while (*s) { if (!strncmp(s, qt_s, n_qt_s)) { ! ++qt_cnt; ! s += n_qt_s; } else ! ++s; } if (!(qt_cnt & 1)) { ! fini: s = to_utf8(bf, NULL); free(bf); --- 71,81 ---- while (*s) { if (!strncmp(s, qt_s, n_qt_s)) { ! ++qt_cnt; ! s += n_qt_s; } else ! ++s; } if (!(qt_cnt & 1)) { ! fini: s = to_utf8(bf, NULL); free(bf); *************** *** 145,152 **** { int n, st = 0, fld_sz = 256, n_fld, rec_sz = 64, n_ws = 0, n_rec = 0, ! n_delimiter, n_escape, n_quote, n_lineterm, skipspace_f, ! esc_eq_quote; ! char *fld, *tfld, *fldp, *s, errmsg[80], ! *delimiter, *escape, *quote, *lineterm; long quoting; expr *xs, *rec, *trec; --- 145,151 ---- { int n, st = 0, fld_sz = 256, n_fld, rec_sz = 64, n_ws = 0, n_rec = 0, ! n_delimiter, n_escape, n_quote, n_lineterm, skipspace_f, esc_eq_quote; ! char *fld, *tfld, *fldp, *s, errmsg[80], *delimiter, *escape, *quote, ! *lineterm; long quoting; expr *xs, *rec, *trec; *************** *** 156,165 **** || !istuple(argv[0], &n, &xs) || n != 6 ! || !isstr(xs[0], &delimiter) ! || !isstr(xs[1], &escape) ! || !isstr(xs[2], "e) ! || !isint(xs[3], "ing) ! || !isstr(xs[4], &lineterm) ! || !isbool(xs[5], &skipspace_f) || !isstr(argv[1], &s)) return __FAIL; --- 155,164 ---- || !istuple(argv[0], &n, &xs) || n != 6 ! || !isstr(xs[CSV_DELIMITER], &delimiter) ! || !isstr(xs[CSV_ESCAPE], &escape) ! || !isstr(xs[CSV_QUOTE], "e) ! || !isint(xs[CSV_QUOTING], "ing) ! || !isstr(xs[CSV_LINETERMINATOR], &lineterm) ! || !isbool(xs[CSV_SKIPSPACE], &skipspace_f) || !isstr(argv[1], &s)) return __FAIL; *************** *** 181,296 **** while (st < 10) { switch (st) { ! case 0: ! fldp = fld; ! n_fld = 0; ! if (!strncmp(s, delimiter, n_delimiter)) { ! *fldp = 0; ! putrec(FORCEQUOTE); ! s += n_delimiter; ! } else if (!strncmp(s, quote, n_quote)) { ! s += n_quote; ! st = 1; ! } else if (!*s || *s == EOF || !strncmp(s, lineterm, n_lineterm)) { ! st = 10; ! } else if (isspace(*s) && skipspace_f) { ! ++s; ! } else if (!strncmp(s, escape, n_escape)) { ! sprintf(errmsg, "Column %d: Unexpected escape.", n_fld+1); ! st = 20; ! } else { ! putfld(1); ! ++s; ! st = 4; ! } ! break; ! case 1: ! if (!strncmp(s, quote, n_quote)) { ! s += n_quote; ! st = 2; ! } else if (!*s || *s == EOF) { ! sprintf(errmsg, "Column %d: Expected {%s}.", n_fld+1, quote); ! st = 20; ! } else if (!strncmp(s, escape, n_escape)) { ! s += n_escape; ! putfld(1); ! ++s; ! } else { ! putfld(1); ! ++s; ! } ! break; ! case 2: ! if (!strncmp(s, quote, n_quote) && esc_eq_quote) { ! putfld(n_quote); ! s += n_quote; ! st = 1; ! } else if (!strncmp(s, delimiter, n_delimiter)) { ! putrec(FORCEQUOTE); ! s += n_delimiter; ! st = 0; ! } else if (!*s || *s == EOF || !strncmp(s, lineterm, n_lineterm)) { ! putrec(FORCEQUOTE); ! st = 10; ! } else if (isspace(*s)) { ! ++s; ! st = 3; ! } else { ! sprintf(errmsg, "Column %d: Expected {%s}.", n_fld+1, delimiter); ! st = 20; ! } ! break; ! case 3: ! if (!strncmp(s, delimiter, n_delimiter)) { ! putrec(FORCEQUOTE); ! s += n_delimiter; ! st = 0; ! } else if (!*s || *s == '\n' || *s == EOF) { ! putrec(FORCEQUOTE); ! st = 10; ! } else if (isspace(*s)) { ! ++s; ! } else { ! sprintf(errmsg, "Column %d: Expected {%s}.", n_fld+1, delimiter); ! st = 20; ! } ! break; ! case 4: ! if (!strncmp(s, quote, n_quote) || !strncmp(s, escape, n_escape)) { ! sprintf(errmsg, "Column %d: Expected {%s}.", n_fld+1, delimiter); ! st = 20; ! } else if (!strncmp(s, delimiter, n_delimiter)) { ! fldp -= n_ws; ! n_fld -= n_ws; ! putrec(quoting); ! s += n_delimiter; ! st = 0; ! } else if (!*s || *s == EOF || !strncmp(s, lineterm, n_lineterm)) { ! putrec(quoting); ! st = 10; ! } else if (isspace(*s)) { ! n_ws = n_ws ? n_ws+1 : 1; ! putfld(1); ! ++s; ! } else { ! n_ws = 0; ! putfld(1); ! ++s; ! } ! break; } } done: ! free(fld); ! if (st == 10) { ! rec = realloc(rec, sizeof(expr)*n_rec); ! return mktuplev(n_rec, rec); ! } else { ! for (n = 0; n < n_rec; ++n) ! dispose(rec[n]); ! free(rec); ! if (st == 20) ! return mkapp(mksym(sym(csv_error)), mkstr(strdup(errmsg))); ! return __ERROR; ! } } --- 180,295 ---- while (st < 10) { switch (st) { ! case 0: ! fldp = fld; ! n_fld = 0; ! if (!strncmp(s, delimiter, n_delimiter)) { ! *fldp = 0; ! putrec(FORCEQUOTE); ! s += n_delimiter; ! } else if (!strncmp(s, quote, n_quote)) { ! s += n_quote; ! st = 1; ! } else if (!*s || *s == EOF || !strncmp(s, lineterm, n_lineterm)) { ! st = 10; ! } else if (isspace(*s) && skipspace_f) { ! ++s; ! } else if (!strncmp(s, escape, n_escape)) { ! sprintf(errmsg, "Column %d: Unexpected escape.", n_fld+1); ! st = 20; ! } else { ! putfld(1); ! ++s; ! st = 4; ! } ! break; ! case 1: ! if (!strncmp(s, quote, n_quote)) { ! s += n_quote; ! st = 2; ! } else if (!*s || *s == EOF) { ! sprintf(errmsg, "Column %d: Expected {%s}.", n_fld+1, quote); ! st = 20; ! } else if (!strncmp(s, escape, n_escape)) { ! s += n_escape; ! putfld(1); ! ++s; ! } else { ! putfld(1); ! ++s; ! } ! break; ! case 2: ! if (!strncmp(s, quote, n_quote) && esc_eq_quote) { ! putfld(n_quote); ! s += n_quote; ! st = 1; ! } else if (!strncmp(s, delimiter, n_delimiter)) { ! putrec(FORCEQUOTE); ! s += n_delimiter; ! st = 0; ! } else if (!*s || *s == EOF || !strncmp(s, lineterm, n_lineterm)) { ! putrec(FORCEQUOTE); ! st = 10; ! } else if (isspace(*s)) { ! ++s; ! st = 3; ! } else { ! sprintf(errmsg, "Column %d: Expected {%s}.", n_fld+1, delimiter); ! st = 20; ! } ! break; ! case 3: ! if (!strncmp(s, delimiter, n_delimiter)) { ! putrec(FORCEQUOTE); ! s += n_delimiter; ! st = 0; ! } else if (!*s || *s == '\n' || *s == EOF) { ! putrec(FORCEQUOTE); ! st = 10; ! } else if (isspace(*s)) { ! ++s; ! } else { ! sprintf(errmsg, "Column %d: Expected {%s}.", n_fld+1, delimiter); ! st = 20; ! } ! break; ! case 4: ! if (!strncmp(s, quote, n_quote) || !strncmp(s, escape, n_escape)) { ! sprintf(errmsg, "Column %d: Expected {%s}.", n_fld+1, delimiter); ! st = 20; ! } else if (!strncmp(s, delimiter, n_delimiter)) { ! fldp -= n_ws; ! n_fld -= n_ws; ! putrec(quoting); ! s += n_delimiter; ! st = 0; ! } else if (!*s || *s == EOF || !strncmp(s, lineterm, n_lineterm)) { ! putrec(quoting); ! st = 10; ! } else if (isspace(*s)) { ! n_ws = n_ws ? n_ws+1 : 1; ! putfld(1); ! ++s; ! } else { ! n_ws = 0; ! putfld(1); ! ++s; ! } ! break; } } done: ! free(fld); ! if (st == 10) { ! rec = realloc(rec, sizeof(expr)*n_rec); ! return mktuplev(n_rec, rec); ! } else { ! for (n = 0; n < n_rec; ++n) ! dispose(rec[n]); ! free(rec); ! if (st == 20) ! return mkapp(mksym(sym(csv_error)), mkstr(strdup(errmsg))); ! return __ERROR; ! } } *************** *** 340,349 **** || !istuple(argv[0], &i, &ys) || i != 6 ! || !isstr(ys[0], &delimiter) ! || !isstr(ys[1], &escape) ! || !isstr(ys[2], "e) ! || !isint(ys[3], "ing) ! || !isstr(ys[4], &lineterm) ! || !isbool(ys[5], &skipspace_f) || !istuple(argv[1], &n, &xs)) { return __FAIL; --- 339,348 ---- || !istuple(argv[0], &i, &ys) || i != 6 ! || !isstr(ys[CSV_DELIMITER], &delimiter) ! || !isstr(ys[CSV_ESCAPE], &escape) ! || !isstr(ys[CSV_QUOTE], "e) ! || !isint(ys[CSV_QUOTING], "ing) ! || !isstr(ys[CSV_LINETERMINATOR], &lineterm) ! || !isbool(ys[CSV_SKIPSPACE], &skipspace_f) || !istuple(argv[1], &n, &xs)) { return __FAIL; *************** *** 360,372 **** if (isint(xs[i], &ival)) { if (!quoting) ! sprintf(tb, "%s%d%s%s", quote, ival, quote, delimiter); else ! sprintf(tb, "%d%s", ival, delimiter); insert; } else if (isfloat(xs[i], &dval)) { if (!quoting) ! sprintf(tb, "%s%.16g%s%s", quote, dval, quote, delimiter); else ! sprintf(tb, "%.16g%s", dval, delimiter); insert; } else if (isstr(xs[i], &sval)) { --- 359,371 ---- if (isint(xs[i], &ival)) { if (!quoting) ! sprintf(tb, "%s%d%s%s", quote, ival, quote, delimiter); else ! sprintf(tb, "%d%s", ival, delimiter); insert; } else if (isfloat(xs[i], &dval)) { if (!quoting) ! sprintf(tb, "%s%.16g%s%s", quote, dval, quote, delimiter); else ! sprintf(tb, "%.16g%s", dval, delimiter); insert; } else if (isstr(xs[i], &sval)) { *************** *** 376,433 **** p = sval; if (skipspace_f && quoting == NOQUOTE) ! while (isspace(*p) ! && strncmp(p, quote, n_delimiter) ! && strncmp(p, delimiter, n_delimiter) ! && strncmp(p, lineterm, n_lineterm)) { ! ++p; ! } ! k = p - sval; ! mrk = len; ! while (*p) { ! if (!strncmp(p, quote, n_quote)) { ! ++quote_cnt; ! p += n_quote; ! len += n_escape + n_quote; ! } else if (!strncmp(p, delimiter, n_delimiter)) { ! ++delim_cnt; ! p += n_delimiter; ! len += n_delimiter; ! } else if (!strncmp(p, lineterm, n_lineterm)) { ! ++lineterm_cnt; ! p += n_lineterm; ! len += n_lineterm; ! } else { ! ++len; ! ++p; ! } ! } ! len += n_delimiter; ! p = sval + k; ! if (quoting==NOQUOTE && !(quote_cnt + delim_cnt + lineterm_cnt)) { ! resize_str; ! k = len-mrk-1; ! strncpy(t, p, k); ! t += k; ! } else { ! /* Add space for surrounding quotes */ ! len += n_quote << 1; ! resize_str; ! strncpy(t, quote, n_quote); ! t += n_quote; ! while (*p) { ! if (!strncmp(p, quote, n_quote)) { ! strncpy(t, escape, n_escape); ! t += n_escape; ! strncpy(t, quote, n_quote); ! t += n_quote; ! p += n_quote; ! } else ! *t++ = *p++; ! } ! strncpy(t, quote, n_quote); ! t += n_quote; ! } ! strncpy(t, delimiter, n_delimiter); ! t += n_delimiter; } else { sprintf(errmsg, "Field %d: Invalid conversion type.", i+1); --- 375,432 ---- p = sval; if (skipspace_f && quoting == NOQUOTE) ! while (isspace(*p) ! && strncmp(p, quote, n_delimiter) ! && strncmp(p, delimiter, n_delimiter) ! && strncmp(p, lineterm, n_lineterm)) { ! ++p; ! } ! k = p - sval; ! mrk = len; ! while (*p) { ! if (!strncmp(p, quote, n_quote)) { ! ++quote_cnt; ! p += n_quote; ! len += n_escape + n_quote; ! } else if (!strncmp(p, delimiter, n_delimiter)) { ! ++delim_cnt; ! p += n_delimiter; ! len += n_delimiter; ! } else if (!strncmp(p, lineterm, n_lineterm)) { ! ++lineterm_cnt; ! p += n_lineterm; ! len += n_lineterm; ! } else { ! ++len; ! ++p; ! } ! } ! len += n_delimiter; ! p = sval + k; ! if (quoting == NOQUOTE && !(quote_cnt + delim_cnt + lineterm_cnt)) { ! resize_str; ! k = len-mrk-1; ! strncpy(t, p, k); ! t += k; ! } else { ! /* Add space for surrounding quotes */ ! len += n_quote << 1; ! resize_str; ! strncpy(t, quote, n_quote); ! t += n_quote; ! while (*p) { ! if (!strncmp(p, quote, n_quote)) { ! strncpy(t, escape, n_escape); ! t += n_escape; ! strncpy(t, quote, n_quote); ! t += n_quote; ! p += n_quote; ! } else ! *t++ = *p++; ! } ! strncpy(t, quote, n_quote); ! t += n_quote; ! } ! strncpy(t, delimiter, n_delimiter); ! t += n_delimiter; } else { sprintf(errmsg, "Field %d: Invalid conversion type.", i+1); *************** *** 438,441 **** --- 437,441 ---- len += n_lineterm; resize_str; + strcpy(t,lineterm); if (!(t = strdup(s))) { free(s); Index: csv.q =================================================================== RCS file: /cvsroot/q-lang/q-csv/csv.q,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** csv.q 23 Jan 2008 16:05:04 -0000 1.13 --- csv.q 24 Jan 2008 22:26:07 -0000 1.14 *************** *** 22,28 **** Python's csv module (http://docs.python.org/lib/module-csv.html) */ ! private extern fread_csvstr FILE QUOTE; ! private extern tuple_to_csvstr ARGS REC; ! private extern csvstr_to_tuple ARGS STR; public csv_error MSG; --- 22,28 ---- Python's csv module (http://docs.python.org/lib/module-csv.html) */ ! public extern fread_csvstr FILE QUOTE; ! public extern tuple_to_csvstr ARGS REC; ! public extern csvstr_to_tuple ARGS STR; public csv_error MSG; *************** *** 31,93 **** from dict import dict, insert, vals, member; ! /* Dialect Options */ ! public const var ! csv_delimiter = 0, /* Field delimiter. Defaults to ",". */ ! csv_escape = 1, /* Embedded escape character. Defaults to "\"". ! Reading: The escape character is dropped and ! the next char is inserted into the field. ! Writing: The escape character is written into the ! output stream. */ ! csv_quote = 2, /* Quote character. Defaults to "\"". ! Note: If embedded quotes are doubled, csv_escape ! must equal csv_quote. */ ! csv_quoting = 3, /* Quoting options: Defaults to quote_strings. ! If csv_quote_all, ! Reading: all fields are read as strings. ! Writing: all fields are quoted. ! If csv_quote_strings, ! Reading: integers and floats are converted. ! Writing: integers and floats are unquoted. ! If csv_quote_none, ! Reading: ntegers and floats are converted. ! Writing: all fields are unquoted except for ! those containing embedded quotes or ! newlines. */ ! csv_lineterminator = 4, /* Record terminator. Defaults to "\r\n" */ ! csv_skipspace = 5, /* Skip white space flag. Defaults to true. ! Reading/Writing: If true, white spaces before ! fields are removed. Quoted fields retain white ! space. */ ! /* Constants used by csv quoting */ ! csv_quote_all = 0, /* Quote every field */ ! csv_quote_strings = 1, /* Quote only strings */ ! csv_quote_none = 2; /* Quote only fields with embedded field delimeters, ! line terminators, or escaped quotes. */ /* Defaults to RFC 4180 (http://www.ietf.org/rfc/rfc4180.txt) */ ! def DEFAULTS ! = dict [csv_delimiter, ","; ! csv_escape, "\""; ! csv_quote, "\""; ! csv_quoting, csv_quote_strings; ! csv_lineterminator, "\r\n"; ! csv_skipspace, true]; /* Create a dialect base on the list of dialect options given above */ public csv_dialect OPTS; csv_dialect Opts:List ! = tuple $ vals ! $ foldl insert (insert DEFAULTS (csv_escape, D!csv_quote)) $ Opts ! if (member D csv_quote) and then (not member D csv_escape) ! where D = dict Opts; ! = tuple $ vals $ foldl insert DEFAULTS $ Opts; ! /* Some CSV formats */ public const var ! RFC4180 = csv_dialect [], ! UNIX = csv_dialect [csv_lineterminator,"\n";]; ! /* Convert a tuple (record) to a CSV string Dialect: CSV format specification. If none is given, defaults to the RFC4180 dialect. --- 31,105 ---- from dict import dict, insert, vals, member; ! public const var ! csv_delimiter = 0, ! csv_escape = 1, ! csv_quote = 2, ! csv_quoting = 3, ! csv_lineterminator = 4, ! csv_skipspace = 5; ! public const var ! csv_quote_all = 0, ! csv_quote_strings = 1, ! csv_quote_none = 2; ! ! /* Dialect Options ! csv_delimiter: Field delimiter. Defaults to ",". ! ! csv_escape: Embedded escape character. Defaults to "\"". ! Reading: The escape character is dropped and ! the next char is inserted into the field. ! Writing: The escape character is written into the ! output stream. ! ! csv_quote: Quote character. Defaults to "\"". ! Note: If embedded quotes are doubled, csv_escape must equal ! csv_quote. The csv_dialect function will automatically set ! the csv_escape character to csv_quote if csv_escape is not ! specified. ! ! csv_quoting: Quoting options: Defaults to csv_quote_strings. ! See QuoteStyle constants below. ! ! csv_lineterminator: Record terminator. Defaults to "\r\n". ! ! csv_skipspace: Skip white space flag. Defaults to true. ! Reading/Writing: If true, white spaces before fields are removed. ! Quoted fields always retain white space. */ ! ! /* QuoteStyle constants used by csv quoting. ! csv_quote_all: Every field, including numeric fields, is quoted. ! csv_quote_strings: Quote only strings fields, numeric fields are not quoted. ! csv_quote_none: Only fields containing embedded field delimeters, line ! terminators, or escaped quotes are quoted. */ /* Defaults to RFC 4180 (http://www.ietf.org/rfc/rfc4180.txt) */ ! def DEFAULTS ! = dict [csv_delimiter, ","; ! csv_escape, "\""; ! csv_quote, "\""; ! csv_quoting, csv_quote_strings; ! csv_lineterminator, "\r\n"; ! csv_skipspace, true]; /* Create a dialect base on the list of dialect options given above */ public csv_dialect OPTS; csv_dialect Opts:List ! = tuple ! $ vals ! $ foldl insert (insert DEFAULTS (csv_escape, D!csv_quote)) ! $ Opts ! if (member D csv_quote) and then (not member D csv_escape) ! where D = dict Opts; ! = tuple $ vals $ foldl insert DEFAULTS $ Opts; ! /* Some typical CSV formats */ public const var ! RFC4180 = csv_dialect [], ! UNIX = csv_dialect [csv_lineterminator, "\n";], ! EXCEL = csv_dialect [csv_quoting, csv_quote_none;]; ! ! /* Convert a tuple (record) to a CSV string. Dialect: CSV format specification. If none is given, defaults to the RFC4180 dialect. *************** *** 99,112 **** public swritecsv ARGS; swritecsv (Dialect:Tuple, Rec:Tuple) ! = tuple_to_csvstr Dialect Rec; swritecsv Rec:Tuple ! = tuple_to_csvstr RFC4180 Rec; /* Convert a list of tuples to a list of CSV formated strings. */ public swritecsvlist ARGS; swritecsvlist (Dialect:Tuple, L:List) ! = map (tuple_to_csvstr Dialect) L; swritecsvlist L:List ! = map (tuple_to_csvstr RFC4180) L; /* Convert a tuple (record) to a CSV string --- 111,124 ---- public swritecsv ARGS; swritecsv (Dialect:Tuple, Rec:Tuple) ! = tuple_to_csvstr Dialect Rec; swritecsv Rec:Tuple ! = tuple_to_csvstr RFC4180 Rec; /* Convert a list of tuples to a list of CSV formated strings. */ public swritecsvlist ARGS; swritecsvlist (Dialect:Tuple, L:List) ! = map (tuple_to_csvstr Dialect) L; swritecsvlist L:List ! = map (tuple_to_csvstr RFC4180) L; /* Convert a tuple (record) to a CSV string *************** *** 119,155 **** public sreadcsv ARGS; sreadcsv (Rec:Tuple, Dialect:Tuple) ! = csvstr_to_tuple Dialect Rec; sreadcsv Rec:Tuple ! = csvstr_to_tuple RFC4180 Rec; /* Convert a list of CSV formated strings to a list of tuples */ public sreadcsvlist ARGS; sreadcsvlist (L:List, Dialect:Tuple) ! = map (csvstr_to_tuple Dialect) L; sreadcsvlist L:List ! = map (csvstr_to_tuple RFC4180) L; /* File handling functions */ public freadcsv ARGS; freadcsv (F:File, Dialect:Tuple) ! = csvstr_to_tuple Dialect $ fread_csvstr F (Dialect!csv_quote); freadcsv F:File ! = csvstr_to_tuple RFC4180 $ fread_csvstr F "\""; public fwritecsv ARGS REC; fwritecsv (F:File, Dialect:Tuple) Rec:Tuple ! = fwrites F $ tuple_to_csvstr Dialect Rec; fwritecsv F:File Rec:Tuple ! = fwrites F $ tuple_to_csvstr RFC4180 Rec; public freadcsvlist ARGS; freadcsvlist (F:File, Dialect:Tuple) ! = [freadcsv (F, Dialect) | freadcsvlist (F, Dialect)]; freadcsvlist F:File ! = [freadcsv F | freadcsvlist F]; public fwritecsvlist ARGS REC; fwritecsvlist (F:File, Dialect:Tuple) L:List ! = do (fwritecsv F Dialect) L; fwritecsvlist F:File L:List ! = do (fwritecsv F) L; \ No newline at end of file --- 131,167 ---- public sreadcsv ARGS; sreadcsv (Rec:Tuple, Dialect:Tuple) ! = csvstr_to_tuple Dialect Rec; sreadcsv Rec:Tuple ! = csvstr_to_tuple RFC4180 Rec; /* Convert a list of CSV formated strings to a list of tuples */ public sreadcsvlist ARGS; sreadcsvlist (L:List, Dialect:Tuple) ! = map (csvstr_to_tuple Dialect) L; sreadcsvlist L:List ! = map (csvstr_to_tuple RFC4180) L; /* File handling functions */ public freadcsv ARGS; freadcsv (F:File, Dialect:Tuple) ! = csvstr_to_tuple Dialect $ fread_csvstr F (Dialect!csv_quote); freadcsv F:File ! = csvstr_to_tuple RFC4180 $ fread_csvstr F "\""; public fwritecsv ARGS REC; fwritecsv (F:File, Dialect:Tuple) Rec:Tuple ! = fwrites F $ tuple_to_csvstr Dialect Rec; fwritecsv F:File Rec:Tuple ! = fwrites F $ tuple_to_csvstr RFC4180 Rec; public freadcsvlist ARGS; freadcsvlist (F:File, Dialect:Tuple) ! = [freadcsv (F, Dialect) | freadcsvlist (F, Dialect)]; freadcsvlist F:File ! = [freadcsv F | freadcsvlist F]; public fwritecsvlist ARGS REC; fwritecsvlist (F:File, Dialect:Tuple) L:List ! = do (fwritecsv F Dialect) L; fwritecsvlist F:File L:List ! = do (fwritecsv F) L; \ No newline at end of file |