ref: babf901b4a508c3ec5d1f89655f10377bbdf9637
dir: /appl/lib/csv.b/
implement CSV;
include "sys.m";
include "bufio.m";
bufio: Bufio;
Iobuf: import bufio;
include "csv.m";
init(b: Bufio)
{
bufio = b;
}
getline(fd: ref Iobuf): list of string
{
rl: list of string;
for(;;){
(w, end) := getfield(fd);
if(rl == nil && w == nil && end < 0)
return nil;
rl = w :: rl;
if(end != ',')
break;
}
l: list of string;
for(; rl != nil; rl = tl rl)
l = hd rl :: l;
return l;
}
getfield(fd: ref Iobuf): (string, int)
{
w := "";
if((c := getcr(fd)) == '"'){ # quoted field
while((c = getcr(fd)) >= 0){
if(c == '"'){
c = getcr(fd);
if(c != '"')
break;
}
w[len w] = c;
}
}
# unquoted text, possibly following quoted text above
for(; c >= 0 && c != ',' && c != '\n'; c = getcr(fd))
w[len w] = c;
return (w, c);
}
getcr(fd: ref Iobuf): int
{
c := fd.getc();
if(c == '\r'){
nc := fd.getc();
if(nc >= 0 && nc != '\n')
fd.ungetc();
c = '\n';
}
return c;
}
quote(s: string): string
{
sep := 0;
for(i := 0; i < len s; i++)
if((c := s[i]) == '"')
return innerquote(s);
else if(c == ',' || c == '\n')
sep = 1;
if(sep)
return "\""+s+"\"";
return s;
}
innerquote(s: string): string
{
w := "\"";
for(i := j := 0; i < len s; i++)
if(s[i] == '"'){
w += s[j: i+1]; # including "
j = i; # including " again
}
return w+s[j:i]+"\"";
}