/* xls2xml: Converts from Microsoft Excel files to XML. Copyright 1999 Roberto Arturo Tena Sanchez This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Roberto Arturo Tena Sanchez */ /* this functions are called by the functions that process records */ #include #include static char * alpha_col (U16 n); /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 AA AB AC AD AE AF AG AH AI AJ AK AL AM AN AO AP AQ AR AS AT AU AV AW AX AY AZ 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 BA BB BC BD BE BF BG BH BI BJ BK BL BM BN BO BP BQ BR BS BT BU BV BW BX BY BZ n n / 26 - 1 n % 26 return */ char * alpha_col (U16 n) { /* if we make alphabeth static, does it makes cole doesn't thread safe?? */ char * alphabeth = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; char buf[5]; /* FIXME MAGIC NUMBER max length of col name with U16 */ char *ret, *p; p = buf + 4; do { p--; *p = alphabeth [ n % 26 ]; if (n / 26 == 0) break; n = n / 26 - 1; } while (1); return (char *)strdup (p); } int create_coord (char ** pcoord, U16 row, U16 col, int relrow, int relcol) { char * scol; assert_return (xls2xml, pcoord != NULL, 19); *pcoord = (char *)malloc (19); /* max string is $xxx65535$xxx65535 */ test (*pcoord != NULL, 10); (*pcoord)[0] = 0; row++; /* there are not row zero */ switch (parameters->this_refmode) { case REFMODE_A1: scol = alpha_col (col); test (scol != NULL, 10); if (relrow) if (relcol) sprintf (*pcoord, "%s%d", scol, row); else sprintf (*pcoord, "$%s%d", scol, row); else if (relcol) sprintf (*pcoord, "%s$%d", scol, row); else sprintf (*pcoord, "$%s$%d", scol, row); free (scol); break; case REFMODE_R1C1: if (relrow) if (relcol) sprintf (*pcoord, "R%dC%d", row, col); else sprintf (*pcoord, "$R%dC%d", row, col); else if (relcol) sprintf (*pcoord, "R%d$C%d", row, col); else sprintf (*pcoord, "$R%d$C%d", row, col); break; default: report_bug (xls2xml); return 19; } return 0; } int create_cell_coord (xmlNodePtr cell, U16 row, U16 col) { char * coord; assert_return (xls2xml, cell != NULL, 19); test_call (create_coord (&coord, row, col, 1, 1), int); test_exitf (xmlSetProp (cell, (unsigned char *)"coord", (unsigned char *)coord) != NULL, 10, free (coord)); free (coord); return 0; } int create_new_sheet (xmlNodePtr * psheet) { char number[6]; /* max number 65535 */ U16 flags; xmlNodePtr sheet; sheet = xmlNewChild (parameters->xml_tree_shortcuts.sheets, NULL, (unsigned char *)"sheet", NULL); test (sheet != NULL, 10); if (psheet != NULL) *psheet = sheet; test (xmlNewChild (sheet, NULL, (unsigned char *)"cells", NULL) != NULL, 10); if (parameters->xml_tree_shortcuts.first_sheet == NULL) parameters->xml_tree_shortcuts.first_sheet = sheet; /* refnum */ sprintf (number, "%d", parameters->next_sheet_refnum); parameters->next_sheet_refnum++; test (xmlSetProp (sheet, (unsigned char *)"refnum", (unsigned char *)number) != NULL, 10); /* name */ switch (parameters->biff_version) { case BIFF_5_7: *(parameters->record.info + 4) = *(parameters->record.info + 6); *(parameters->record.info + 5) = 0x00; *(parameters->record.info + 6) = 0x00; test_call (write_unicode_xml_child (sheet, NULL, "name", parameters->record.info+4, 3+_xls2xml_sreadU16 (parameters->record.info+4), NULL), int); break; case BIFF_8: *(parameters->record.info + 5) = *(parameters->record.info + 6); *(parameters->record.info + 6) = *(parameters->record.info + 7); *(parameters->record.info + 7) = 0x00; test_call (write_unicode_xml_child (sheet, NULL, "name", parameters->record.info+5, 3+_xls2xml_sreadU16 (parameters->record.info+5), NULL), int); break; default: return 15; } flags = _xls2xml_sreadU16 (parameters->record.info+4); /* hidden */ switch (flags & 0x03) { default: test (xmlNewChild (sheet, NULL, (unsigned char *)"hidden", (unsigned char *)"no") != NULL, 10); break; case 0x01: test (xmlNewChild (sheet, NULL, (unsigned char *)"hidden", (unsigned char *)"yes") != NULL, 10); break; case 0x02: test (xmlNewChild (sheet, NULL, (unsigned char *)"hidden", (unsigned char *)"very") != NULL, 10); break; } return 0; } xmlNodePtr search_child (char * name, xmlNodePtr node) { xmlNodePtr child; for (child = node->childs; child != NULL; child = child->next) if (!strcmp ((char *)child->name, name)) return child; return NULL; }