msexceltables.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733
  1. /* msexceltables.c Steve Simon 5-Jan-2005 */
  2. #include <u.h>
  3. #include <libc.h>
  4. #include <bio.h>
  5. #include <ctype.h>
  6. enum {
  7. Tillegal = 0,
  8. Tnumber, // cell types
  9. Tlabel,
  10. Tindex,
  11. Tbool,
  12. Terror,
  13. Ver8 = 0x600, // only BIFF8 and BIFF8x files support unicode
  14. };
  15. typedef struct Biff Biff;
  16. typedef struct Col Col;
  17. typedef struct Row Row;
  18. struct Row {
  19. Row *next;
  20. int r;
  21. Col *col;
  22. };
  23. struct Col {
  24. Col *next;
  25. int c;
  26. int f;
  27. int type;
  28. union {
  29. int index;
  30. int error;
  31. int bool;
  32. char *label;
  33. double number;
  34. };
  35. };
  36. struct Biff {
  37. Biobuf *bp;
  38. int op;
  39. int len;
  40. };
  41. // options
  42. static int Nopad = 0; // disable padding cells to colum width
  43. static int Trunc = 0; // truncate cells to colum width
  44. static int All = 0; // dump all sheet types, Worksheets only by default
  45. static char *Delim = " "; // field delimiter
  46. static int Debug = 0;
  47. // file scope
  48. static int Defwidth = 10; // default colum width if non given
  49. static int Biffver; // file vesion
  50. static int Datemode; // date ref: 1899-Dec-31 or 1904-jan-1
  51. static char **Strtab = nil; // label contents heap
  52. static int Nstrtab = 0; // # of above
  53. static int *Xf; // array of extended format indices
  54. static int Nxf = 0; // # of above
  55. static Biobuf *bo; // stdout (sic)
  56. // table scope
  57. static int *Width = nil; // array of colum widths
  58. static int Nwidths = 0; // # of above
  59. static int Ncols = -1; // max colums in table used
  60. static int Content = 0; // type code for contents of sheet
  61. static Row *Root = nil; // one worksheet's worth of cells
  62. static char *Months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  63. "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
  64. static char *Errmsgs[] = {
  65. [0x0] "#NULL!", // intersection of two cell ranges is empty
  66. [0x7] "#DIV/0!", // division by zero
  67. [0xf] "#VALUE!", // wrong type of operand
  68. [0x17] "#REF!", // illegal or deleted cell reference
  69. [0x1d] "#NAME?", // wrong function or range name
  70. [0x24] "#NUM!", // value range overflow
  71. [0x2a] "#N/A!", // argument of function not available
  72. };
  73. void
  74. cell(int r, int c, int f, int type, void *val)
  75. {
  76. Row *row, *nrow;
  77. Col *col, *ncol;
  78. if (c > Ncols)
  79. Ncols = c;
  80. if ((ncol = malloc(sizeof(Col))) == nil)
  81. sysfatal("no memory\n");
  82. ncol->c = c;
  83. ncol->f = f;
  84. ncol->type = type;
  85. ncol->next = nil;
  86. switch(type){
  87. case Tnumber: ncol->number = *(double *)val; break;
  88. case Tlabel: ncol->label = (char *)val; break;
  89. case Tindex: ncol->index = *(int *)val; break;
  90. case Tbool: ncol->bool = *(int *)val; break;
  91. case Terror: ncol->error = *(int *)val; break;
  92. default: sysfatal("can't happen error\n");
  93. }
  94. if (Root == nil || Root->r > r){
  95. if ((nrow = malloc(sizeof(Row))) == nil)
  96. sysfatal("no memory\n");
  97. nrow->col = ncol;
  98. ncol->next = nil;
  99. nrow->r = r;
  100. nrow->next = Root;
  101. Root = nrow;
  102. return;
  103. }
  104. for (row = Root; row; row = row->next){
  105. if (row->r == r){
  106. if (row->col->c > c){
  107. ncol->next = row->col;
  108. row->col = ncol;
  109. return;
  110. }
  111. else{
  112. for (col = row->col; col; col = col->next)
  113. if (col->next == nil || col->next->c > c){
  114. ncol->next = col->next;
  115. col->next = ncol;
  116. return;
  117. }
  118. }
  119. }
  120. if (row->next == nil || row->next->r > r){
  121. if ((nrow = malloc(sizeof(Row))) == nil)
  122. sysfatal("no memory\n");
  123. nrow->col = ncol;
  124. nrow->r = r;
  125. nrow->next = row->next;
  126. row->next = nrow;
  127. return;
  128. }
  129. }
  130. sysfatal("cannot happen error\n");
  131. }
  132. void
  133. numfmt(int fmt, int min, int max, double num)
  134. {
  135. long t;
  136. char buf[1024];
  137. struct Tm *tm;
  138. /* Beware - These epochs are wrong, this
  139. * is to remain compatible with Lotus-123
  140. * which believed 1900 was a leap year
  141. */
  142. if (Datemode)
  143. t = (num-24107)*60*60*24; // epoch = 1/1/1904
  144. else
  145. t = (num-25569)*60*60*24; // epoch = 31/12/1899
  146. tm = localtime(t);
  147. if (fmt == 9)
  148. snprint(buf, sizeof(buf),"%.0f%%", num);
  149. else
  150. if (fmt == 10)
  151. snprint(buf, sizeof(buf),"%f%%", num);
  152. else
  153. if (fmt == 11 || fmt == 48)
  154. snprint(buf, sizeof(buf),"%e", num);
  155. else
  156. if (fmt >= 14 && fmt <= 17)
  157. snprint(buf, sizeof(buf),"%d-%s-%d",
  158. tm->mday, Months[tm->mon], tm->year+1900);
  159. else
  160. if ((fmt >= 18 && fmt <= 21) || (fmt >= 45 && fmt <= 47))
  161. snprint(buf, sizeof(buf),"%02d:%02d:%02d", tm->hour, tm->min, tm->sec);
  162. else
  163. if (fmt == 22)
  164. snprint(buf, sizeof(buf),"%02d:%02d:%02d %d-%s-%d",
  165. tm->hour, tm->min, tm->sec,
  166. tm->mday, Months[tm->mon], tm->year+1900);
  167. else
  168. snprint(buf, sizeof(buf),"%g", num);
  169. Bprint(bo, "%-*.*q", min, max, buf);
  170. }
  171. void
  172. dump(void)
  173. {
  174. Row *r;
  175. Col *c;
  176. int i, min, max;
  177. for (r = Root; r; r = r->next){
  178. for (c = r->col; c; c = c->next){
  179. if (c->c < 0 || c->c >= Nwidths || (min = Width[c->c]) == 0)
  180. min = Defwidth;
  181. if ((c->next && c->c == c->next->c) || Nopad)
  182. min = 0;
  183. max = -1;
  184. if (Trunc && min > 2)
  185. max = min -2; // FIXME: -2 because of bug %q format ?
  186. switch(c->type){
  187. case Tnumber:
  188. if (Xf[c->f] == 0)
  189. Bprint(bo, "%-*.*g", min, max, c->number);
  190. else
  191. numfmt(Xf[c->f], min, max, c->number);
  192. break;
  193. case Tlabel:
  194. Bprint(bo, "%-*.*q", min, max, c->label);
  195. break;
  196. case Tbool:
  197. Bprint(bo, "%-*.*s", min, max, (c->bool)? "True": "False");
  198. break;
  199. case Tindex:
  200. if (c->error < 0 || c->error >= Nstrtab)
  201. sysfatal("SST string out of range - corrupt file?\n");
  202. Bprint(bo, "%-*.*q", min, max, Strtab[c->index]);
  203. break;
  204. case Terror:
  205. if (c->error < 0 || c->error >= nelem(Errmsgs))
  206. Bprint(bo, "#ERR=%d", c->index);
  207. else
  208. Bprint(bo, "%-*.*q", min, max, Errmsgs[c->error]);
  209. break;
  210. default:
  211. sysfatal("cannot happen error\n");
  212. break;
  213. }
  214. if (c->next){
  215. if (c->next->c == c->c) // bar charts
  216. Bprint(bo, "=");
  217. else{
  218. Bprint(bo, "%s", Delim);
  219. for (i = c->c; c->next && i < c->next->c -1; i++)
  220. Bprint(bo, "%-*.*s%s", min, max, "", Delim);
  221. }
  222. }
  223. }
  224. if (r->next)
  225. for (i = r->r; i < r->next->r; i++)
  226. Bprint(bo, "\n");
  227. }
  228. Bprint(bo, "\n");
  229. }
  230. void
  231. release(void)
  232. {
  233. Row *r, *or;
  234. Col *c, *oc;
  235. r = Root;
  236. while(r){
  237. c = r->col;
  238. while(c){
  239. if (c->type == Tlabel)
  240. free(c->label);
  241. oc = c;
  242. c = c->next;
  243. free(oc);
  244. }
  245. or = r;
  246. r = r->next;
  247. free(or);
  248. }
  249. Root = nil;
  250. free(Width);
  251. Width = nil;
  252. Nwidths = 0;
  253. Ncols = -1;
  254. }
  255. void
  256. skip(Biff *b, int len)
  257. {
  258. if (Bseek(b->bp, len, 1) == -1)
  259. sysfatal("seek failed - %r\n");
  260. b->len -= len;
  261. }
  262. void
  263. gmem(Biff *b, void *p, int n)
  264. {
  265. if (b->len < n)
  266. sysfatal("short record %d < %d\n", b->len, n);
  267. if (Bread(b->bp, p, n) != n)
  268. sysfatal("unexpected EOF - %r\n");
  269. b->len -= n;
  270. }
  271. void
  272. xd(Biff *b)
  273. {
  274. uvlong off;
  275. uchar buf[16];
  276. int addr, got, n, i, j;
  277. addr = 0;
  278. off = Boffset(b->bp);
  279. while (addr < b->len){
  280. n = (b->len >= sizeof(buf))? sizeof(buf): b->len;
  281. got = Bread(b->bp, buf, n);
  282. Bprint(bo, " %6d ", addr);
  283. addr += n;
  284. for (i = 0; i < got; i++)
  285. Bprint(bo, "%02x ", buf[i]);
  286. for (j = i; j < 16; j++)
  287. Bprint(bo, " ");
  288. Bprint(bo, " ");
  289. for (i = 0; i < got; i++)
  290. Bprint(bo, "%c", isprint(buf[i])? buf[i]: '.');
  291. Bprint(bo, "\n");
  292. }
  293. Bseek(b->bp, off, 0);
  294. off = Boffset(b->bp);
  295. }
  296. static int
  297. getrec(Biff *b)
  298. {
  299. int c;
  300. if ((c = Bgetc(b->bp)) == -1)
  301. return -1; // real EOF
  302. b->op = c;
  303. if ((c = Bgetc(b->bp)) == -1)
  304. sysfatal("unexpected EOF - %r\n");
  305. b->op |= c << 8;
  306. if ((c = Bgetc(b->bp)) == -1)
  307. sysfatal("unexpected EOF - %r\n");
  308. b->len = c;
  309. if ((c = Bgetc(b->bp)) == -1)
  310. sysfatal("unexpected EOF - %r\n");
  311. b->len |= c << 8;
  312. if (b->op == 0 && b->len == 0)
  313. return -1;
  314. if (Debug){
  315. Bprint(bo, "op=0x%x len=%d\n", b->op, b->len);
  316. xd(b);
  317. }
  318. return 0;
  319. }
  320. static uvlong
  321. gint(Biff *b, int n)
  322. {
  323. int i, c;
  324. uvlong vl, rc;
  325. if (b->len < n)
  326. return -1;
  327. rc = 0;
  328. for (i = 0; i < n; i++){
  329. if ((c = Bgetc(b->bp)) == -1)
  330. sysfatal("unexpected EOF - %r\n");
  331. b->len--;
  332. vl = c;
  333. rc |= vl << (8*i);
  334. }
  335. return rc;
  336. }
  337. double
  338. grk(Biff *b)
  339. {
  340. int f;
  341. uvlong n;
  342. double d;
  343. n = gint(b, 4);
  344. f = n & 3;
  345. n &= ~3LL;
  346. if (f & 2){
  347. d = n / 4.0;
  348. }
  349. else{
  350. n <<= 32;
  351. memcpy(&d, &n, sizeof(d));
  352. }
  353. if (f & 1)
  354. d /= 100.0;
  355. return d;
  356. }
  357. double
  358. gdoub(Biff *b)
  359. {
  360. double d;
  361. uvlong n = gint(b, 8);
  362. memcpy(&d, &n, sizeof(n));
  363. return d;
  364. }
  365. char *
  366. gstr(Biff *b, int len_width)
  367. {
  368. Rune r;
  369. int nch, sz, len, opt;
  370. char *buf, *p;
  371. if (b->len < len_width){
  372. if (getrec(b) == -1)
  373. sysfatal("expected CONTINUE, got EOF\n");
  374. if (b->op != 0x03c)
  375. sysfatal("expected CONTINUE, got op=0x%x\n", b->op);
  376. }
  377. len = gint(b, len_width);
  378. if (Biffver != Ver8){
  379. if ((buf = calloc(len+1, sizeof(char))) == nil)
  380. sysfatal("no memory\n");
  381. gmem(b, buf, len);
  382. return buf;
  383. }
  384. if ((buf = calloc(len+1, sizeof(char)*UTFmax)) == nil)
  385. sysfatal("no memory\n");
  386. p = buf;
  387. if (len == 0)
  388. return buf;
  389. nch = 0;
  390. while (1){
  391. opt = gint(b, 1);
  392. sz = (opt & 1)? sizeof(Rune): sizeof(char);
  393. while(b->len > 0){
  394. r = gint(b, sz);
  395. p += runetochar(p, &r);
  396. if (++nch >= len){
  397. return buf;
  398. }
  399. }
  400. if (getrec(b) == -1)
  401. sysfatal("expected CONTINUE, got EOF\n");
  402. if (b->op != 0x03c)
  403. sysfatal("expected CONTINUE, got op=0x%x\n", b->op);
  404. }
  405. sysfatal("cannot ever happen error\n");
  406. return buf;
  407. }
  408. void
  409. sst(Biff *b)
  410. {
  411. int n;
  412. skip(b, 4); // total # strings
  413. Nstrtab = gint(b, 4); // # unique strings
  414. if ((Strtab = calloc(Nstrtab, sizeof(char *))) == nil)
  415. sysfatal("no memory\n");
  416. for (n = 0; n < Nstrtab; n++)
  417. Strtab[n] = gstr(b, 2);
  418. }
  419. void
  420. boolerr(Biff *b)
  421. {
  422. int r = gint(b, 2); // row
  423. int c = gint(b, 2); // col
  424. int f = gint(b, 2); // formatting ref
  425. int v = gint(b, 1); // bool value / err code
  426. int t = gint(b, 1); // type
  427. cell(r, c, f, (t)? Terror: Tbool, &v);
  428. }
  429. void
  430. rk(Biff *b)
  431. {
  432. int r = gint(b, 2); // row
  433. int c = gint(b, 2); // col
  434. int f = gint(b, 2); // formatting ref
  435. double v = grk(b); // value
  436. cell(r, c, f, Tnumber, &v);
  437. }
  438. void
  439. mulrk(Biff *b)
  440. {
  441. int r = gint(b, 2); // row
  442. int c = gint(b, 2); // first col
  443. while (b->len >= 6){
  444. int f = gint(b, 2); // formatting ref
  445. double v = grk(b); // value
  446. cell(r, c++, f, Tnumber, &v);
  447. }
  448. }
  449. void
  450. number(Biff *b)
  451. {
  452. int r = gint(b, 2); // row
  453. int c = gint(b, 2); // col
  454. int f = gint(b, 2); // formatting ref
  455. double v = gdoub(b); // double
  456. cell(r, c, f, Tnumber, &v);
  457. }
  458. void
  459. label(Biff *b)
  460. {
  461. int r = gint(b, 2); // row
  462. int c = gint(b, 2); // col
  463. int f = gint(b, 2); // formatting ref
  464. char *s = gstr(b, 2); // byte string
  465. cell(r, c, f, Tlabel, s);
  466. }
  467. void
  468. labelsst(Biff *b)
  469. {
  470. int r = gint(b, 2); // row
  471. int c = gint(b, 2); // col
  472. int f = gint(b, 2); // formatting ref
  473. int i = gint(b, 2); // sst string ref
  474. cell(r, c, f, Tindex, &i);
  475. }
  476. void
  477. bof(Biff *b)
  478. {
  479. Biffver = gint(b, 2);
  480. Content = gint(b, 2);
  481. }
  482. void
  483. defcolwidth(Biff *b)
  484. {
  485. Defwidth = gint(b, 2);
  486. }
  487. void
  488. datemode(Biff *b)
  489. {
  490. Datemode = gint(b, 2);
  491. }
  492. void
  493. eof(Biff *b)
  494. {
  495. int i;
  496. struct {
  497. int n;
  498. char *s;
  499. } names[] = {
  500. 0x005, "Workbook globals",
  501. 0x006, "Visual Basic module",
  502. 0x010, "Worksheet",
  503. 0x020, "Chart",
  504. 0x040, "Macro sheet",
  505. 0x100, "Workspace file",
  506. };
  507. if (Ncols != -1){
  508. if (All){
  509. for (i = 0; i < nelem(names); i++)
  510. if (names[i].n == Content){
  511. Bprint(bo, "\n# contents %s\n", names[i].s);
  512. dump();
  513. }
  514. }
  515. else
  516. if (Content == 0x10)
  517. dump();
  518. }
  519. release();
  520. USED(b);
  521. }
  522. void
  523. colinfo(Biff *b)
  524. {
  525. int c;
  526. int c1 = gint(b, 2);
  527. int c2 = gint(b, 2);
  528. int w = gint(b, 2);
  529. if (c2 >= Nwidths){
  530. Nwidths = c2+20;
  531. if ((Width = realloc(Width, Nwidths*sizeof(int))) == nil)
  532. sysfatal("no memory\n");
  533. }
  534. w /= 256;
  535. if (w > 100)
  536. w = 100;
  537. if (w < 0)
  538. w = 0;
  539. for (c = c1; c <= c2; c++)
  540. Width[c] = w;
  541. }
  542. void
  543. xf(Biff *b)
  544. {
  545. int fmt;
  546. static int nalloc = 0;
  547. skip(b, 2);
  548. fmt = gint(b, 2);
  549. if (nalloc >= Nxf){
  550. nalloc += 20;
  551. if ((Xf = realloc(Xf, nalloc*sizeof(int))) == nil)
  552. sysfatal("no memory\n");
  553. }
  554. Xf[Nxf++] = fmt;
  555. }
  556. void
  557. writeaccess(Biff *b)
  558. {
  559. Bprint(bo, "# author %s\n", gstr(b, 2));
  560. }
  561. void
  562. codepage(Biff *b)
  563. {
  564. int codepage = gint(b, 2);
  565. if (codepage != 1200) // 1200 == UTF-16
  566. Bprint(bo, "# codepage %d\n", codepage);
  567. }
  568. void
  569. xls2csv(Biobuf *bp)
  570. {
  571. int i;
  572. Biff biff, *b;
  573. struct {
  574. int op;
  575. void (*func)(Biff *);
  576. } dispatch[] = {
  577. 0x00a, eof,
  578. 0x022, datemode,
  579. 0x042, codepage,
  580. 0x055, defcolwidth,
  581. 0x05c, writeaccess,
  582. 0x07d, colinfo,
  583. 0x0bd, mulrk,
  584. 0x0fc, sst,
  585. 0x0fd, labelsst,
  586. 0x203, number,
  587. 0x204, label,
  588. 0x205, boolerr,
  589. 0x27e, rk,
  590. 0x809, bof,
  591. 0x0e0, xf,
  592. };
  593. b = &biff;
  594. b->bp = bp;
  595. while(getrec(b) != -1){
  596. for (i = 0; i < nelem(dispatch); i++)
  597. if (b->op == dispatch[i].op)
  598. (*dispatch[i].func)(b);
  599. skip(b, b->len);
  600. }
  601. }
  602. void
  603. usage(void)
  604. {
  605. fprint(2, "usage: %s [-nta] [-d delim] file.xls\n", argv0);
  606. exits("usage");
  607. }
  608. void
  609. main(int argc, char *argv[])
  610. {
  611. int i;
  612. Biobuf bin, bout, *bp;
  613. ARGBEGIN{
  614. case 'n':
  615. Nopad = 1;
  616. break;
  617. case 't':
  618. Trunc = 1;
  619. break;
  620. case 'a':
  621. All = 1;
  622. break;
  623. case 'd':
  624. Delim = EARGF(usage());
  625. break;
  626. case 'D':
  627. Debug = 1;
  628. break;
  629. default:
  630. usage();
  631. break;
  632. }ARGEND;
  633. if (argc != 1)
  634. usage();
  635. bo = &bout;
  636. quotefmtinstall();
  637. Binit(bo, OWRITE, 1);
  638. if(argc > 0) {
  639. for(i = 0; i < argc; i++){
  640. if ((bp = Bopen(argv[i], OREAD)) == nil)
  641. sysfatal("%s cannot open - %r\n", argv[i]);
  642. xls2csv(bp);
  643. Bterm(bp);
  644. }
  645. } else {
  646. Binit(&bin, 0, OREAD);
  647. xls2csv(&bin);
  648. }
  649. exits(0);
  650. }