#include <u.h>
#include <libc.h>
#include <bio.h>
#include <ctype.h>
static void
wr2(Biobuf *bo, short n)
{
Bwrite(bo, &n, 2);
}
static void
wrn(Biobuf *bo, void *buf, int len)
{
Bwrite(bo, buf, len);
}
static void
str(Biobuf *bo, int r, int c, char *s)
{
int len;
len = strlen(s);
wr2(bo, 0x0204); /* string object */
wr2(bo, len + 8); /* bytes following */
wr2(bo, r);
wr2(bo, c);
wr2(bo, 0); /* format type - none */
wr2(bo, len); /* string length */
wrn(bo, s, len);
}
static void
num(Biobuf *bo, int r, int c, double n)
{
wr2(bo, 0x0203); /* number object */
wr2(bo, 14); /* bytes following */
wr2(bo, r);
wr2(bo, c);
wr2(bo, 0); /* format type - none */
wrn(bo, &n, sizeof(double));
}
static void
cell(Biobuf *bo, int r, int c, char *s)
{
char *t;
double n;
n = strtod(s, &t);
if(*s == 0 || *t != 0)
str(bo, r, c, s);
else
num(bo, r, c, n);
}
static void
usage(void)
{
fprint(2, "usage: %s [-d c] [<input-file>]\n", argv0);
fprint(2, " -d c set field deliminator\n");
exits("usage");
}
void
main(int argc, char *argv[])
{
int n, r, c;
char *delim, *line, *a[128];
Biobuf bout, *bo = &bout;
Biobuf binp, *bi = &binp;
delim = "|";
ARGBEGIN{
case 'd':
delim = EARGF(usage());
break;
default:
usage();
break;
}ARGEND;
switch(argc){
case 1:
bi = Bopen(argv[0], OREAD);
if(bi == nil)
sysfatal("%s cannot open - %r\n", argv[0]);
break;
case 0:
Binit(bi, OREAD, 0);
break;
default:
usage();
break;
}
Binit(bo, OWRITE, 1);
wr2(bo, 0x0809); /* Start of file */
wr2(bo, 4); /* bytes following */
wr2(bo, 0x500); /* Biff V5 file */
wr2(bo, 0x10); /* is a worksheet */
while((line = Brdline(bi, '\n')) != nil){
line[Blinelen(bi) -1] = 0;
n = getfields(line, a, nelem(a), 0, delim);
if(n < 2) /* blank lines */
continue;
if(a[0][0] == '#') /* comments */
continue;
r = atoi(a[0]) -1; /* -1 as excel ordinates start at zero */
for(c = 1; c < n; c++)
cell(bo, r, c-1, a[c]); /* -1 as excel ordinates start at zero */
}
wr2(bo, 0xa); /* End of file */
wr2(bo, 0); /* bytes following */
Bterm(bi);
Bterm(bo);
exits(nil);
}
|