diff --git a/xlhtml/Makefile.am b/xlhtml/Makefile.am index 0c02a1f..fe450ea 100644 --- a/xlhtml/Makefile.am +++ b/xlhtml/Makefile.am @@ -9,7 +9,7 @@ man_MANS = xlhtml.1 bin_SCRIPTS = nsopen nsxlview bin_PROGRAMS = xlhtml LDADD = ../cole/libcole.a -lm -xlhtml_SOURCES = support.c xlhtml.c html.c ascii.c xml.c +xlhtml_SOURCES = support.c xlhtml.c html.c ascii.c xml.c setupExtraction.c engine.c xldump_SOURCES = xldump.c xlcdump_SOURCES = xlcdump.c AM_CFLAGS = -Wall -Wshadow -Wcast-align -Wpointer-arith diff --git a/xlhtml/Makefile.in b/xlhtml/Makefile.in index ecf9d6e..6c00539 100644 --- a/xlhtml/Makefile.in +++ b/xlhtml/Makefile.in @@ -83,9 +83,10 @@ man_MANS = xlhtml.1 bin_SCRIPTS = nsopen nsxlview bin_PROGRAMS = xlhtml LDADD = ../cole/libcole.a -lm -xlhtml_SOURCES = support.c xlhtml.c html.c ascii.c xml.c +xlhtml_SOURCES = support.c xlhtml.c html.c ascii.c xml.c setupExtraction.c engine.c xldump_SOURCES = xldump.c xlcdump_SOURCES = xlcdump.c +AM_CFLAGS = -Wall -Wshadow -Wcast-align -Wpointer-arith mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = ../config.h CONFIG_CLEAN_FILES = @@ -96,7 +97,8 @@ DEFS = @DEFS@ -I. -I$(srcdir) -I.. CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ -xlhtml_OBJECTS = support.o xlhtml.o html.o ascii.o xml.o +xlhtml_OBJECTS = support.o xlhtml.o html.o ascii.o xml.o \ +setupExtraction.o engine.o xlhtml_LDADD = $(LDADD) xlhtml_DEPENDENCIES = ../cole/libcole.a xlhtml_LDFLAGS = @@ -109,7 +111,6 @@ xlcdump_LDADD = $(LDADD) xlcdump_DEPENDENCIES = ../cole/libcole.a xlcdump_LDFLAGS = SCRIPTS = $(bin_SCRIPTS) $(noinst_SCRIPTS) -AM_CFLAGS = -Wall -Wshadow -Wcast-align -Wpointer-arith CFLAGS = @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -384,6 +385,7 @@ install-am install uninstall-am uninstall all-redirect all-am all \ installdirs mostlyclean-generic distclean-generic clean-generic \ maintainer-clean-generic clean mostlyclean distclean maintainer-clean + doc: doxygen.conf xlhtml.c ascii.c xml.c html.c support.c xlhtml.h tuneable.h @echo Generating documentation... doxygen doxygen.conf diff --git a/xlhtml/ascii.c b/xlhtml/ascii.c index 24e834f..0b6a046 100644 --- a/xlhtml/ascii.c +++ b/xlhtml/ascii.c @@ -26,78 +26,85 @@ -void OutputPartialTableAscii(void) +void +OutputPartialTableAscii (void) { - int i, j, k; + int i, j, k; - SetupExtraction(); + SetupExtraction (); - /* Here's where we dump the Html Page out */ - for (i=first_sheet; i<=last_sheet; i++) /* For each worksheet */ + /* Here's where we dump the Html Page out */ + for (i = first_sheet; i <= last_sheet; i++) /* For each worksheet */ + { + if (ws_array[i] == 0) + continue; + if ((ws_array[i]->biggest_row == -1) + || (ws_array[i]->biggest_col == -1)) + continue; + if (ws_array[i]->c_array == 0) + continue; + + /* Now dump the table */ + for (j = ws_array[i]->first_row; j <= ws_array[i]->biggest_row; j++) { - if (ws_array[i] == 0) - continue; - if ((ws_array[i]->biggest_row == -1)||(ws_array[i]->biggest_col == -1)) - continue; - if (ws_array[i]->c_array == 0) - continue; + for (k = ws_array[i]->first_col; k <= ws_array[i]->biggest_col; k++) + { + int safe, numeric = 0; + cell *c = ws_array[i]->c_array[(j * ws_array[i]->max_cols) + k]; /* This stuff happens for each cell... */ - /* Now dump the table */ - for (j=ws_array[i]->first_row; j<=ws_array[i]->biggest_row; j++) + if (c) { - for (k=ws_array[i]->first_col; k<=ws_array[i]->biggest_col; k++) - { - int safe, numeric=0; - cell *c = ws_array[i]->c_array[(j*ws_array[i]->max_cols)+k]; /* This stuff happens for each cell... */ + numeric = IsCellNumeric (c); + if (!numeric && Csv) + printf ("\""); + safe = IsCellSafe (c); - if (c) - { - numeric = IsCellNumeric(c); - if (!numeric && Csv) - printf("\""); - safe = IsCellSafe(c); - - if (c->ustr.str) - { - if (safe) - output_formatted_data(&(c->ustr), xf_array[c->xfmt]->fmt_idx, numeric, IsCellFormula(c)); - else - OutputString(&(c->ustr)); - } - else if (!Csv) - printf(" "); /* Empty cell... */ - } - else - { /* Empty cell... */ - if (!Csv) - printf(" "); - else - printf("\""); - } - if (ws_array[i]->c_array[(j*ws_array[i]->max_cols)+k]) /* Honor Column spanning ? */ - { - if (ws_array[i]->c_array[(j*ws_array[i]->max_cols)+k]->colspan != 0) - k += ws_array[i]->c_array[(j*ws_array[i]->max_cols)+k]->colspan-1; - } - if (!numeric && Csv) - printf("\""); - - if (Csv && (k < ws_array[i]->biggest_col)) - { /* big cheat here: quoting everything! */ - putchar(','); /* Csv Cell Separator */ - } - else - { - if (( !Csv )&&( k != ws_array[i]->biggest_col )) - putchar('\t'); /* Ascii Cell Separator */ - } - } - if (Csv) - printf("\r\n"); - else - putchar(0x0A); /* Row Separator */ + if (c->ustr.str) + { + if (safe) + output_formatted_data (&(c->ustr), + xf_array[c->xfmt]->fmt_idx, + numeric, IsCellFormula (c)); + else + OutputString (&(c->ustr)); + } + else if (!Csv) + printf (" "); /* Empty cell... */ } - if (!Csv) - printf("\n\n"); /* End of Table 2 LF-CR */ + else + { /* Empty cell... */ + if (!Csv) + printf (" "); + else + printf ("\""); + } + if (ws_array[i]->c_array[(j * ws_array[i]->max_cols) + k]) /* Honor Column spanning ? */ + { + if (ws_array[i]->c_array[(j * ws_array[i]->max_cols) + k]-> + colspan != 0) + k += + ws_array[i]->c_array[(j * ws_array[i]->max_cols) + + k]->colspan - 1; + } + if (!numeric && Csv) + printf ("\""); + + if (Csv && (k < ws_array[i]->biggest_col)) + { /* big cheat here: quoting everything! */ + putchar (','); /* Csv Cell Separator */ + } + else + { + if ((!Csv) && (k != ws_array[i]->biggest_col)) + putchar ('\t'); /* Ascii Cell Separator */ + } + } + if (Csv) + printf ("\r\n"); + else + putchar (0x0A); /* Row Separator */ } + if (!Csv) + printf ("\n\n"); /* End of Table 2 LF-CR */ + } } diff --git a/xlhtml/html.c b/xlhtml/html.c index b13b8b8..3c40404 100644 --- a/xlhtml/html.c +++ b/xlhtml/html.c @@ -28,372 +28,395 @@ /* prototypes for functions in this file */ -void output_header(void); -void output_footer(void); +void output_header (void); +void output_footer (void); -void OutputTableHTML(void) +void +OutputTableHTML (void) { - int i, j, k; + int i, j, k; - output_header(); - if (center_tables) + output_header (); + if (center_tables) + { + printf ("
"); + do_cr (); + } + + SetupExtraction (); + + /* Here's where we dump the Html Page out */ + for (i = first_sheet; i <= last_sheet; i++) /* For each worksheet */ + { + update_default_font (i); + if (ws_array[i] == 0) + continue; + if ((ws_array[i]->biggest_row == -1) + || (ws_array[i]->biggest_col == -1)) + continue; + if (ws_array[i]->c_array == 0) + continue; + trim_sheet_edges (i); + + /* Print its name */ + if (next_ws_title > 0) { - printf("
"); - do_cr(); + if (ws_array[i]->ws_title.str) + { + printf ("

"); + OutputString (&ws_array[i]->ws_title); + printf ("


"); + do_cr (); + } + else + { + printf ("

(Unknown Page)


"); + do_cr (); + } } - SetupExtraction(); - - /* Here's where we dump the Html Page out */ - for (i=first_sheet; i<=last_sheet; i++) /* For each worksheet */ + /* Now dump the table */ + printf (""); + do_cr (); + printf (""); + do_cr (); + if (TableHeaders) { - update_default_font(i); - if (ws_array[i] == 0) - continue; - if ((ws_array[i]->biggest_row == -1)||(ws_array[i]->biggest_col == -1)) - continue; - if (ws_array[i]->c_array == 0) - continue; - trim_sheet_edges(i); - - /* Print its name */ - if (next_ws_title > 0) + printf (""); + for (k = ws_array[i]->first_col; k <= ws_array[i]->biggest_col; k++) + { + char col_hdr[3]; + if (k < 26) { - if (ws_array[i]->ws_title.str) - { - printf("

"); - OutputString(&ws_array[i]->ws_title); - printf("


"); - do_cr(); - } - else - { - printf("

(Unknown Page)


"); - do_cr(); - } + col_hdr[0] = 'A' + (k % 26); + col_hdr[1] = '\0'; } - - /* Now dump the table */ - printf(""); - do_cr(); - printf("
"); - do_cr(); - if (TableHeaders) + else { - printf(""); - for (k=ws_array[i]->first_col; k<=ws_array[i]->biggest_col; k++) - { - char col_hdr[3]; - if (k < 26) - { - col_hdr[0]='A' + (k % 26); - col_hdr[1]='\0'; - } - else - { - col_hdr[0]='A' - 1 + (k / 26); - col_hdr[1]='A' + (k % 26); - col_hdr[2]='\0'; - } - printf("")); - } - printf("\n"); + col_hdr[0] = 'A' - 1 + (k / 26); + col_hdr[1] = 'A' + (k % 26); + col_hdr[2] = '\0'; } - for (j=ws_array[i]->first_row; j<=ws_array[i]->biggest_row; j++) + printf ("")); + } + printf ("\n"); + } + for (j = ws_array[i]->first_row; j <= ws_array[i]->biggest_row; j++) + { + update_default_alignment (i, j); + printf (""); + else + { + if (strcmp (default_alignment, "left") != 0) + printf (" ALIGN=\"%s\"", default_alignment); + if (!aggressive) + printf (" VALIGN=\"bottom\">\n"); + else + printf (">"); + } + if (TableHeaders) + printf ("")); + for (k = ws_array[i]->first_col; k <= ws_array[i]->biggest_col; k++) + { + output_cell (ws_array[i]->c_array[(j * ws_array[i]->max_cols) + k], 0); /* This stuff happens for each cell... */ + if (ws_array[i]->c_array[(j * ws_array[i]->max_cols) + k]) { - update_default_alignment(i, j); - printf(""); - else - { - if (strcmp(default_alignment, "left") != 0) - printf(" ALIGN=\"%s\"", default_alignment); - if (!aggressive) - printf(" VALIGN=\"bottom\">\n"); - else - printf(">"); - } - if (TableHeaders) - printf("")); - for (k=ws_array[i]->first_col; k<=ws_array[i]->biggest_col; k++) - { - output_cell(ws_array[i]->c_array[(j*ws_array[i]->max_cols)+k],0); /* This stuff happens for each cell... */ - if (ws_array[i]->c_array[(j*ws_array[i]->max_cols)+k]) - { - if (ws_array[i]->c_array[(j*ws_array[i]->max_cols)+k]->colspan != 0) - k += ws_array[i]->c_array[(j*ws_array[i]->max_cols)+k]->colspan-1; - } - } - - if (!aggressive) - printf("\n"); + if (ws_array[i]->c_array[(j * ws_array[i]->max_cols) + k]-> + colspan != 0) + k += + ws_array[i]->c_array[(j * ws_array[i]->max_cols) + + k]->colspan - 1; } - printf("
%s%s",col_hdr,(aggressive ? "" : "
%s%s", col_hdr, (aggressive ? "" : "
%d%s", j + 1, (aggressive ? "" : "%d%s",j+1,(aggressive ? "" : "

"); - do_cr(); - } + } - if (center_tables) - { - printf("
"); - do_cr(); + if (!aggressive) + printf ("\n"); } + printf ("
"); + do_cr (); + } - /* Print the author's name in itallics... */ - if (author.str) - { - printf("Spreadsheet's Author: "); - OutputString(&author); - printf("
"); - do_cr(); - } + if (center_tables) + { + printf ("
"); + do_cr (); + } - /* Print when & how the file was last updated. */ - printf("Last Updated "); - if (lastUpdated) - printf("%s  ", lastUpdated); - switch (file_version) - { - case EXCEL95: - printf("with Excel 5.0 or 95"); - break; - case EXCEL97: - printf("with Excel 97"); - break; - default: - printf("with Excel ????"); - break; - } - printf("
"); - do_cr(); + /* Print the author's name in itallics... */ + if (author.str) + { + printf ("Spreadsheet's Author: "); + OutputString (&author); + printf ("
"); + do_cr (); + } - /* Next print Disclaimers... */ - if (NoFormat) - { - printf("
* This cell's format is not supported.
"); - do_cr(); - } - if ((notAccurate)&&(formula_warnings)) - { - printf("
** This cell's data may not be accurate.
"); - do_cr(); - } - if (NotImplemented) - { - printf("
*** This cell's data type will be supported in the future.
"); - do_cr(); - } - if (Unsupported) - { - printf("
**** This cell's type is unsupported.
"); - do_cr(); - } + /* Print when & how the file was last updated. */ + printf ("Last Updated "); + if (lastUpdated) + printf ("%s  ", lastUpdated); + switch (file_version) + { + case EXCEL95: + printf ("with Excel 5.0 or 95"); + break; + case EXCEL97: + printf ("with Excel 97"); + break; + default: + printf ("with Excel ????"); + break; + } + printf ("
"); + do_cr (); - /* Now out exceeded capacity warnings... */ - if (MaxWorksheetsExceeded || MaxRowExceeded || MaxColExceeded || MaxStringsExceeded || - MaxFontsExceeded || MaxPalExceeded || MaxXFExceeded || MaxFormatsExceeded ) - printf("", colorTab[0x0A]); - if (MaxWorksheetsExceeded) - { - printf("The Maximum Number of Worksheets was exceeded, you might want to increase it.
"); - do_cr(); - } - if (MaxRowExceeded) - { - printf("The Maximum Number of Rows was exceeded, you might want to increase it.
"); - do_cr(); - } - if (MaxColExceeded) - { - printf("The Maximum Number of Columns was exceeded, you might want to increase it.
"); - do_cr(); - } - if (MaxStringsExceeded) - { - printf("The Maximum Number of Strings was exceeded, you might want to increase it.
"); - do_cr(); - } - if (MaxFontsExceeded) - { - printf("The Maximum Number of Fonts was exceeded, you might want to increase it.
"); - do_cr(); - } - if (MaxPalExceeded) - { - printf("The Maximum Number of Color Palettes was exceeded, you might want to increase it.
"); - do_cr(); - } - if (MaxXFExceeded) - { - printf("The Maximum Number of Extended Formats was exceeded, you might want to increase it.
"); - do_cr(); - } - if (MaxFormatsExceeded) - { - printf("The Maximum Number of Formats was exceeded, you might want to increase it.
"); - do_cr(); - } - if (MaxWorksheetsExceeded || MaxRowExceeded || MaxColExceeded || MaxStringsExceeded || - MaxFontsExceeded || MaxPalExceeded || MaxXFExceeded || MaxFormatsExceeded ) - printf("
"); + /* Next print Disclaimers... */ + if (NoFormat) + { + printf ("
* This cell's format is not supported.
"); + do_cr (); + } + if ((notAccurate) && (formula_warnings)) + { + printf ("
** This cell's data may not be accurate.
"); + do_cr (); + } + if (NotImplemented) + { + printf + ("
*** This cell's data type will be supported in the future.
"); + do_cr (); + } + if (Unsupported) + { + printf ("
**** This cell's type is unsupported.
"); + do_cr (); + } - printf(" 
"); - do_cr(); + /* Now out exceeded capacity warnings... */ + if (MaxWorksheetsExceeded || MaxRowExceeded || MaxColExceeded + || MaxStringsExceeded || MaxFontsExceeded || MaxPalExceeded + || MaxXFExceeded || MaxFormatsExceeded) + printf ("", colorTab[0x0A]); + if (MaxWorksheetsExceeded) + { + printf + ("The Maximum Number of Worksheets was exceeded, you might want to increase it.
"); + do_cr (); + } + if (MaxRowExceeded) + { + printf + ("The Maximum Number of Rows was exceeded, you might want to increase it.
"); + do_cr (); + } + if (MaxColExceeded) + { + printf + ("The Maximum Number of Columns was exceeded, you might want to increase it.
"); + do_cr (); + } + if (MaxStringsExceeded) + { + printf + ("The Maximum Number of Strings was exceeded, you might want to increase it.
"); + do_cr (); + } + if (MaxFontsExceeded) + { + printf + ("The Maximum Number of Fonts was exceeded, you might want to increase it.
"); + do_cr (); + } + if (MaxPalExceeded) + { + printf + ("The Maximum Number of Color Palettes was exceeded, you might want to increase it.
"); + do_cr (); + } + if (MaxXFExceeded) + { + printf + ("The Maximum Number of Extended Formats was exceeded, you might want to increase it.
"); + do_cr (); + } + if (MaxFormatsExceeded) + { + printf + ("The Maximum Number of Formats was exceeded, you might want to increase it.
"); + do_cr (); + } + if (MaxWorksheetsExceeded || MaxRowExceeded || MaxColExceeded + || MaxStringsExceeded || MaxFontsExceeded || MaxPalExceeded + || MaxXFExceeded || MaxFormatsExceeded) + printf ("
"); - /* Output Credit */ - printf("
Created with xlhtml %s
", VERSION); - do_cr(); + printf (" 
"); + do_cr (); - /* Output Tail */ - output_footer(); + /* Output Credit */ + printf + ("
Created with xlhtml %s
", + VERSION); + do_cr (); + + /* Output Tail */ + output_footer (); } -void output_header(void) -{ /* Ouput Header */ - if (NoHeaders) - return; - if (!aggressive) +void +output_header (void) +{ /* Ouput Header */ + if (NoHeaders) + return; + if (!aggressive) + { + printf (""); + do_cr (); + } + printf ("\n"); + printf ("\n"); + do_cr (); + printf ("", CodePage); + else + { + switch (UnicodeStrings) { - printf(""); - do_cr(); + case 0: + printf ("iso-8859-1\">"); /* Latin-1 */ + break; + case 1: + printf ("windows-1252\">"); /* Microsoft */ + break; + default: + printf ("utf-8\">"); /* Unicode */ + break; } - printf("\n"); - printf("\n"); - do_cr(); - printf("", CodePage); - else - { - switch (UnicodeStrings) - { - case 0: - printf("iso-8859-1\">"); /* Latin-1 */ - break; - case 1: - printf("windows-1252\">"); /* Microsoft */ - break; - default: - printf("utf-8\">"); /* Unicode */ - break; - } - } - do_cr(); + } + do_cr (); - if (!aggressive) - { - printf(""); - do_cr(); - } - printf(""); - if (title) - printf("%s", title); - else - printf("%s", filename); - printf(""); - do_cr(); - printf(""); - do_cr(); - do_cr(); - printf("
"); - do_cr(); + if (!aggressive) + { + printf (""); + do_cr (); + } + printf (""); + if (title) + printf ("%s", title); + else + printf ("%s", filename); + printf (""); + do_cr (); + printf (""); + do_cr (); + do_cr (); + printf ("
"); + do_cr (); } -void output_footer(void) +void +output_footer (void) { - if (NoHeaders) - return; - printf(""); - do_cr(); - fflush(stdout); + if (NoHeaders) + return; + printf (""); + do_cr (); + fflush (stdout); } -void output_start_html_attr(html_attr *h, unsigned int fnt_idx, int do_underlines) +void +output_start_html_attr (html_attr * h, unsigned int fnt_idx, + int do_underlines) { - if (fnt_idx < next_font) + if (fnt_idx < next_font) + { + if (((font_array[fnt_idx]->underline & 0x0023) > 0) && (do_underlines)) { - if (((font_array[fnt_idx]->underline&0x0023) > 0)&&(do_underlines)) - { - printf(""); - h->uflag = 1; - } - if (font_array[fnt_idx]->bold >= 0x02BC) - { - h->bflag = 1; - printf(""); - } - if (font_array[fnt_idx]->attr & 0x0002) - { - h->iflag = 1; - printf(""); - } - if (font_array[fnt_idx]->attr & 0x0008) - { - h->sflag = 1; - printf(""); - } - if ((font_array[fnt_idx]->super & 0x0003) == 0x0001) - { - h->spflag = 1; - printf(""); - } - else if ((font_array[fnt_idx]->super & 0x0003) == 0x0002) - { - h->sbflag = 1; - printf(""); - } + printf (""); + h->uflag = 1; } + if (font_array[fnt_idx]->bold >= 0x02BC) + { + h->bflag = 1; + printf (""); + } + if (font_array[fnt_idx]->attr & 0x0002) + { + h->iflag = 1; + printf (""); + } + if (font_array[fnt_idx]->attr & 0x0008) + { + h->sflag = 1; + printf (""); + } + if ((font_array[fnt_idx]->super & 0x0003) == 0x0001) + { + h->spflag = 1; + printf (""); + } + else if ((font_array[fnt_idx]->super & 0x0003) == 0x0002) + { + h->sbflag = 1; + printf (""); + } + } } -void output_end_html_attr(html_attr *h) +void +output_end_html_attr (html_attr * h) { - if (h->sbflag) - { - printf(""); - h->sbflag = 0; - } - else if (h->spflag) - { - printf(""); - h->spflag = 0; - } - if (h->sflag) - { - printf(""); - h->sflag = 0; - } - if (h->iflag) - { - printf(""); - h->iflag = 0; - } - if (h->bflag) - { - printf(""); - h->bflag = 0; - } - if (h->uflag) - { - if (h->uflag == 1) - printf(""); - else - printf(""); - h->uflag = 0; - } - if (h->fflag) - { - printf(""); - h->fflag = 0; - } + if (h->sbflag) + { + printf (""); + h->sbflag = 0; + } + else if (h->spflag) + { + printf (""); + h->spflag = 0; + } + if (h->sflag) + { + printf (""); + h->sflag = 0; + } + if (h->iflag) + { + printf (""); + h->iflag = 0; + } + if (h->bflag) + { + printf (""); + h->bflag = 0; + } + if (h->uflag) + { + if (h->uflag == 1) + printf (""); + else + printf (""); + h->uflag = 0; + } + if (h->fflag) + { + printf (""); + h->fflag = 0; + } } diff --git a/xlhtml/setupExtraction.c b/xlhtml/setupExtraction.c new file mode 100644 index 0000000..cb545aa --- /dev/null +++ b/xlhtml/setupExtraction.c @@ -0,0 +1,94 @@ + +#include +#include "xlhtml.h" +#include "support.h" + +extern int Xtract; +extern int xp; +extern int sheet_count; +extern int xr1 ; +extern int xr2 ; +extern int xc1 ; +extern int xc2 ; +extern int Ascii; + + + +void +SetupExtraction (void) +{ + if (Xtract) + { /* Revise the page settings... */ +/* printf("-%d %d %d %d %d
\n", xp, xr1, xr2, xc1, xc2); */ + if ((xp >= first_sheet) && (xp <= last_sheet) && (xp <= sheet_count)) + { + first_sheet = xp; + last_sheet = xp; + if (xr1 < 0) + { + xr1 = (S16) ws_array[xp]->first_row; + xr2 = (S16) ws_array[xp]->biggest_row; + } + else if ((xr1 >= ws_array[xp]->first_row) + && (xr1 <= ws_array[xp]->biggest_row) + && (xr2 >= ws_array[xp]->first_row) + && (xr2 <= ws_array[xp]->biggest_row)) + { + ws_array[xp]->first_row = xr1; + ws_array[xp]->biggest_row = xr2; + } + else + { + if (Ascii) + fprintf (stderr, "Error - Row not in range during extraction" + " (%d or %d not in [%ld..%ld])\n", xr1, xr2, + (long) ws_array[xp]->first_row, + (long) ws_array[xp]->biggest_row); + else + { + printf ("Error - Row not in range during extraction."); + output_footer (); + } + return; + } + + if (xc1 < 0) + { + xc1 = ws_array[xp]->first_col; + xc2 = ws_array[xp]->biggest_col; + } + else if ((xc1 >= ws_array[xp]->first_col) + && (xc1 <= ws_array[xp]->biggest_col) + && (xc2 >= ws_array[xp]->first_col) + && (xc2 <= ws_array[xp]->biggest_col)) + { + ws_array[xp]->first_col = xc1; + ws_array[xp]->biggest_col = xc2; + } + else + { + if (Ascii) + fprintf (stderr, "Error - Col not in range during extraction" + " (%d or %d not in [%d..%d])\n", xc1, xc2, + ws_array[xp]->first_col, ws_array[xp]->biggest_col); + else + { + printf ("Error - Col not in range during extraction.\n"); + output_footer (); + } + return; + } + } + else + { + if (Ascii) + fprintf (stderr, "Error - Page not in range during extraction."); + else + { + printf ("Error - Page not in range during extraction."); + output_footer (); + } + return; + } + } +} diff --git a/xlhtml/support.c b/xlhtml/support.c index 9b377ab..8d777ba 100644 --- a/xlhtml/support.c +++ b/xlhtml/support.c @@ -28,195 +28,207 @@ #include -int DatesR1904 = 0; /*!< Flag that the dates are based on McIntosh Dates system */ +int DatesR1904 = 0; /*!< Flag that the dates are based on McIntosh Dates system */ -void print_version(void) +void +print_version (void) { - printf("xlhtml %s \nCopyright (c) 1999-2002, Charles Wyble\n" - "Released under GPL.\n", VERSION ); - exit(0); + printf ("xlhtml %s \nCopyright (c) 1999-2002, Charles Wyble\n" + "Released under GPL.\n", VERSION); + exit (0); } -void display_usage(void) +void +display_usage (void) { -fprintf(stderr, "\nxlhtml converts excel files (.xls) to Html.\n" - "Copyright (c) 1999-2001, Charles Wyble. Released under GPL.\n" -"Usage: xlhtml [-xp:# -xc:#-# -xr:#-# -bc###### -bi???????? -tc######] \n" - "\t-a: aggressive html optimization\n" - "\t-asc ascii output for -dp & -x? options\n" - "\t-csv comma separated value output for -dp & -x? options\n" - "\t-xml XML output\n" - "\t-bc: Set default background color - default white\n" - "\t-bi: Set background image path\n" - "\t-c: Center justify tables\n" - "\t-dp: Dumps page count and max rows & colums per page\n" - "\t-v: Prints program version number\n" - "\t-fw: Suppress formula warnings\n" - "\t-m: No encoding for multibyte\n" - "\t-nc: No Colors - black & white\n" - "\t-nh: No Html Headers\n" - "\t-tc: Set default text color - default black\n" - "\t-te: Trims empty rows & columns at the edges of a worksheet\n" - "\t-xc: Columns (separated by a dash) for extraction (zero based)\n" - "\t-xp: Page extracted (zero based)\n" - "\t-xr: Rows (separated by a dash) to be extracted (zero based)\n"); - fprintf(stderr, "\nReport bugs to jackshck@thewybles.com\n"); - exit (1); + fprintf (stderr, "\nxlhtml converts excel files (.xls) to Html.\n" + "Copyright (c) 1999-2001, Charles Wyble. Released under GPL.\n" + "Usage: xlhtml [-xp:# -xc:#-# -xr:#-# -bc###### -bi???????? -tc######] \n" + "\t-a: aggressive html optimization\n" + "\t-asc ascii output for -dp & -x? options\n" + "\t-csv comma separated value output for -dp & -x? options\n" + "\t-xml XML output\n" + "\t-bc: Set default background color - default white\n" + "\t-bi: Set background image path\n" + "\t-c: Center justify tables\n" + "\t-dp: Dumps page count and max rows & colums per page\n" + "\t-v: Prints program version number\n" + "\t-fw: Suppress formula warnings\n" + "\t-m: No encoding for multibyte\n" + "\t-nc: No Colors - black & white\n" + "\t-nh: No Html Headers\n" + "\t-tc: Set default text color - default black\n" + "\t-te: Trims empty rows & columns at the edges of a worksheet\n" + "\t-xc: Columns (separated by a dash) for extraction (zero based)\n" + "\t-xp: Page extracted (zero based)\n" + "\t-xr: Rows (separated by a dash) to be extracted (zero based)\n"); + fprintf (stderr, "\nReport bugs to jackshck@thewybles.com\n"); + exit (1); } -void do_cr(void) +void +do_cr (void) { - extern int aggressive; - if (!aggressive) - putchar('\n'); + extern int aggressive; + if (!aggressive) + putchar ('\n'); } -U16 getShort(U8 *ptr) +U16 +getShort (U8 * ptr) { - if (ptr == 0) - return (U16)0; - - return (U16)((*(ptr+1)<<8)+*ptr); + if (ptr == 0) + return (U16) 0; + + return (U16) ((*(ptr + 1) << 8) + *ptr); } /*! This is used in the RK number, so signedness counts */ -S32 getLong(U8 *ptr) +S32 +getLong (U8 * ptr) { - if (ptr == 0) - return (S32)0; + if (ptr == 0) + return (S32) 0; - return (S32)(*(ptr+3)<<24)+(*(ptr+2)<<16)+(*(ptr+1)<<8)+*ptr; + return (S32) (*(ptr + 3) << 24) + (*(ptr + 2) << 16) + (*(ptr + 1) << 8) + + *ptr; } -#ifndef WORDS_BIGENDIAN /* Defined in */ +#ifndef WORDS_BIGENDIAN /* Defined in */ #ifdef __arm__ /* cross-endian doubles in little endian ARM */ -void getDouble(U8 *ptr, F64 *d) +void +getDouble (U8 * ptr, F64 * d) { - size_t i; - F64 dd; - U8 *t = (U8 *)ⅆ + size_t i; + F64 dd; + U8 *t = (U8 *) & dd; - for (i=0; i (((y%4) == 0) ? 366 : 365)) - num -= ((y++%4) == 0) ? 366 : 365; + int t, i, y = 0; - *year = y; - t = num; - if (DatesR1904) - *year += 4; /* Adjust for McIntosh... */ - if ((*year%4) == 0) - { /* Leap Year */ - for (i=0; i<12; i++) - { - if (t <= ldays[i]) - break; - t -= ldays[i]; - } - } - else + num = num % 36525L; /* Trim century */ + while (num > (((y % 4) == 0) ? 366 : 365)) + num -= ((y++ % 4) == 0) ? 366 : 365; + + *year = y; + t = num; + if (DatesR1904) + *year += 4; /* Adjust for McIntosh... */ + if ((*year % 4) == 0) + { /* Leap Year */ + for (i = 0; i < 12; i++) { - for (i=0; i<12; i++) - { - if (t <= ndays[i]) - break; - t -= ndays[i]; - } + if (t <= ldays[i]) + break; + t -= ldays[i]; } - /* Some fixups... */ - *month = 1+i; - if (t == 0) - t = 1; - *day = t; - *year = *year % 100; + } + else + { + for (i = 0; i < 12; i++) + { + if (t <= ndays[i]) + break; + t -= ndays[i]; + } + } + /* Some fixups... */ + *month = 1 + i; + if (t == 0) + t = 1; + *day = t; + *year = *year % 100; } typedef S32 swords[2]; @@ -224,30 +236,34 @@ typedef S32 swords[2]; #define noaliasdub(type,ptr) \ (((union{swords sw; F64 dub;} *)(ptr))->sw) -#ifndef WORDS_BIGENDIAN /*! Defined in */ +#ifndef WORDS_BIGENDIAN /*! Defined in */ #ifdef __arm__ /* cross-endian doubles in little endian ARM */ -void RKtoDouble(S32 n, F64 *d) +void +RKtoDouble (S32 n, F64 * d) { - noaliasdub(swords,d)[0] = n << 2; - noaliasdub(swords,d)[1] = 0; + noaliasdub (swords, d)[0] = n << 2; + noaliasdub (swords, d)[1] = 0; } #else /*! Little Endian - 0x86 family */ -void RKtoDouble(S32 n, F64 *d) +void +RKtoDouble (S32 n, F64 * d) { - noaliasdub(swords,d)[0] = 0; - noaliasdub(swords,d)[1] = n << 2; + noaliasdub (swords, d)[0] = 0; + noaliasdub (swords, d)[1] = n << 2; } #endif #else /*! Big Endian version - UltraSparc's, etc. */ -void RKtoDouble(S32 n, F64 *d) +void +RKtoDouble (S32 n, F64 * d) { - U8 *ptr = (U8 *)&n; + U8 *ptr = (U8 *) & n; - noaliasdub(swords,d)[1] = 0; - noaliasdub(swords,d)[0] = - ((*(ptr+0)<<24)+(*(ptr+1)<<16)+(*(ptr+2)<<8)+(*(ptr+3))) << 2; + noaliasdub (swords, d)[1] = 0; + noaliasdub (swords, d)[0] = + ((*(ptr + 0) << 24) + (*(ptr + 1) << 16) + (*(ptr + 2) << 8) + + (*(ptr + 3))) << 2; } #endif diff --git a/xlhtml/xlcdump.c b/xlhtml/xlcdump.c index c23d479..de8f062 100644 --- a/xlhtml/xlcdump.c +++ b/xlhtml/xlcdump.c @@ -25,22 +25,22 @@ #include /* For isprint */ -#define MODE 0 /* 0 - ascii; 1 - hex */ +#define MODE 0 /* 0 - ascii; 1 - hex */ #define TEXT 0 /* In ascii mode, 0 - ascii, 1 - hex */ #define PRGNAME "xlcdump" #define MAX_COLS 64 #define MAX_ROWS 512 -static char FileName[2][12] = /* The section of the Excel Spreadsheet we read in */ +static char FileName[2][12] = /* The section of the Excel Spreadsheet we read in */ { - "/Workbook", /* Office 97 */ - "/Book" /* Everything else ? */ + "/Workbook", /* Office 97 */ + "/Book" /* Everything else ? */ }; /* Function Prototypes */ COLE_LOCATE_ACTION_FUNC dump_file; -static void output_opcode_string(int); +static void output_opcode_string (int); /* Global data */ static char filename[128]; @@ -48,323 +48,331 @@ static char filename[128]; int aggressive = 0; /*!< Aggressive html optimization */ -int main (int argc, char **argv) +int +main (int argc, char **argv) { - int f_ptr = 0; - COLEFS * cfs; - COLERRNO colerrno; + int f_ptr = 0; + COLEFS *cfs; + COLERRNO colerrno; - if (argc < 2) + if (argc < 2) + { + fprintf (stderr, "dump - Outputs excel chart records for analysis.\n" + "Usage: " PRGNAME " \n"); + exit (1); + } + else + { + strncpy (filename, argv[1], 124); + cfs = cole_mount (filename, &colerrno); + if (cfs == NULL) { - fprintf (stderr, "dump - Outputs excel chart records for analysis.\n" - "Usage: "PRGNAME" \n"); - exit (1); - } - else - { - strncpy(filename, argv[1], 124); - cfs = cole_mount (filename, &colerrno); - if (cfs == NULL) - { - cole_perror (PRGNAME, colerrno); - exit (1); - } + cole_perror (PRGNAME, colerrno); + exit (1); } + } - while (cole_locate_filename (cfs, FileName[f_ptr], NULL, dump_file, &colerrno)) + while (cole_locate_filename + (cfs, FileName[f_ptr], NULL, dump_file, &colerrno)) + { + if (f_ptr) { - if (f_ptr) - { - cole_perror (PRGNAME, colerrno); - break; - } - else - f_ptr++; + cole_perror (PRGNAME, colerrno); + break; } + else + f_ptr++; + } - if (cole_umount (cfs, &colerrno)) - { - cole_perror ("travel", colerrno); - exit (1); - } - - return 0; + if (cole_umount (cfs, &colerrno)) + { + cole_perror ("travel", colerrno); + exit (1); + } + + return 0; } -void dump_file(COLEDIRENT *cde, void *_info) +void +dump_file (COLEDIRENT * cde, void *_info) { - unsigned int length=0, opcode=0, target=0, count = 0; - unsigned char buf[16]; - COLEFILE *cf; - COLERRNO err; + unsigned int length = 0, opcode = 0, target = 0, count = 0; + unsigned char buf[16]; + COLEFILE *cf; + COLERRNO err; - (void) _info; /*UNUSED*/ - - cf = cole_fopen_direntry(cde, &err); + (void) _info; + /*UNUSED*/ cf = cole_fopen_direntry (cde, &err); - /* Ouput Header */ - printf("\n"); - printf("%s", filename); - printf("\n"); + /* Ouput Header */ + printf ("\n"); + printf ("%s", filename); + printf ("\n"); /* Output body */ #if (MODE == 1) - while (cole_fread(cf, buf, 8, &err)) /* For mode >= 1 */ + while (cole_fread (cf, buf, 8, &err)) /* For mode >= 1 */ #else - while (cole_fread(cf, buf, 1, &err)) -#endif - { - if (MODE == 0) - { - if (count == 0) - { - length = 0; - opcode = (unsigned)buf[0]; - target = 80; /* ficticious number */ - printf("
"); - } - else if (count == 1) - opcode |= (buf[0]<<8)&0x0000FFFFL; - else if (count == 2) - length = (unsigned)buf[0]; - else if (count == 3) - { - length |= (buf[0]<<8); - target = length; - printf("
\nLength:%04X Opcode:%04X - ", length, opcode); - output_opcode_string(opcode); - puts("
\n"); - } - if (count > 3) - { /* Here is where we want to process the data */ - /* based on the opcode... */ -#if (TEXT == 0) - if (isprint(buf[0])) - putc(buf[0], stdout); -#else - printf("%02X ", buf[0]); - if (((count-3) % 8) == 0) - printf("
\n"); + while (cole_fread (cf, buf, 1, &err)) #endif - } - if (count == (target+3)) - count = 0; - else - count++; - } - else /* mode >= 1 */ - { - printf("%02x %02x %02x %02x %02x %02x %02x %02x         ", - (unsigned)buf[0], (unsigned)buf[1], (unsigned)buf[2], (unsigned)buf[3], - (unsigned)buf[4], (unsigned)buf[5], (unsigned)buf[6], (unsigned)buf[7]); - putchar(buf[0]); putchar(buf[1]); - putchar(buf[2]); putchar(buf[3]); - putchar(buf[4]); putchar(buf[5]); - putchar(buf[6]); putchar(buf[7]); - printf("
\n"); - } + { + if (MODE == 0) + { + if (count == 0) + { + length = 0; + opcode = (unsigned) buf[0]; + target = 80; /* ficticious number */ + printf ("
"); + } + else if (count == 1) + opcode |= (buf[0] << 8) & 0x0000FFFFL; + else if (count == 2) + length = (unsigned) buf[0]; + else if (count == 3) + { + length |= (buf[0] << 8); + target = length; + printf ("
\nLength:%04X Opcode:%04X - ", length, opcode); + output_opcode_string (opcode); + puts ("
\n"); + } + if (count > 3) + { /* Here is where we want to process the data */ + /* based on the opcode... */ +#if (TEXT == 0) + if (isprint (buf[0])) + putc (buf[0], stdout); +#else + printf ("%02X ", buf[0]); + if (((count - 3) % 8) == 0) + printf ("
\n"); +#endif + } + if (count == (target + 3)) + count = 0; + else + count++; } + else /* mode >= 1 */ + { + printf + ("%02x %02x %02x %02x %02x %02x %02x %02x         ", + (unsigned) buf[0], (unsigned) buf[1], (unsigned) buf[2], + (unsigned) buf[3], (unsigned) buf[4], (unsigned) buf[5], + (unsigned) buf[6], (unsigned) buf[7]); + putchar (buf[0]); + putchar (buf[1]); + putchar (buf[2]); + putchar (buf[3]); + putchar (buf[4]); + putchar (buf[5]); + putchar (buf[6]); + putchar (buf[7]); + printf ("
\n"); + } + } /* Output Tail */ - printf("\n"); - cole_fclose(cf, &err); + printf ("\n"); + cole_fclose (cf, &err); } -static void output_opcode_string(int opcode) +static void +output_opcode_string (int opcode) { - switch (opcode&0x00FF) - { + switch (opcode & 0x00FF) + { - case 0x10: - case 0x01: - puts("UNITS: Chart Units"); - break; - case 0x02: - puts("CHART: Location and overall chart dimensions"); - break; - case 0x03: - puts("SERIES: Series Definition"); - break; - case 0x06: - puts("DATAFORMAT: Series and Data Point Numbers"); - break; - case 0x07: - puts("LINEFORMAT: Style of a line or border"); - break; - case 0x09: - puts("MARKERFORMAT: Style of a line marker"); - break; - case 0x0A: - puts("AREAFORMAT: Colors and patterns for an area"); - break; - case 0x0B: - puts("PIEFORMAT: Position of the pie slice"); - break; - case 0x0C: - puts("ATTACHEDLABEL: Series data/value labels"); - break; - case 0x0D: - puts("SERIESTEXT: Legend/category/value text"); - break; - case 0x14: - puts("CHARTFORMAT: Parent record for chart group"); - break; - case 0x15: - puts("LEGEND: Legend type and position"); - break; - case 0x16: - puts("SERIESLIST: Specifies the series in an overlay chart"); - break; - case 0x17: - puts("BAR: Chart group is a bar or column chart group"); - break; - case 0x18: - puts("LINE: Chart group is a line chart group"); - break; - case 0x19: - puts("PIE: Chart group is a pie chart group"); - break; - case 0x1A: - puts("AREA: Chart group is an area chart group"); - break; - case 0x1B: - puts("SCATTER: Chart group is a scatter chart group"); - break; - case 0x1C: - puts("CHARTLINE: Drop/Hi-Lo/Series Lines on a line chart"); - break; - case 0x1D: - puts("AXIS: Axis Type"); - break; - case 0x1E: - puts("TICK: Tick marks and labels format"); - break; - case 0x1F: - puts("VALUERANGE: Defines value axis scale"); - break; - case 0x20: - puts("CATSERRANGE: Defines a category or series axis"); - break; - case 0x21: - puts("AXISLINEFORMAT: Defines a line that spans an axis"); - break; - case 0x22: - puts("CHARTFORMTLINK: Not Used"); - break; - case 0x24: - puts("DEFAULTTEXT: Default data label text properties"); - break; - case 0x25: - puts("TEXT: Defines display of text fields"); - break; - case 0x26: - puts("FONTX: Font Index"); - break; - case 0x27: - puts("OBJECTLINK: Attaches Text to chart or chart item"); - break; - case 0x32: - puts("FRAME: Defines border shape around displayed text"); - break; - case 0x33: - puts("BEGIN: Defines the beginning of an object"); - break; - case 0x34: - puts("END: Defines the end of an object"); - break; - case 0x35: - puts("PLOTAREA: Frame belongs to ploat area"); - break; - case 0x3A: - puts("3d Chart group"); - break; - case 0x3C: - puts("PICF: Picture Format"); - break; - case 0x3D: - puts("DROPBAR: Defines drop bars"); - break; - case 0x3E: - puts("RADAR: Chart group is a radar chart group"); - break; - case 0x3F: - puts("SURFACE: Chart group is a surface chart group"); - break; - case 0x40: - puts("RADARAREA: Chart group is a radar area chart group"); - break; - case 0x41: - puts("AXISPARENT: Axis size and location"); - break; - case 0x43: - puts("LEGENDXN: Legend Exception"); - break; - case 0x44: - puts("SHTPROPS: Sheet Properties"); - break; - case 0x45: - puts("SERTOCRT: Series chart-group index"); - break; - case 0x46: - puts("AXESUSED: Number of axes sets"); - break; - case 0x48: - puts("SBASEREF: PivotTable Reference"); - break; - case 0x4A: - puts("SERPARENT: Trendline or Errorbar series index"); - break; - case 0x4B: - puts("SERAUXTREND: Series trendline"); - break; - case 0x4E: - puts("IFMT: Number-Format Index"); - break; - case 0x4F: - puts("POS: Position information"); - break; - case 0x50: - puts("ALRUNS: Text formatting"); - break; - case 0x51: - puts("AI: Linked data"); - break; - case 0x5B: - puts("Series ErrorBar"); - break; - case 0x5D: - puts("SERFMT: Series Format"); - break; - case 0x60: - puts("FBI: Font Basis"); - break; - case 0x61: - puts("BOPPOP: Bar of pie/pie of pie chart options"); - break; - case 0x62: - puts("AXCEXT: Axis options"); - break; - case 0x63: - puts("DAT: Data Table Options"); - break; - case 0x64: - puts("PLOTGROWTH: Font scale factors"); - break; - case 0x65: - puts("SIINDEX: Series Index"); - break; - case 0x66: - puts("GELFRAME: Fill data"); - break; - case 0x67: - puts("Custom bar of pie/ pie of pie chart options"); - break; - default: - puts("Unknown Chart Opcode"); - break; - } + case 0x10: + case 0x01: + puts ("UNITS: Chart Units"); + break; + case 0x02: + puts ("CHART: Location and overall chart dimensions"); + break; + case 0x03: + puts ("SERIES: Series Definition"); + break; + case 0x06: + puts ("DATAFORMAT: Series and Data Point Numbers"); + break; + case 0x07: + puts ("LINEFORMAT: Style of a line or border"); + break; + case 0x09: + puts ("MARKERFORMAT: Style of a line marker"); + break; + case 0x0A: + puts ("AREAFORMAT: Colors and patterns for an area"); + break; + case 0x0B: + puts ("PIEFORMAT: Position of the pie slice"); + break; + case 0x0C: + puts ("ATTACHEDLABEL: Series data/value labels"); + break; + case 0x0D: + puts ("SERIESTEXT: Legend/category/value text"); + break; + case 0x14: + puts ("CHARTFORMAT: Parent record for chart group"); + break; + case 0x15: + puts ("LEGEND: Legend type and position"); + break; + case 0x16: + puts ("SERIESLIST: Specifies the series in an overlay chart"); + break; + case 0x17: + puts ("BAR: Chart group is a bar or column chart group"); + break; + case 0x18: + puts ("LINE: Chart group is a line chart group"); + break; + case 0x19: + puts ("PIE: Chart group is a pie chart group"); + break; + case 0x1A: + puts ("AREA: Chart group is an area chart group"); + break; + case 0x1B: + puts ("SCATTER: Chart group is a scatter chart group"); + break; + case 0x1C: + puts ("CHARTLINE: Drop/Hi-Lo/Series Lines on a line chart"); + break; + case 0x1D: + puts ("AXIS: Axis Type"); + break; + case 0x1E: + puts ("TICK: Tick marks and labels format"); + break; + case 0x1F: + puts ("VALUERANGE: Defines value axis scale"); + break; + case 0x20: + puts ("CATSERRANGE: Defines a category or series axis"); + break; + case 0x21: + puts ("AXISLINEFORMAT: Defines a line that spans an axis"); + break; + case 0x22: + puts ("CHARTFORMTLINK: Not Used"); + break; + case 0x24: + puts ("DEFAULTTEXT: Default data label text properties"); + break; + case 0x25: + puts ("TEXT: Defines display of text fields"); + break; + case 0x26: + puts ("FONTX: Font Index"); + break; + case 0x27: + puts ("OBJECTLINK: Attaches Text to chart or chart item"); + break; + case 0x32: + puts ("FRAME: Defines border shape around displayed text"); + break; + case 0x33: + puts ("BEGIN: Defines the beginning of an object"); + break; + case 0x34: + puts ("END: Defines the end of an object"); + break; + case 0x35: + puts ("PLOTAREA: Frame belongs to ploat area"); + break; + case 0x3A: + puts ("3d Chart group"); + break; + case 0x3C: + puts ("PICF: Picture Format"); + break; + case 0x3D: + puts ("DROPBAR: Defines drop bars"); + break; + case 0x3E: + puts ("RADAR: Chart group is a radar chart group"); + break; + case 0x3F: + puts ("SURFACE: Chart group is a surface chart group"); + break; + case 0x40: + puts ("RADARAREA: Chart group is a radar area chart group"); + break; + case 0x41: + puts ("AXISPARENT: Axis size and location"); + break; + case 0x43: + puts ("LEGENDXN: Legend Exception"); + break; + case 0x44: + puts ("SHTPROPS: Sheet Properties"); + break; + case 0x45: + puts ("SERTOCRT: Series chart-group index"); + break; + case 0x46: + puts ("AXESUSED: Number of axes sets"); + break; + case 0x48: + puts ("SBASEREF: PivotTable Reference"); + break; + case 0x4A: + puts ("SERPARENT: Trendline or Errorbar series index"); + break; + case 0x4B: + puts ("SERAUXTREND: Series trendline"); + break; + case 0x4E: + puts ("IFMT: Number-Format Index"); + break; + case 0x4F: + puts ("POS: Position information"); + break; + case 0x50: + puts ("ALRUNS: Text formatting"); + break; + case 0x51: + puts ("AI: Linked data"); + break; + case 0x5B: + puts ("Series ErrorBar"); + break; + case 0x5D: + puts ("SERFMT: Series Format"); + break; + case 0x60: + puts ("FBI: Font Basis"); + break; + case 0x61: + puts ("BOPPOP: Bar of pie/pie of pie chart options"); + break; + case 0x62: + puts ("AXCEXT: Axis options"); + break; + case 0x63: + puts ("DAT: Data Table Options"); + break; + case 0x64: + puts ("PLOTGROWTH: Font scale factors"); + break; + case 0x65: + puts ("SIINDEX: Series Index"); + break; + case 0x66: + puts ("GELFRAME: Fill data"); + break; + case 0x67: + puts ("Custom bar of pie/ pie of pie chart options"); + break; + default: + puts ("Unknown Chart Opcode"); + break; + } } - diff --git a/xlhtml/xldump.c b/xlhtml/xldump.c index e675645..d3d2193 100644 --- a/xlhtml/xldump.c +++ b/xlhtml/xldump.c @@ -25,23 +25,23 @@ #include /* For isprint */ -#define MODE 0 /* 0 - ascii; 1 - hex */ +#define MODE 0 /* 0 - ascii; 1 - hex */ #define TEXT 0 /* In ascii mode, 0 - ascii, 1 - hex */ #define PRGNAME "xldump" #define MAX_COLS 64 #define MAX_ROWS 512 -static char FileName[2][12] = /* The section of the Excel Spreadsheet we read in */ +static char FileName[2][12] = /* The section of the Excel Spreadsheet we read in */ { - "/Workbook", /* Office 97 */ - "/Book" /* Everything else ? */ + "/Workbook", /* Office 97 */ + "/Book" /* Everything else ? */ }; /* Function Prototypes */ COLE_LOCATE_ACTION_FUNC dump_file; /*static void main_line_processor(int opcode, char data);*/ -static void output_opcode_string(int); +static void output_opcode_string (int); /* Global data */ static char filename[128]; @@ -49,127 +49,135 @@ static char filename[128]; int aggressive = 0; /*!< Aggressive html optimization */ -int main (int argc, char **argv) +int +main (int argc, char **argv) { - int f_ptr = 0; - COLEFS * cfs; - COLERRNO colerrno; + int f_ptr = 0; + COLEFS *cfs; + COLERRNO colerrno; - if (argc < 2) + if (argc < 2) + { + fprintf (stderr, "dump - Outputs excel file records for analysis.\n" + "Usage: " PRGNAME " \n"); + exit (1); + } + else + { + strncpy (filename, argv[1], 124); + cfs = cole_mount (filename, &colerrno); + if (cfs == NULL) { - fprintf (stderr, "dump - Outputs excel file records for analysis.\n" - "Usage: "PRGNAME" \n"); - exit (1); - } - else - { - strncpy(filename, argv[1], 124); - cfs = cole_mount (filename, &colerrno); - if (cfs == NULL) - { - cole_perror (PRGNAME, colerrno); - exit (1); - } + cole_perror (PRGNAME, colerrno); + exit (1); } + } - while (cole_locate_filename (cfs, FileName[f_ptr], NULL, dump_file, &colerrno)) + while (cole_locate_filename + (cfs, FileName[f_ptr], NULL, dump_file, &colerrno)) + { + if (f_ptr) { - if (f_ptr) - { - cole_perror (PRGNAME, colerrno); - break; - } - else - f_ptr++; + cole_perror (PRGNAME, colerrno); + break; } + else + f_ptr++; + } - if (cole_umount (cfs, &colerrno)) - { - cole_perror ("travel", colerrno); - exit (1); - } - - return 0; + if (cole_umount (cfs, &colerrno)) + { + cole_perror ("travel", colerrno); + exit (1); + } + + return 0; } -void dump_file(COLEDIRENT *cde, void *_info) +void +dump_file (COLEDIRENT * cde, void *_info) { - unsigned int length=0, opcode=0, target=0, count = 0; - unsigned char buf[16]; - COLEFILE *cf; - COLERRNO err; - - (void) _info; /*UNUSED*/ + unsigned int length = 0, opcode = 0, target = 0, count = 0; + unsigned char buf[16]; + COLEFILE *cf; + COLERRNO err; - cf = cole_fopen_direntry(cde, &err); + (void) _info; + /*UNUSED*/ cf = cole_fopen_direntry (cde, &err); - /* Ouput Header */ - printf("\n"); - printf("%s", filename); - printf("\n"); + /* Ouput Header */ + printf ("\n"); + printf ("%s", filename); + printf ("\n"); /* Output body */ #if (MODE == 1) - while (cole_fread(cf, buf, 8, &err)) /* For mode >= 1 */ + while (cole_fread (cf, buf, 8, &err)) /* For mode >= 1 */ #else - while (cole_fread(cf, buf, 1, &err)) -#endif - { - if (MODE == 0) - { - if (count == 0) - { - length = 0; - opcode = (unsigned)buf[0]; - target = 80; /* ficticious number */ - printf("
"); - } - else if (count == 1) - opcode |= (buf[0]<<8)&0x0000FFFFL; - else if (count == 2) - length = (unsigned)buf[0]; - else if (count == 3) - { - length |= (buf[0]<<8); - target = length; - printf("
\nLength:%04X Opcode:%04X - ", length, opcode); - output_opcode_string(opcode); - puts("
\n"); - } - if (count > 3) - { /* Here is where we want to process the data */ - /* based on the opcode... */ -#if (TEXT == 0) - if (isprint(buf[0])) - putc(buf[0], stdout); -#else - printf("%02X ", buf[0]); - if (((count-3) % 8) == 0) - printf("
\n"); + while (cole_fread (cf, buf, 1, &err)) #endif - } - if (count == (target+3)) - count = 0; - else - count++; - } - else /* mode >= 1 */ - { - printf("%02x %02x %02x %02x %02x %02x %02x %02x         ", - (unsigned)buf[0], (unsigned)buf[1], (unsigned)buf[2], (unsigned)buf[3], - (unsigned)buf[4], (unsigned)buf[5], (unsigned)buf[6], (unsigned)buf[7]); - putchar(buf[0]); putchar(buf[1]); - putchar(buf[2]); putchar(buf[3]); - putchar(buf[4]); putchar(buf[5]); - putchar(buf[6]); putchar(buf[7]); - printf("
\n"); - } + { + if (MODE == 0) + { + if (count == 0) + { + length = 0; + opcode = (unsigned) buf[0]; + target = 80; /* ficticious number */ + printf ("
"); + } + else if (count == 1) + opcode |= (buf[0] << 8) & 0x0000FFFFL; + else if (count == 2) + length = (unsigned) buf[0]; + else if (count == 3) + { + length |= (buf[0] << 8); + target = length; + printf ("
\nLength:%04X Opcode:%04X - ", length, opcode); + output_opcode_string (opcode); + puts ("
\n"); + } + if (count > 3) + { /* Here is where we want to process the data */ + /* based on the opcode... */ +#if (TEXT == 0) + if (isprint (buf[0])) + putc (buf[0], stdout); +#else + printf ("%02X ", buf[0]); + if (((count - 3) % 8) == 0) + printf ("
\n"); +#endif + } + if (count == (target + 3)) + count = 0; + else + count++; } + else /* mode >= 1 */ + { + printf + ("%02x %02x %02x %02x %02x %02x %02x %02x         ", + (unsigned) buf[0], (unsigned) buf[1], (unsigned) buf[2], + (unsigned) buf[3], (unsigned) buf[4], (unsigned) buf[5], + (unsigned) buf[6], (unsigned) buf[7]); + putchar (buf[0]); + putchar (buf[1]); + putchar (buf[2]); + putchar (buf[3]); + putchar (buf[4]); + putchar (buf[5]); + putchar (buf[6]); + putchar (buf[7]); + printf ("
\n"); + } + } /* Output Tail */ - printf("\n"); - cole_fclose(cf, &err); + printf ("\n"); + cole_fclose (cf, &err); } /*static void main_line_processor(int opcode, char data) @@ -177,412 +185,412 @@ void dump_file(COLEDIRENT *cde, void *_info) } */ -static void output_opcode_string(int opcode) +static void +output_opcode_string (int opcode) { - switch (opcode&0x00FF) - { + switch (opcode & 0x00FF) + { - /* start of documented general opcodes */ - - case 0x0A: - puts("\nEOF: End of File"); - break; - case 0x0C: - puts("CALCCOUNT: Iteration count"); - break; - case 0x0D: - puts("CalcMode: Calculation mode"); - break; - case 0x0E: - puts("Precision"); - break; - case 0x0F: - puts("Reference Mode"); - break; - case 0x10: - puts("Delta: Iteration Increment"); - break; - case 0x11: - puts("Iteration Mode"); - break; - case 0x12: - puts("Protection Flag"); - break; - case 0x13: - puts("Protection Password"); - break; - case 0x14: - puts("Print Header on each page"); - break; - case 0x15: - puts("Print Footer on each page"); - break; - case 0x16: - puts("External Count: Number of external references"); - break; - case 0x17: - puts("External reference"); - break; - case 0x18: - puts("NAME"); - break; - case 0x19: - puts("Windows are Protected"); - break; - case 0x1A: - puts("Vertical Page Breaks"); - break; - case 0x1B: - puts("Horizontal Page Breaks"); - break; - case 0x1C: - puts("Cell Note"); - break; - case 0x1D: - puts("Selection"); - break; - case 0x22: - puts("1904 date system"); - break; - case 0x26: - puts("Left Margin Measurement"); - break; - case 0x27: - puts("Right Margin Measurement"); - break; - case 0x28: - puts("Top Margin Measurement"); - break; - case 0x29: - puts("Bottom Margin Measurement"); - break; - case 0x2A: - puts("Print Row/Column Labels"); - break; - case 0x2B: - puts("Print Gridlines Flag"); - break; - case 0x2F: - puts("File is Password protected"); - break; - case 0x31: - puts("FONT"); - break; - case 0x3C: - puts("Continues long records"); - break; - case 0x3D: - puts("Window1"); - break; - case 0x40: - puts("BACKUP: Save Backup Version of the File"); - break; - case 0x41: - puts("Number of Panes and their position"); - break; - case 0x42: - puts("CODEPAGE: Default code page"); - break; - case 0x4D: - puts("PLS: Environment specific print record"); - break; - case 0x50: - puts("DCON: Data consolidation information"); - break; - case 0x51: - puts("DCONREF: Data consolidation references"); - break; - case 0x52: - puts("DCONNAME: Data Consolidation Named References"); - break; - case 0x55: - puts("DEFCOLWIDTH: Default Column Width"); - break; - case 0x59: - puts("XCT: CRN Record Count"); - break; - case 0x5A: - puts("CRN: Nonresident operands"); - break; - case 0x5B: - puts("FILESHARING:File-sharing information"); - break; - case 0x5C: - puts("Write Access"); - break; - case 0x5D: - puts("OBJ: Describes a Graphic object"); - break; - case 0x5E: - puts("UNCALCED: Recalculation Status"); - break; - case 0x5F: - puts("SAVERECALC: Recalculate before save"); - break; - case 0x60: - puts("TEMPLATE: Workbook is a template"); - break; - case 0x63: - puts("OBJPROTECT: Objects are protected"); - break; - case 0x7D: - puts("COLINFO: Column formatting information"); - break; - case 0x7E: - puts("RK Number"); - break; - case 0x7F: - puts("IMDATA: Image data"); - break; - case 0x80: - puts("GUTS: Size of row and column gutters"); - break; - case 0x81: - puts("WSBOOL: Additional workspace information"); - break; - case 0x82: - puts("GRIDSET: State change of gridlines option"); - break; - case 0x83: - puts("HCENTER: Center between horizontal margins"); - break; - case 0x84: - puts("VCENTER: Center between vertical margins"); - break; - case 0x85: - puts("BoundSheet"); - break; - case 0x86: - puts("WRITEPROT: Workbook is Write-protected"); - break; - case 0x87: - puts("ADDIN: Workbook is add-in macro"); - break; - case 0x88: - puts("EDG: Edition globals"); - break; - case 0x89: - puts("PUB: Publisher"); - break; - case 0x8C: - puts("COUNTRY: Default country and WIN.INI Country"); - break; - case 0x8D: - puts("HIDEOBJ: Object display options"); - break; - case 0x90: - puts("SORT: Sorting options"); - break; - case 0x91: - puts("SUB: Subscriber"); - break; - case 0x92: - puts("Palette Info"); - break; - case 0x94: - puts("LHRECORD: .WK? File Conversion Information"); - break; - case 0x95: - puts("LHNGRAPH: Named Graph Information"); - break; - case 0x96: - puts("SOUND: Sound note"); - break; - case 0x98: - puts("LPR: Sheet was printed using LINE.PRINT()"); - break; - case 0x99: - puts("STANDARDWIDTH: Standard column width"); - break; - case 0x9A: - puts("FNGROUPNAME: Function Group name"); - break; - case 0x9B: - puts("FILTERMODE: Sheet contains filtered list"); - break; - case 0x9C: - puts("FNGROUPCOUNT: Built-in function group count"); - break; - case 0x9D: - puts("AUTOFILTERINFO: Drop Down Arrow Count"); - break; - case 0x9E: - puts("AUTOFILTER: AutoFilter data"); - break; - case 0xA0: - puts("SCL: Window Zoom magnification"); - break; - case 0xA1: - puts("Page Setup"); - break; - case 0xA9: - puts("COORDLIST: Polygon Object Vertex coordinates"); - break; - case 0xAB: - puts("GCW: Global Column-Wdith flags"); - break; - case 0xAE: - puts("SCENMAN: Scenario Output data"); - break; - case 0xAF: - puts("PROT4REV: Shared Workbook protection flag"); - break; - case 0xB0: - puts("SXVIEW: View Definition"); - break; - case 0xB1: - puts("SXVD: View Fields"); - break; - case 0xB2: - puts("SXVI: View Item"); - break; - case 0xB4: - puts("SXIVD: Row/Column Field Ids"); - break; - case 0xB5: - puts("SXLI: Line item array"); - break; - case 0xB6: - puts("SXPI: Page item"); - break; - case 0xB8: - puts("DOCROUTE: Routing slip information"); - break; - case 0xB9: - puts("RECIPNAME: Recipient name"); - break; - case 0xBC: - puts("SHRFMLA: Shared formula"); - break; - case 0xBD: - puts("MULRK: Multiple RK cells"); - break; - case 0xBE: - puts("Multiple Blanks"); - break; - case 0xC1: - puts("MMS: ADDMENU/DELMENU Record Group count"); - break; - case 0xC2: - puts("ADDMENU: Menu Addition"); - break; - case 0xC3: - puts("DELMENU: Menu Deletion"); - break; - case 0xC5: - puts("SXDI: Data Item"); - break; - case 0xC6: - puts("SXDB: PivtoTable Cache Data"); - break; - case 0xCD: - puts("SXSTRING: String"); - break; - case 0xD0: - puts("SXTBL: Multiple Consolidation Source Info"); - break; - case 0xD1: - puts("SXTBRGIITM: Page Item Name Count"); - break; - case 0xD2: - puts("SXTBPG: Page Item Indexes"); - break; - case 0xD3: - puts("OBPROJ: Visual Basic Project"); - break; - case 0xD5: - puts("SXIDSTM: Stream ID"); - break; - case 0xD6: - puts("RString"); - break; - case 0xD7: - puts("DBCELL: Stream offsets"); - break; - case 0xDA: - puts("BOOKBOOL: Workbook option flag"); - break; + /* start of documented general opcodes */ - /* error in ms docs - case 0xDC: - puts("PARAMQRY: Query parameters"); - break; - case 0xDC: - puts("SXEXT: External source information"); - break; - */ + case 0x0A: + puts ("\nEOF: End of File"); + break; + case 0x0C: + puts ("CALCCOUNT: Iteration count"); + break; + case 0x0D: + puts ("CalcMode: Calculation mode"); + break; + case 0x0E: + puts ("Precision"); + break; + case 0x0F: + puts ("Reference Mode"); + break; + case 0x10: + puts ("Delta: Iteration Increment"); + break; + case 0x11: + puts ("Iteration Mode"); + break; + case 0x12: + puts ("Protection Flag"); + break; + case 0x13: + puts ("Protection Password"); + break; + case 0x14: + puts ("Print Header on each page"); + break; + case 0x15: + puts ("Print Footer on each page"); + break; + case 0x16: + puts ("External Count: Number of external references"); + break; + case 0x17: + puts ("External reference"); + break; + case 0x18: + puts ("NAME"); + break; + case 0x19: + puts ("Windows are Protected"); + break; + case 0x1A: + puts ("Vertical Page Breaks"); + break; + case 0x1B: + puts ("Horizontal Page Breaks"); + break; + case 0x1C: + puts ("Cell Note"); + break; + case 0x1D: + puts ("Selection"); + break; + case 0x22: + puts ("1904 date system"); + break; + case 0x26: + puts ("Left Margin Measurement"); + break; + case 0x27: + puts ("Right Margin Measurement"); + break; + case 0x28: + puts ("Top Margin Measurement"); + break; + case 0x29: + puts ("Bottom Margin Measurement"); + break; + case 0x2A: + puts ("Print Row/Column Labels"); + break; + case 0x2B: + puts ("Print Gridlines Flag"); + break; + case 0x2F: + puts ("File is Password protected"); + break; + case 0x31: + puts ("FONT"); + break; + case 0x3C: + puts ("Continues long records"); + break; + case 0x3D: + puts ("Window1"); + break; + case 0x40: + puts ("BACKUP: Save Backup Version of the File"); + break; + case 0x41: + puts ("Number of Panes and their position"); + break; + case 0x42: + puts ("CODEPAGE: Default code page"); + break; + case 0x4D: + puts ("PLS: Environment specific print record"); + break; + case 0x50: + puts ("DCON: Data consolidation information"); + break; + case 0x51: + puts ("DCONREF: Data consolidation references"); + break; + case 0x52: + puts ("DCONNAME: Data Consolidation Named References"); + break; + case 0x55: + puts ("DEFCOLWIDTH: Default Column Width"); + break; + case 0x59: + puts ("XCT: CRN Record Count"); + break; + case 0x5A: + puts ("CRN: Nonresident operands"); + break; + case 0x5B: + puts ("FILESHARING:File-sharing information"); + break; + case 0x5C: + puts ("Write Access"); + break; + case 0x5D: + puts ("OBJ: Describes a Graphic object"); + break; + case 0x5E: + puts ("UNCALCED: Recalculation Status"); + break; + case 0x5F: + puts ("SAVERECALC: Recalculate before save"); + break; + case 0x60: + puts ("TEMPLATE: Workbook is a template"); + break; + case 0x63: + puts ("OBJPROTECT: Objects are protected"); + break; + case 0x7D: + puts ("COLINFO: Column formatting information"); + break; + case 0x7E: + puts ("RK Number"); + break; + case 0x7F: + puts ("IMDATA: Image data"); + break; + case 0x80: + puts ("GUTS: Size of row and column gutters"); + break; + case 0x81: + puts ("WSBOOL: Additional workspace information"); + break; + case 0x82: + puts ("GRIDSET: State change of gridlines option"); + break; + case 0x83: + puts ("HCENTER: Center between horizontal margins"); + break; + case 0x84: + puts ("VCENTER: Center between vertical margins"); + break; + case 0x85: + puts ("BoundSheet"); + break; + case 0x86: + puts ("WRITEPROT: Workbook is Write-protected"); + break; + case 0x87: + puts ("ADDIN: Workbook is add-in macro"); + break; + case 0x88: + puts ("EDG: Edition globals"); + break; + case 0x89: + puts ("PUB: Publisher"); + break; + case 0x8C: + puts ("COUNTRY: Default country and WIN.INI Country"); + break; + case 0x8D: + puts ("HIDEOBJ: Object display options"); + break; + case 0x90: + puts ("SORT: Sorting options"); + break; + case 0x91: + puts ("SUB: Subscriber"); + break; + case 0x92: + puts ("Palette Info"); + break; + case 0x94: + puts ("LHRECORD: .WK? File Conversion Information"); + break; + case 0x95: + puts ("LHNGRAPH: Named Graph Information"); + break; + case 0x96: + puts ("SOUND: Sound note"); + break; + case 0x98: + puts ("LPR: Sheet was printed using LINE.PRINT()"); + break; + case 0x99: + puts ("STANDARDWIDTH: Standard column width"); + break; + case 0x9A: + puts ("FNGROUPNAME: Function Group name"); + break; + case 0x9B: + puts ("FILTERMODE: Sheet contains filtered list"); + break; + case 0x9C: + puts ("FNGROUPCOUNT: Built-in function group count"); + break; + case 0x9D: + puts ("AUTOFILTERINFO: Drop Down Arrow Count"); + break; + case 0x9E: + puts ("AUTOFILTER: AutoFilter data"); + break; + case 0xA0: + puts ("SCL: Window Zoom magnification"); + break; + case 0xA1: + puts ("Page Setup"); + break; + case 0xA9: + puts ("COORDLIST: Polygon Object Vertex coordinates"); + break; + case 0xAB: + puts ("GCW: Global Column-Wdith flags"); + break; + case 0xAE: + puts ("SCENMAN: Scenario Output data"); + break; + case 0xAF: + puts ("PROT4REV: Shared Workbook protection flag"); + break; + case 0xB0: + puts ("SXVIEW: View Definition"); + break; + case 0xB1: + puts ("SXVD: View Fields"); + break; + case 0xB2: + puts ("SXVI: View Item"); + break; + case 0xB4: + puts ("SXIVD: Row/Column Field Ids"); + break; + case 0xB5: + puts ("SXLI: Line item array"); + break; + case 0xB6: + puts ("SXPI: Page item"); + break; + case 0xB8: + puts ("DOCROUTE: Routing slip information"); + break; + case 0xB9: + puts ("RECIPNAME: Recipient name"); + break; + case 0xBC: + puts ("SHRFMLA: Shared formula"); + break; + case 0xBD: + puts ("MULRK: Multiple RK cells"); + break; + case 0xBE: + puts ("Multiple Blanks"); + break; + case 0xC1: + puts ("MMS: ADDMENU/DELMENU Record Group count"); + break; + case 0xC2: + puts ("ADDMENU: Menu Addition"); + break; + case 0xC3: + puts ("DELMENU: Menu Deletion"); + break; + case 0xC5: + puts ("SXDI: Data Item"); + break; + case 0xC6: + puts ("SXDB: PivtoTable Cache Data"); + break; + case 0xCD: + puts ("SXSTRING: String"); + break; + case 0xD0: + puts ("SXTBL: Multiple Consolidation Source Info"); + break; + case 0xD1: + puts ("SXTBRGIITM: Page Item Name Count"); + break; + case 0xD2: + puts ("SXTBPG: Page Item Indexes"); + break; + case 0xD3: + puts ("OBPROJ: Visual Basic Project"); + break; + case 0xD5: + puts ("SXIDSTM: Stream ID"); + break; + case 0xD6: + puts ("RString"); + break; + case 0xD7: + puts ("DBCELL: Stream offsets"); + break; + case 0xDA: + puts ("BOOKBOOL: Workbook option flag"); + break; - case 0xDD: - puts("SCENPROTECT: Scenario protection"); - break; - case 0xDE: - puts("OLESIZE: Size of an OLE object"); - break; - case 0xDF: - puts("UDDESC: Description string for chart autoformat"); - break; - case 0xE0: - puts("Extended Format"); - break; - case 0xE1: - puts("INTERFACEHDR: Beginning of User Interface Records"); - break; - case 0xE2: - puts("INTERFACEEND: End of User interface records"); - break; - case 0xE3: - puts("SXVS: View source"); - break; - case 0xEA: - puts("TABIDCONF: Sheet tab ID of Conflict history"); - break; - case 0xEB: - puts("MSODRAWINGGROUP: MS Office Drawing Group"); - break; - case 0xEC: - puts("MSODRAWING: MS Office Drawing"); - break; - case 0xED: - puts("MS Office Drawing Selection"); - break; - case 0xF0: - puts("SXRULE: PivotTable Rule data"); - break; - case 0xF1: - puts("SXEX: PivotTable Extended information"); - break; - case 0xF2: - puts("SXFILT: PivotTable Rule Filter"); - break; - case 0xF6: - puts("SXNAME: PivotTable Name"); - break; - case 0xF7: - puts("SXSELECT: PivotTable Selection Information"); - break; - case 0xF8: - puts("PivotTable Name Pair"); - break; - case 0xF9: - puts("PivotTable Parsed Expression"); - break; - case 0xFB: - puts("PivotTable Format Record"); - break; - case 0xFC: - puts("Shared String Table"); - break; - case 0xFD: - puts("Cell Value, String Constant/SST"); - break; - case 0xFF: - puts("Extended Shared String Table"); - break; + /* error in ms docs + case 0xDC: + puts("PARAMQRY: Query parameters"); + break; + case 0xDC: + puts("SXEXT: External source information"); + break; + */ + + case 0xDD: + puts ("SCENPROTECT: Scenario protection"); + break; + case 0xDE: + puts ("OLESIZE: Size of an OLE object"); + break; + case 0xDF: + puts ("UDDESC: Description string for chart autoformat"); + break; + case 0xE0: + puts ("Extended Format"); + break; + case 0xE1: + puts ("INTERFACEHDR: Beginning of User Interface Records"); + break; + case 0xE2: + puts ("INTERFACEEND: End of User interface records"); + break; + case 0xE3: + puts ("SXVS: View source"); + break; + case 0xEA: + puts ("TABIDCONF: Sheet tab ID of Conflict history"); + break; + case 0xEB: + puts ("MSODRAWINGGROUP: MS Office Drawing Group"); + break; + case 0xEC: + puts ("MSODRAWING: MS Office Drawing"); + break; + case 0xED: + puts ("MS Office Drawing Selection"); + break; + case 0xF0: + puts ("SXRULE: PivotTable Rule data"); + break; + case 0xF1: + puts ("SXEX: PivotTable Extended information"); + break; + case 0xF2: + puts ("SXFILT: PivotTable Rule Filter"); + break; + case 0xF6: + puts ("SXNAME: PivotTable Name"); + break; + case 0xF7: + puts ("SXSELECT: PivotTable Selection Information"); + break; + case 0xF8: + puts ("PivotTable Name Pair"); + break; + case 0xF9: + puts ("PivotTable Parsed Expression"); + break; + case 0xFB: + puts ("PivotTable Format Record"); + break; + case 0xFC: + puts ("Shared String Table"); + break; + case 0xFD: + puts ("Cell Value, String Constant/SST"); + break; + case 0xFF: + puts ("Extended Shared String Table"); + break; - default: - puts("Unknown Opcode"); - break; - } + default: + puts ("Unknown Opcode"); + break; + } } - diff --git a/xlhtml/xlhtml.c b/xlhtml/xlhtml.c index 5d0b51f..1f2b745 100644 --- a/xlhtml/xlhtml.c +++ b/xlhtml/xlhtml.c @@ -27,6 +27,7 @@ #include "tuneable.h" #include "xlhtml.h" #include "support.h" +#include "color.h" @@ -34,149 +35,85 @@ static U16 HARD_MAX_ROWS = HARD_MAX_ROWS_97; static char SectionName[2][12] = /* The section of the Excel Stream where the workbooks are kept */ { - "/Workbook", /*!< Excel 97 & 2000 */ - "/Book" /*!< Everything else ? */ + "/Workbook", /*!< Excel 97 & 2000 */ + "/Book" /*!< Everything else ? */ }; int numCustomColors = 0; U8 **customColors = 0; -char colorTab[MAX_COLORS][8] = -{ - "000000", /* FIXME: Need to find these first 8 colors! */ - "FFFFFF", - "FFFFFF", - "FFFFFF", - "FFFFFF", - "FFFFFF", - "FFFFFF", - "FFFFFF", - "FFFFFF", /*0x08 - This one's Black, too ??? */ - "FFFFFF", /* This one's normal */ - "red", /* "FF0000", */ - "lime", /* "00FF00", */ - "blue", /* "0000FF", */ - "FFFF00", - "FF00FF", - "aqua", /* "00FFFF", */ - "800000", /* 0x10 */ - "green", /* "008000", */ - "navy", /* "000080", */ - "808000", - "800080", - "teal", /* "008080", */ - "C0C0C0", - "gray", /* "808080", */ - "9999FF", /* 0x18 */ - "993366", - "FFFFCC", - "CCFFFF", - "660066", - "FF8080", - "0066CC", - "CCCCFF", - "000080", - "FF00FF", /* 0x20 */ - "FFFF00", - "00FFFF", - "800080", - "800000", - "008080", - "0000FF", - "00CCFF", /* 0x28 */ - "CCFFFF", - "CCFFCC", - "FFFF99", - "99CCFF", - "FF99CC", - "CC99FF", - "FFCC99", - "3366FF", /* 0x30 */ - "33CCCC", - "99CC00", - "FFCC00", - "FF9900", - "FF6600", - "666699", - "969696", - "003366", /* 0x38 */ - "339966", - "003300", - "333300", - "993300", - "993366", - "333399", - "333333", - "FFFFFF" /* 0x40 */ -}; /* FIXME: Support major languages here...not just English */ -const char month_abbr[12][5] = { "Jan", "Feb", "Mar", "Apr", "May", "June", - "July", "Aug", "Sep", "Oct", "Nov", "Dec" }; +const char month_abbr[12][5] = { "Jan", "Feb", "Mar", "Apr", "May", "June", + "July", "Aug", "Sep", "Oct", "Nov", "Dec" +}; /* Function Prototypes */ /* This function is in xml.c */ -extern void OutputTableXML(void); +extern void OutputTableXML (void); /* This function is in ascii.c */ -void OutputPartialTableAscii(void); +void OutputPartialTableAscii (void); /* These functions are in html.c */ -extern void OutputTableHTML(void); -extern void output_start_html_attr(html_attr *h, unsigned int, int); -extern void output_end_html_attr(html_attr *h); -extern void output_footer(void); -extern void output_header(void); +extern void OutputTableHTML (void); +extern void output_start_html_attr (html_attr * h, unsigned int, int); +extern void output_end_html_attr (html_attr * h); +extern void output_footer (void); +extern void output_header (void); COLE_LOCATE_ACTION_FUNC scan_file; -void main_line_processor(U16, U16, U32, U16, U8); -void decodeBoolErr(U16, U16, char *); -void PrintFloatComma(char *, int, F64); -void print_as_fraction(F64, int); -void incr_f_cnt(uni_string *); -int get_default_font(void); -void OutputCharCorrected(U8); -void update_crun_info(U16 *loc, U16 *fnt_idx, U16 crun_cnt, U8 *fmt_run); -void put_utf8(U16); -void print_utf8(U16); -void uni_string_clear(uni_string *); -int uni_string_comp(uni_string *, uni_string *); -void html_flag_init(html_attr *h); -void output_start_font_attribute(html_attr *h, U16 fnt_idx); +void main_line_processor (U16, U16, U32, U16, U8); +void decodeBoolErr (U16, U16, char *); +void PrintFloatComma (char *, int, F64); +void print_as_fraction (F64, int); +void incr_f_cnt (uni_string *); +int get_default_font (void); +void OutputCharCorrected (U8); +void update_crun_info (U16 * loc, U16 * fnt_idx, U16 crun_cnt, U8 * fmt_run); +void put_utf8 (U16); +void print_utf8 (U16); +void uni_string_clear (uni_string *); +int uni_string_comp (uni_string *, uni_string *); +void html_flag_init (html_attr * h); +void output_start_font_attribute (html_attr * h, U16 fnt_idx); /* The array update functions */ -int ws_init(int); -int add_more_worksheet_ptrs(void); -int resize_c_array(work_sheet *, U32, U16); -void add_wb_array(U16, U16, U16, U16, U8, U8 *, U16, U16, U8 *); -void update_cell_xf(U16, U16, U16); -void update_cell_hyperlink(U16 r, U16 c, U8 *hyperlink, int len, U16 type); -void add_str_array(U8, U8 *, U16, U8 *, U8); -void add_font(U16, U16, U16, U16, U16, U8, U16, U8 *, U16); -void add_ws_title(U16, U8 *, U16); -void add_xf_array(U16 fnt_idx, U16 fmt_idx, U16 gen, U16 align, -U16 indent, U16 b_style, U16 b_l_color, U32 b_t_color, U16 cell_color); +int ws_init (int); +int add_more_worksheet_ptrs (void); +int resize_c_array (work_sheet *, U32, U16); +void add_wb_array (U16, U16, U16, U16, U8, U8 *, U16, U16, U8 *); +void update_cell_xf (U16, U16, U16); +void update_cell_hyperlink (U16 r, U16 c, U8 * hyperlink, int len, U16 type); +void add_str_array (U8, U8 *, U16, U8 *, U8); +void add_font (U16, U16, U16, U16, U16, U8, U16, U8 *, U16); +void add_ws_title (U16, U8 *, U16); +void add_xf_array (U16 fnt_idx, U16 fmt_idx, U16 gen, U16 align, + U16 indent, U16 b_style, U16 b_l_color, U32 b_t_color, + U16 cell_color); /* Global data */ +int Ascii = 0; /*!< Whether or not to out ascii instaed of html */ char filename[256]; int file_version = 0; -U32 next_string=0; -unsigned int next_font=0, next_ws_title=0, next_xf=0; -int sheet_count=-2; /*!< Number of worksheets found */ -uni_string default_font; /*!< Font for table */ +U32 next_string = 0; +unsigned int next_font = 0, next_ws_title = 0, next_xf = 0; +int sheet_count = -2; /*!< Number of worksheets found */ +uni_string default_font; /*!< Font for table */ int default_fontsize = 3; /*!< Default font size for table */ char *default_alignment = 0; /*!< Alignment for table */ int first_sheet = 0; /*!< First worksheet to display */ -int last_sheet = WORKSHEETS_INCR-1; /*!< The last worksheet to display */ -S16 xp=0, xr1=-1, xr2=-1, xc1=-1, xc2=-1; /*!< Extraction info... */ -int currency_symbol = '$'; /*!< What to use for currency */ -U16 str_formula_row = 0; /*!< Data holders for string formulas */ -U16 str_formula_col = 0; /*!< Data holders for string formulas */ +int last_sheet = WORKSHEETS_INCR - 1; /*!< The last worksheet to display */ +S16 xp = 0, xr1 = -1, xr2 = -1, xc1 = -1, xc2 = -1; /*!< Extraction info... */ +int currency_symbol = '$'; /*!< What to use for currency */ +U16 str_formula_row = 0; /*!< Data holders for string formulas */ +U16 str_formula_col = 0; /*!< Data holders for string formulas */ U16 str_formula_format = 0; /*!< Data holders for string formulas */ + /* Limits */ unsigned int max_fonts = FONTS_INCR; unsigned int max_xformats = XFORMATS_INCR; @@ -202,9 +139,8 @@ int formula_warnings = 1; /*!< Whether or not to suppress formula warnings */ int center_tables = 0; /*!< Whether or not to center justify tables or leave it left */ int trim_edges = 0; /*!< Whether or not to trim the edges of columns or rows */ char *default_text_color = "000000"; -char *default_background_color="FFFFFF"; -char *default_image=NULL; /*!< Point to background image */ -int Ascii = 0; /*!< Whether or not to out ascii instaed of html */ +char *default_background_color = "FFFFFF"; +char *default_image = NULL; /*!< Point to background image */ int Csv = 0; /*!< Whether or not to out csv instaed of html */ int OutputXML = 0; /*!< Output as xml */ int DumpPage = 0; /*!< Dump page count & max cols & rows */ @@ -215,10 +151,10 @@ int TableHeaders = 0; /*!< Output row/column headers */ /* Some Global Flags */ -int notAccurate = 0; /*!< Flag used to indicate that stale data was used */ -int NoFormat = 0; /*!< Flag used to indicated unimplemented format */ -int NotImplemented = 0; /*!< Flag to print unimplemented cell type message */ -int Unsupported = 0; /*!< Flag to print unsupported cell type message */ +int notAccurate = 0; /*!< Flag used to indicate that stale data was used */ +int NoFormat = 0; /*!< Flag used to indicated unimplemented format */ +int NotImplemented = 0; /*!< Flag to print unimplemented cell type message */ +int Unsupported = 0; /*!< Flag to print unsupported cell type message */ int MaxPalExceeded = 0; int MaxXFExceeded = 0; int MaxFormatsExceeded = 0; @@ -228,457 +164,2666 @@ int MaxWorksheetsExceeded = 0; int MaxStringsExceeded = 0; int WorkingBufferOverflow = 0; int MaxFontsExceeded = 0; -int UnicodeStrings = 0; /*!< 0==ASCII, 1==windows-1252, 2==uft-8 */ -int CodePage = 0; /*!< Micosoft CodePage as specified in the Excel file. */ +int UnicodeStrings = 0; /*!< 0==ASCII, 1==windows-1252, 2==uft-8 */ +int CodePage = 0; /*!< Micosoft CodePage as specified in the Excel file. */ -int main (int argc, char **argv) +int +main (int argc, char **argv) { - int i, f_ptr = 0; - U16 k; - U32 j; - COLEFS * cfs; - COLERRNO colerrno; + int i, f_ptr = 0; + U16 k; + U32 j; + COLEFS *cfs; + COLERRNO colerrno; - if (argc < 2) + if (argc < 2) + { + printf ("Incorrect usage. Try xlhtml --help for more information\n"); + exit (0); + } + else + { + strncpy (filename, argv[argc - 1], 252); + filename[252] = 0; + for (i = 1; i < (argc - 1); i++) { - printf("Incorrect usage. Try xlhtml --help for more information\n"); - exit(0); + if (strcmp (argv[i], "-nc") == 0) + use_colors = 0; + else if (strcmp (argv[i], "-xml") == 0) + OutputXML = 1; + else if (strcmp (argv[i], "-asc") == 0) + Ascii = 1; + else if (strcmp (argv[i], "--ascii") == 0) + Ascii = 1; + else if (strcmp (argv[i], "-csv") == 0) + { + Ascii = 1; + Csv = 1; + + } + else if (strcmp (argv[i], "-a") == 0) + aggressive = 1; + else if (strcmp (argv[i], "-fw") == 0) + formula_warnings = 0; + else if (strcmp (argv[i], "-c") == 0) + center_tables = 1; + else if (strcmp (argv[i], "-dp") == 0) + DumpPage = 1; + else if (strcmp (argv[i], "-m") == 0) + MultiByte = 1; + else if (strncmp (argv[i], "-tc", 3) == 0) + { + default_text_color = &argv[i][3]; + if (strlen (default_text_color) != 6) + display_usage (); + } + else if (strncmp (argv[i], "-bc", 3) == 0) + { + default_background_color = &argv[i][3]; + if (strlen (default_background_color) != 6) + display_usage (); + } + else if (strncmp (argv[i], "-bi", 3) == 0) + { + default_image = &argv[i][3]; + use_colors = 0; + } + else if (strncmp (argv[i], "-te", 3) == 0) + trim_edges = 1; + else if (strcmp (argv[i], "-v") == 0) + print_version (); + else if (strcmp (argv[i], "-nh") == 0) + NoHeaders = 1; + else if (strcmp (argv[i], "-th") == 0) + TableHeaders = 1; + else if (strncmp (argv[i], "-xc:", 4) == 0) + { + int d1, d2; + if (sscanf (argv[i] + 4, "%d-%d", &d1, &d2) != 2) + { + fprintf (stderr, + "column range %s not valid, expected -xc:FIRST-LAST\n", + argv[i] + 4); + display_usage (); + } + xc1 = (S16) d1; + xc2 = (S16) d2; + Xtract = 1; + if (xc1 > xc2) + { + fprintf (stderr, "last column must be >= the first\n"); + exit (1); + } + } + else if (strncmp (argv[i], "-xp:", 4) == 0) + { + Xtract = 1; + xp = (S16) atoi (&(argv[i][4])); + if (xp < 0) + { + fprintf (stderr, "Negative numbers are illegal.\n"); + exit (1); + } + } + else if (strncmp (argv[i], "-xr:", 4) == 0) + { + char *ptr, *buf; + Xtract = 1; + buf = strdup (argv[i]); + ptr = strrchr (buf, '-'); + xr2 = (S16) atoi (ptr + 1); + *ptr = 0; + ptr = strchr (buf, ':'); + xr1 = (S16) atoi (ptr + 1); + free (buf); + if (xr1 > xr2) + { + fprintf (stderr, "row's 2nd digit must be >= the first\n"); + exit (1); + } + } + else + display_usage (); } - else + if (strcmp (filename, "-v") == 0) { - strncpy(filename, argv[argc-1], 252); - filename[252] = 0; - for (i=1; i<(argc-1); i++) - { - if (strcmp(argv[i], "-nc") == 0) - use_colors = 0; - else if(strcmp(argv[i], "-xml") == 0 ) - OutputXML = 1; - else if (strcmp(argv[i], "-asc") == 0) - Ascii = 1; - else if (strcmp(argv[i], "--ascii") == 0) - Ascii = 1; - else if (strcmp(argv[i], "-csv") == 0) - { - Ascii = 1; - Csv = 1; - - } - else if (strcmp(argv[i], "-a") == 0) - aggressive = 1; - else if (strcmp(argv[i], "-fw") == 0) - formula_warnings = 0; - else if (strcmp(argv[i], "-c") == 0) - center_tables = 1; - else if (strcmp(argv[i], "-dp") == 0) - DumpPage = 1; - else if (strcmp(argv[i], "-m") == 0) - MultiByte = 1; - else if (strncmp(argv[i], "-tc", 3) == 0) - { - default_text_color = &argv[i][3]; - if (strlen(default_text_color) != 6) - display_usage(); - } - else if (strncmp(argv[i], "-bc", 3) == 0) - { - default_background_color = &argv[i][3]; - if (strlen(default_background_color) != 6) - display_usage(); - } - else if (strncmp(argv[i], "-bi", 3) == 0) - { - default_image = &argv[i][3]; - use_colors = 0; - } - else if (strncmp(argv[i], "-te", 3) == 0) - trim_edges = 1; - else if (strcmp(argv[i], "-v") == 0) - print_version(); - else if(strcmp(argv[i], "-nh") == 0 ) - NoHeaders = 1; - else if(strcmp(argv[i], "-th") == 0 ) - TableHeaders = 1; - else if (strncmp(argv[i], "-xc:", 4) == 0) - { - int d1, d2; - if (sscanf(argv[i] + 4, "%d-%d", &d1, &d2) != 2) - { - fprintf(stderr, "column range %s not valid, expected -xc:FIRST-LAST\n", argv[i] + 4); - display_usage(); - } - xc1 = (S16)d1; - xc2 = (S16)d2; - Xtract = 1; - if (xc1 > xc2) - { - fprintf(stderr, "last column must be >= the first\n"); - exit(1); - } - } - else if (strncmp(argv[i], "-xp:", 4) == 0) - { - Xtract = 1; - xp = (S16)atoi(&(argv[i][4])); - if (xp < 0) - { - fprintf(stderr, "Negative numbers are illegal.\n"); - exit(1); - } - } - else if (strncmp(argv[i], "-xr:", 4) == 0) - { - char *ptr, *buf; - Xtract = 1; - buf = strdup(argv[i]); - ptr = strrchr(buf, '-'); - xr2 = (S16)atoi(ptr+1); - *ptr = 0; - ptr = strchr(buf, ':'); - xr1 = (S16)atoi(ptr+1); - free(buf); - if (xr1 > xr2) - { - fprintf(stderr, "row's 2nd digit must be >= the first\n"); - exit(1); - } - } - else - display_usage(); - } - if (strcmp(filename, "-v") == 0) - { - print_version(); - } - if (strcmp(filename, "--version") == 0) - { - print_version(); - } - - if (strcmp(filename, "--help") == 0) - display_usage(); - if (strcmp(filename, "-?") == 0) - display_usage(); + print_version (); } - if (Ascii) - { /* Disable it if DumpPage or Xtract isn't used... */ - if (!(DumpPage||Xtract)) - Ascii = 0; + if (strcmp (filename, "--version") == 0) + { + print_version (); } - if (Xtract) - trim_edges = 0; /* No trimming when extracting... */ - if (OutputXML) - aggressive = 0; - /* Init arrays... */ - ws_array = (work_sheet **)malloc(max_worksheets * sizeof(work_sheet *)); - for (i=0; i<(int)max_worksheets; i++) - ws_array[i] = 0; + if (strcmp (filename, "--help") == 0) + display_usage (); + if (strcmp (filename, "-?") == 0) + display_usage (); + } + if (Ascii) + { /* Disable it if DumpPage or Xtract isn't used... */ + if (!(DumpPage || Xtract)) + Ascii = 0; + } + if (Xtract) + trim_edges = 0; /* No trimming when extracting... */ + if (OutputXML) + aggressive = 0; - str_array = (uni_string **)malloc(max_strings*sizeof(uni_string *)); - for (i=0; i<(int)max_strings; i++) - str_array[i] = 0; + /* Init arrays... */ + ws_array = (work_sheet **) malloc (max_worksheets * sizeof (work_sheet *)); + for (i = 0; i < (int) max_worksheets; i++) + ws_array[i] = 0; - font_array = (font_attr **)malloc(max_fonts * sizeof(font_attr *)); - f_cnt = (fnt_cnt *)malloc(max_fonts * sizeof(fnt_cnt)); - for (i=0; i<(int)max_fonts; i++) - { /* I assume these won't fail since we are just starting up... */ - font_array[i] = 0; - f_cnt[i].name = 0; - } - xf_array = (xf_attr **)malloc(max_xformats * sizeof(xf_attr *)); - for (i=0; i<(int)max_xformats; i++) - xf_array[i] = 0; + str_array = (uni_string **) malloc (max_strings * sizeof (uni_string *)); + for (i = 0; i < (int) max_strings; i++) + str_array[i] = 0; - uni_string_clear(&author); - uni_string_clear(&default_font); - umask(GLOBAL_UMASK); + font_array = (font_attr **) malloc (max_fonts * sizeof (font_attr *)); + f_cnt = (fnt_cnt *) malloc (max_fonts * sizeof (fnt_cnt)); + for (i = 0; i < (int) max_fonts; i++) + { /* I assume these won't fail since we are just starting up... */ + font_array[i] = 0; + f_cnt[i].name = 0; + } + xf_array = (xf_attr **) malloc (max_xformats * sizeof (xf_attr *)); + for (i = 0; i < (int) max_xformats; i++) + xf_array[i] = 0; + + uni_string_clear (&author); + uni_string_clear (&default_font); + umask (GLOBAL_UMASK); #if 1 && defined(WIN32) - if( 0 != filename[0] && ':' == filename[1] ) - { - _chdrive(tolower((unsigned char)filename[0]) - 'a' + 1); - /* cut the drive from the filename */ - memmove(filename,filename+2,strlen(filename+2)+1); - } + if (0 != filename[0] && ':' == filename[1]) + { + _chdrive (tolower ((unsigned char) filename[0]) - 'a' + 1); + /* cut the drive from the filename */ + memmove (filename, filename + 2, strlen (filename + 2) + 1); + } #endif - /* If successful, this calls scan_file to extract the work book... */ - cfs = cole_mount(filename, &colerrno); - if (cfs == NULL) - { - cole_perror (NULL, colerrno); - exit(1); - } - while (cole_locate_filename (cfs, SectionName[f_ptr], NULL, scan_file, &colerrno)) - { - if (f_ptr) - { /* Two strikes...we're out! */ - cole_perror (PRGNAME, colerrno); - if (colerrno == COLE_EFILENOTFOUND) - fprintf(stderr, "Section: Workbook\n"); - break; - } - else - f_ptr++; + /* If successful, this calls scan_file to extract the work book... */ + cfs = cole_mount (filename, &colerrno); + if (cfs == NULL) + { + cole_perror (NULL, colerrno); + exit (1); + } + while (cole_locate_filename + (cfs, SectionName[f_ptr], NULL, scan_file, &colerrno)) + { + if (f_ptr) + { /* Two strikes...we're out! */ + cole_perror (PRGNAME, colerrno); + if (colerrno == COLE_EFILENOTFOUND) + fprintf (stderr, "Section: Workbook\n"); + break; } + else + f_ptr++; + } - if (cole_umount (cfs, &colerrno)) - { - cole_perror (PRGNAME, colerrno); - exit(1); - } + if (cole_umount (cfs, &colerrno)) + { + cole_perror (PRGNAME, colerrno); + exit (1); + } - for (i=0; istr) + free (str_array[i]->str); + free (str_array[i]); + } + } + + for (i = 0; i < (int) max_fonts; i++) + { + if (font_array[i]) + { + if (font_array[i]->name.str) + free (font_array[i]->name.str); + free (font_array[i]); + if (f_cnt[i].name) + { + if (f_cnt[i].name->str) + free (f_cnt[i].name->str); + free (f_cnt[i].name); + } + } + } + + + for (i = 0; i < (int) max_worksheets; i++) + { + if (ws_array[i]) + { + if (ws_array[i]->ws_title.str) + free (ws_array[i]->ws_title.str); + if (ws_array[i]->c_array) + { + for (j = 0; j < ws_array[i]->max_rows; j++) { - if (str_array[i]->str) - free(str_array[i]->str); - free(str_array[i]); - } - } - - for (i=0; i<(int)max_fonts; i++) - { - if (font_array[i]) - { - if (font_array[i]->name.str) - free(font_array[i]->name.str); - free(font_array[i]); - if (f_cnt[i].name) + for (k = 0; k < ws_array[i]->max_cols; k++) + { + if (ws_array[i]-> + c_array[(j * ws_array[i]->max_cols) + k]) { - if (f_cnt[i].name->str) - free(f_cnt[i].name->str); - free(f_cnt[i].name); + if (ws_array[i]-> + c_array[(j * ws_array[i]->max_cols) + + k]->ustr.str) + free (ws_array[i]-> + c_array[(j * ws_array[i]->max_cols) + + k]->ustr.str); + if (ws_array[i]-> + c_array[(j * ws_array[i]->max_cols) + + k]->ustr.fmt_run) + free (ws_array[i]-> + c_array[(j * ws_array[i]->max_cols) + + k]->ustr.fmt_run); + if (ws_array[i]-> + c_array[(j * ws_array[i]->max_cols) + + k]->h_link.str) + free (ws_array[i]-> + c_array[(j * ws_array[i]->max_cols) + + k]->h_link.str); + free (ws_array[i]-> + c_array[(j * ws_array[i]->max_cols) + k]); } + } } + free (ws_array[i]->c_array); + } + free (ws_array[i]); } - - - for (i=0; i<(int)max_worksheets; i++) + } + + + for (i = 0; i < (int) max_xformats; i++) + { + if (xf_array[i]) + free (xf_array[i]); + } + + if (numCustomColors) + { + for (i = 0; i < numCustomColors; i++) + free (customColors[i]); + free (customColors); + } + + if (default_font.str) + free (default_font.str); + if (author.str) + free (author.str); + if (title) + free (title); + if (lastUpdated) + free (lastUpdated); + + return 0; +} + + + +void +scan_file (COLEDIRENT * cde, void *_info) +{ + U32 count = 0; + U16 target = 0, opcode = 0, version = 0; + U8 buf[16]; + COLEFILE *cf; + COLERRNO err; + + (void) _info; + /*UNUSED*/ cf = cole_fopen_direntry (cde, &err); + if (cf == 0) + { /* error abort processing */ + cole_perror (PRGNAME, err); + return; + } + + /* Read & process the file... */ + while (cole_fread (cf, buf, 1, &err)) + { + /* The BIFF record format: + * - byte 0: opcode + * - byte 1: version (?) + * - bytes 2 and 3: 16-bit data length + * - from byte 4: record data + */ + if (count > 3) + main_line_processor (opcode, version, count - 4, target, buf[0]); + else if (count == 0) + opcode = (U16) buf[0]; + else if (count == 1) + version = (U16) buf[0]; + else if (count == 2) + target = (U16) buf[0]; + else if (count == 3) + target |= (U16) (buf[0] << 8); + if ((count >= 3) && (count == (U32) target + 3)) + count = 0; + else + count++; + + if (MaxColExceeded || MaxRowExceeded || MaxWorksheetsExceeded) + break; /* We're outta memory and therefore...done */ + + } + cole_fclose (cf, &err); + + if (Ascii) + { + if (DumpPage) + { /* Output the XLS Parameters */ + int i; + printf ("There are %d pages total.\n", sheet_count + 1); + for (i = 0; i <= sheet_count; i++) + { + printf ("Page:%d Name:%s MaxRow:%ld MaxCol:%ld\n", i, + ws_array[i]->ws_title.str ? (char *) ws_array[i]-> + ws_title.str : "(Unknown Page)", + (long) ws_array[i]->biggest_row, + (long) ws_array[i]->biggest_col); + } + } + else if (Xtract) + OutputPartialTableAscii (); + } + else + { + if (DumpPage) + { /* Output the XLS Parameters */ + int i; + output_header (); + printf ("

There are %d pages total.

\n", sheet_count + 1); + for (i = 0; i <= sheet_count; i++) + { + printf ("

Page:%d Name:%s MaxRow:%ld MaxCol:%ld

\n", i, + ws_array[i]->ws_title.str ? (char *) ws_array[i]-> + ws_title.str : "(Unknown Page)", + (long) ws_array[i]->biggest_row, + (long) ws_array[i]->biggest_col); + } + + output_footer (); + } + else { - if (ws_array[i]) + if (OutputXML) + OutputTableXML (); + else + OutputTableHTML (); + } + } +} + + + + + + +/*! returns 1 on error, 0 on success */ +int +ws_init (int i) +{ + U32 j; + U16 k; + if (i >= (int) max_worksheets) + return 1; + + ws_array[i] = (work_sheet *) malloc (sizeof (work_sheet)); + if (ws_array[i]) + { + ws_array[i]->spanned = 0; + ws_array[i]->first_row = 0; + ws_array[i]->biggest_row = -1; + ws_array[i]->max_rows = ROWS_INCR; + ws_array[i]->first_col = 0; + ws_array[i]->biggest_col = -1; + ws_array[i]->max_cols = COLS_INCR; + uni_string_clear (&ws_array[i]->ws_title); + ws_array[i]->c_array = + (cell **) malloc (ROWS_INCR * COLS_INCR * sizeof (cell *)); + if (ws_array[i]->c_array == 0) + return 1; + for (j = 0; j < ROWS_INCR; j++) + for (k = 0; k < COLS_INCR; k++) + ws_array[i]->c_array[(j * ws_array[i]->max_cols) + k] = 0; + } + else + return 1; + + return 0; +} + + + +/*! returns 1 on error, 0 on success */ +int +add_more_worksheet_ptrs (void) +{ + work_sheet **tws_array; + int pages; + + if (MaxWorksheetsExceeded) + return 1; + + if (sheet_count > (int) max_worksheets) + pages = + (((sheet_count - max_worksheets) / WORKSHEETS_INCR) + + 1) * WORKSHEETS_INCR; + else + pages = WORKSHEETS_INCR; + tws_array = (work_sheet **) realloc (ws_array, + (max_worksheets + + pages) * sizeof (work_sheet *)); + + if (tws_array == NULL) + { + MaxWorksheetsExceeded = 1; + return 1; + } + else + { /* Next init the array... */ + unsigned int i; + + ws_array = tws_array; + + for (i = max_worksheets; i < max_worksheets + pages; i++) + ws_array[i] = 0; + + max_worksheets += pages; + last_sheet = max_worksheets - 1; + } + return 0; +} + + + +int +resize_c_array (work_sheet * ws, U32 new_rows, U16 new_cols) +{ + cell **tc_array; + if (ws == 0) + return 1; + if (ws->c_array == 0) + return 1; + + tc_array = + (cell **) malloc ((ws->max_rows + new_rows) * (ws->max_cols + new_cols) * + sizeof (cell *)); + + if (tc_array == NULL) + return 1; + else + { + U32 j; + U16 k; + + memset (tc_array, 0, + (ws->max_rows + new_rows) * (ws->max_cols + + new_cols) * sizeof (cell *)); + for (j = 0; j < (ws->max_rows); j++) + { + for (k = 0; k < ws->max_cols; k++) + tc_array[(j * (ws->max_cols + new_cols)) + k] = + ws->c_array[(j * ws->max_cols) + k]; + } + ws->max_cols += new_cols; + ws->max_rows += new_rows; + free (ws->c_array); + ws->c_array = tc_array; + } + return 0; +} + + + +void +add_wb_array (U16 r, U16 c, U16 xf, U16 type, U8 uni, + U8 * str, U16 len, U16 crun_cnt, U8 * fmt_run) +{ + work_sheet *ws; + + if ((sheet_count < 0) || (r > HARD_MAX_ROWS) || (c > HARD_MAX_COLS)) + return; + if (sheet_count >= (int) max_worksheets) + { + if (add_more_worksheet_ptrs ()) + return; + } + if (ws_array[sheet_count] == 0) + { + if (ws_init (sheet_count)) + return; + } + ws = ws_array[sheet_count]; + if (r >= ws->max_rows) + { + if (MaxRowExceeded) + return; + else + { + int diff = ((r - ws->max_rows) / ROWS_INCR) + 1; + if (resize_c_array (ws, ROWS_INCR * diff, 0)) + { + MaxRowExceeded = 1; + return; + } + } + } + if (c >= ws->max_cols) + { + if (MaxColExceeded) + return; + else + { + U16 diff = (U16) (((c - ws->max_cols) / COLS_INCR) + 1); + if (resize_c_array (ws, 0, (U16) (COLS_INCR * diff))) + { + MaxColExceeded = 1; + return; + } + } + } + if (ws->c_array[(r * ws->max_cols) + c] == 0) + { + if (r > ws_array[sheet_count]->biggest_row) + ws_array[sheet_count]->biggest_row = r; + if (c > ws_array[sheet_count]->biggest_col) + ws_array[sheet_count]->biggest_col = c; + ws->c_array[(r * ws->max_cols) + c] = (cell *) malloc (sizeof (cell)); + if (ws->c_array[(r * ws->max_cols) + c]) + { + if (str) + { + ws->c_array[(r * ws->max_cols) + c]->ustr.str = + (U8 *) malloc (len + 1); + if (ws->c_array[(r * ws->max_cols) + c]->ustr.str) { - if (ws_array[i]->ws_title.str) - free(ws_array[i]->ws_title.str); - if (ws_array[i]->c_array) + memcpy (ws->c_array[(r * ws->max_cols) + c]->ustr.str, str, + len); + ws->c_array[(r * ws->max_cols) + c]->ustr.str[len] = 0; + } + ws->c_array[(r * ws->max_cols) + c]->ustr.uni = uni; + ws->c_array[(r * ws->max_cols) + c]->ustr.len = len; + if (fmt_run && crun_cnt) + { + int rlen = crun_cnt * 4; + + ws->c_array[(r * ws->max_cols) + c]->ustr.fmt_run = + malloc (rlen); + if (ws->c_array[(r * ws->max_cols) + c]->ustr.fmt_run) + { + memcpy (ws->c_array[(r * ws->max_cols) + c]->ustr. + fmt_run, fmt_run, rlen); + ws->c_array[(r * ws->max_cols) + c]->ustr.crun_cnt = + crun_cnt; + } + else + ws->c_array[(r * ws->max_cols) + c]->ustr.crun_cnt = 0; + } + else + { + ws->c_array[(r * ws->max_cols) + c]->ustr.fmt_run = 0; + ws->c_array[(r * ws->max_cols) + c]->ustr.crun_cnt = 0; + } + } + else + uni_string_clear (&ws->c_array[(r * ws->max_cols) + c]->ustr); + + ws->c_array[(r * ws->max_cols) + c]->xfmt = xf; + ws->c_array[(r * ws->max_cols) + c]->type = type; + ws->c_array[(r * ws->max_cols) + c]->spanned = 0; + ws->c_array[(r * ws->max_cols) + c]->rowspan = 0; + ws->c_array[(r * ws->max_cols) + c]->colspan = 0; + uni_string_clear (&ws->c_array[(r * ws->max_cols) + c]->h_link); + } + } + else /* Default attributes already copied */ + { + if (r > ws_array[sheet_count]->biggest_row) + ws_array[sheet_count]->biggest_row = r; + if (c > ws_array[sheet_count]->biggest_col) + ws_array[sheet_count]->biggest_col = c; + if (str) + { /* Check if a place holder is there and free it */ + if (ws->c_array[(r * ws->max_cols) + c]->ustr.str != 0) + free (ws->c_array[(r * ws->max_cols) + c]->ustr.str); + + ws->c_array[(r * ws->max_cols) + c]->ustr.str = + (U8 *) malloc (len + 1); + if (ws->c_array[(r * ws->max_cols) + c]->ustr.str) + { + memcpy (ws->c_array[(r * ws->max_cols) + c]->ustr.str, str, + len); + ws->c_array[(r * ws->max_cols) + c]->ustr.str[len] = 0; + } + ws->c_array[(r * ws->max_cols) + c]->ustr.len = len; + ws->c_array[(r * ws->max_cols) + c]->ustr.uni = uni; + if (fmt_run && crun_cnt) + { + int rlen = crun_cnt * 4; + + ws->c_array[(r * ws->max_cols) + c]->ustr.fmt_run = + malloc (rlen); + if (ws->c_array[(r * ws->max_cols) + c]->ustr.fmt_run) + { + memcpy (ws->c_array[(r * ws->max_cols) + c]->ustr.fmt_run, + fmt_run, rlen); + ws->c_array[(r * ws->max_cols) + c]->ustr.crun_cnt = + crun_cnt; + } + else + ws->c_array[(r * ws->max_cols) + c]->ustr.crun_cnt = 0; + } + else + { + ws->c_array[(r * ws->max_cols) + c]->ustr.fmt_run = 0; + ws->c_array[(r * ws->max_cols) + c]->ustr.crun_cnt = 0; + } + } + else + { + if (ws->c_array[(r * ws->max_cols) + c]->ustr.str == 0) + { + ws->c_array[(r * ws->max_cols) + c]->ustr.len = 0; + ws->c_array[(r * ws->max_cols) + c]->ustr.uni = 0; + ws->c_array[(r * ws->max_cols) + c]->ustr.fmt_run = 0; + ws->c_array[(r * ws->max_cols) + c]->ustr.crun_cnt = 0; + } + } + ws->c_array[(r * ws->max_cols) + c]->xfmt = xf; + ws->c_array[(r * ws->max_cols) + c]->type = type; + ws->c_array[(r * ws->max_cols) + c]->spanned = 0; + ws->c_array[(r * ws->max_cols) + c]->rowspan = 0; + ws->c_array[(r * ws->max_cols) + c]->colspan = 0; + } +} + +void +update_cell_xf (U16 r, U16 c, U16 xf) +{ + work_sheet *ws; + + if ((sheet_count < 0) || (r > HARD_MAX_ROWS) || (c > HARD_MAX_COLS)) + return; + if (sheet_count >= (int) max_worksheets) + { + if (add_more_worksheet_ptrs ()) + return; + } + if (ws_array[sheet_count] == 0) + { + if (ws_init (sheet_count)) + return; + } + if (r >= ws_array[sheet_count]->max_rows) + { + if (MaxRowExceeded) + return; + else + { + int diff = ((r - ws_array[sheet_count]->max_rows) / ROWS_INCR) + 1; + if (resize_c_array (ws_array[sheet_count], ROWS_INCR * diff, 0)) + { + MaxRowExceeded = 1; + return; + } + } + } + if (c >= ws_array[sheet_count]->max_cols) + { + if (MaxColExceeded) + return; + else + { + int diff = ((c - ws_array[sheet_count]->max_cols) / COLS_INCR) + 1; + if (resize_c_array + (ws_array[sheet_count], 0, (U16) (COLS_INCR * diff))) + { + MaxColExceeded = 1; + return; + } + } + } + + ws = ws_array[sheet_count]; + if (ws->c_array[(r * ws->max_cols) + c] == 0) + { + ws->c_array[(r * ws->max_cols) + c] = (cell *) malloc (sizeof (cell)); + if (ws->c_array[(r * ws->max_cols) + c]) + { + uni_string_clear (&ws->c_array[(r * ws->max_cols) + c]->ustr); + ws->c_array[(r * ws->max_cols) + c]->xfmt = xf; + ws->c_array[(r * ws->max_cols) + c]->type = 1; /* This is the Blank Cell type */ + + if (r > ws_array[sheet_count]->biggest_row) + ws_array[sheet_count]->biggest_row = r; + if (c > ws_array[sheet_count]->biggest_col) + ws_array[sheet_count]->biggest_col = c; + ws->c_array[(r * ws->max_cols) + c]->spanned = 0; + ws->c_array[(r * ws->max_cols) + c]->rowspan = 0; + ws->c_array[(r * ws->max_cols) + c]->colspan = 0; + uni_string_clear (&ws->c_array[(r * ws->max_cols) + c]->h_link); + } + } +/* else + { + printf("R:%02X C:%02X XF:%02X is:%02X\n", + r, c, xf, ws->c_array[r][c]->xfmt); + } */ +} + +void +update_cell_hyperlink (U16 r, U16 c, U8 * hyperlink, int len, U16 uni) +{ + work_sheet *ws; + + if (sheet_count < 0) /* Used to do a "0 <" check on r & c */ + return; + if (sheet_count >= (int) max_worksheets) + { + if (add_more_worksheet_ptrs ()) + return; + } + if (ws_array[sheet_count] == 0) + { + if (ws_init (sheet_count)) + return; + } + if (r >= ws_array[sheet_count]->max_rows) + { + if (MaxRowExceeded) + return; + else + { + int diff = ((r - ws_array[sheet_count]->max_rows) / ROWS_INCR) + 1; + if (resize_c_array (ws_array[sheet_count], ROWS_INCR * diff, 0)) + { + MaxRowExceeded = 1; + return; + } + } + } + if (c >= ws_array[sheet_count]->max_cols) + { + if (MaxColExceeded) + return; + else + { + int diff = ((c - ws_array[sheet_count]->max_cols) / COLS_INCR) + 1; + if (resize_c_array + (ws_array[sheet_count], 0, (U16) (COLS_INCR * diff))) + { + MaxColExceeded = 1; + return; + } + } + } + + ws = ws_array[sheet_count]; + if (ws->c_array[(r * ws->max_cols) + c] == 0) + { /* should not get here, but just in case */ + return; + } + if (ws->c_array[(r * ws->max_cols) + c]->h_link.str == 0) + { + ws->c_array[(r * ws->max_cols) + c]->h_link.str = (U8 *) malloc (len); + if (ws->c_array[(r * ws->max_cols) + c]->h_link.str) + memcpy (ws->c_array[(r * ws->max_cols) + c]->h_link.str, hyperlink, + len); + ws->c_array[(r * ws->max_cols) + c]->h_link.uni = uni; + if (len) + { + if (uni < 2) + ws->c_array[(r * ws->max_cols) + c]->h_link.len = (U16) (len - 1); + else + ws->c_array[(r * ws->max_cols) + c]->h_link.len = (U16) (len - 2); + } + } +/* else + { + printf("R:%02X C:%02X XF:%02X is:%s\n", + r, c, xf, ws->c_array[r][c]->h_link.str); + } */ +} + +void +add_str_array (U8 uni, U8 * str, U16 len, U8 * fmt_run, U8 crun_cnt) +{ + + if ((str == 0) || (len == 0)) + { + next_string++; /* increment for empty strings, too */ + return; + } + if (next_string >= max_strings) + { + uni_string **tstr_array; + unsigned long new_max_str; + size_t new_size; + + new_max_str = max_strings + STRINGS_INCR; + while (next_string >= new_max_str) + { /* who knows how many empty strings (see above) we got in a row + * - better make sure there's enough space allocated + */ + new_max_str += STRINGS_INCR; + } + + new_size = new_max_str * sizeof (uni_string *); + tstr_array = (uni_string **) realloc (str_array, new_size); + + if (tstr_array == NULL) + { + MaxStringsExceeded = 1; +/* fprintf(stderr, "%s: cannot allocate %d bytes for string storage %d: %s", + PRGNAME, new_size, errno, strerror(errno)); */ + return; + } + else + { + unsigned long i; + + str_array = tstr_array; + + /* Clear the new string slots */ + for (i = max_strings; i < new_max_str; i++) + str_array[i] = 0; + + max_strings = new_max_str; + } + } + + if (str_array[next_string] == 0) + { /* Can this ever be false? If yes, wouldn't that be a bug? -- VDv */ + str_array[next_string] = (uni_string *) malloc (sizeof (uni_string)); + if (str_array[next_string]) + { + str_array[next_string]->str = (U8 *) malloc (len + 1); + if (str_array[next_string]->str) + { + memcpy (str_array[next_string]->str, str, len); + str_array[next_string]->str[len] = 0; + str_array[next_string]->len = len; + str_array[next_string]->uni = uni; + if (fmt_run && crun_cnt) + { + int rlen = crun_cnt * 4; + + str_array[next_string]->fmt_run = malloc (rlen); + if (str_array[next_string]->fmt_run) + { + memcpy (str_array[next_string]->fmt_run, fmt_run, rlen); + str_array[next_string]->crun_cnt = crun_cnt; + } + else + { + str_array[next_string]->crun_cnt = 0; + MaxStringsExceeded = 1; + } + } + else + { + str_array[next_string]->fmt_run = 0; + str_array[next_string]->crun_cnt = 0; + } + } + else + { + MaxStringsExceeded = 1; +/* fprintf(stderr, "%s: cannot allocate %d bytes for string storage %d: %s", + PRGNAME, len+1, errno, strerror(errno)); */ + } + } + else + { + MaxStringsExceeded = 1; +/* fprintf(stderr, "%s: cannot allocate %d bytes for string storage %d: %s", + PRGNAME, sizeof(uni_string), errno, strerror(errno)); */ + } + } + next_string++; +} + +void +add_font (U16 size, U16 attr, U16 c_idx, U16 bold, U16 super, U8 underline, + U16 uni, U8 * n, U16 len) +{ + if (n == 0) + return; + if (next_font >= max_fonts) + { + font_attr **tfont_array; + fnt_cnt *tf_cnt; + tfont_array = + (font_attr **) realloc (font_array, + (max_fonts * FONTS_INCR) * + sizeof (font_attr *)); + tf_cnt = + (fnt_cnt *) realloc (f_cnt, + (max_fonts * FONTS_INCR) * sizeof (fnt_cnt)); + + if ((tf_cnt == NULL) || (tfont_array == NULL)) + { + MaxFontsExceeded = 1; + return; + } + else + { /* Next init the array... */ + unsigned int i; + + font_array = tfont_array; + f_cnt = tf_cnt; + + for (i = max_fonts; i < max_fonts + FONTS_INCR; i++) + { + font_array[i] = 0; + f_cnt[i].name = 0; + } + max_fonts += FONTS_INCR; + } + } + + if (font_array[next_font] == 0) + { + font_array[next_font] = (font_attr *) malloc (sizeof (font_attr)); + if (font_array[next_font]) + { + font_array[next_font]->name.str = (U8 *) malloc (len + 1); + if (font_array[next_font]->name.str) + { + font_array[next_font]->attr = attr; + font_array[next_font]->c_idx = c_idx; + font_array[next_font]->bold = bold; + font_array[next_font]->super = super; + font_array[next_font]->underline = underline; + font_array[next_font]->name.uni = uni; + memcpy (font_array[next_font]->name.str, n, len); + font_array[next_font]->name.str[len] = 0; + font_array[next_font]->name.len = len; + font_array[next_font]->name.fmt_run = 0; + font_array[next_font]->name.crun_cnt = 0; + + /* We will "pre-digest" the font size.. */ + if (size >= 0x02D0) /* 36 pts */ + font_array[next_font]->size = 7; + else if (size >= 0x01E0) /* 24 pts */ + font_array[next_font]->size = 6; + else if (size >= 0x0168) /* 18 pts */ + font_array[next_font]->size = 5; + else if (size >= 0x00F0) /* 12 pts */ + font_array[next_font]->size = 4; + else if (size >= 0x00C8) /* 10 pts */ + font_array[next_font]->size = 3; + else if (size >= 0x00A0) /* 8 pts */ + font_array[next_font]->size = 2; + else + font_array[next_font]->size = 1; + } + } + } + next_font++; + if (next_font == 4) /* Per the doc's - number 4 doesn't exist. */ + next_font++; +} + +void +add_ws_title (U16 uni, U8 * n, U16 len) +{ + if (n == 0) + return; + + if (next_ws_title >= max_worksheets) + { + if (add_more_worksheet_ptrs ()) + return; + } + + if (ws_array[next_ws_title] == 0) + { + if (ws_init (next_ws_title)) + return; + } + if (ws_array[next_ws_title]->ws_title.str == 0) + { + ws_array[next_ws_title]->ws_title.str = (U8 *) malloc (len + 1); + if (ws_array[next_ws_title]->ws_title.str) + { + ws_array[next_ws_title]->ws_title.uni = uni; + memcpy (ws_array[next_ws_title]->ws_title.str, n, len); + ws_array[next_ws_title]->ws_title.str[len] = 0; + ws_array[next_ws_title]->ws_title.len = len; + ws_array[next_ws_title]->ws_title.crun_cnt = 0; + ws_array[next_ws_title]->ws_title.fmt_run = 0; + } + } + next_ws_title++; +} + +void +add_xf_array (U16 fnt_idx, U16 fmt_idx, U16 gen, U16 align, + U16 indent, U16 b_style, U16 b_l_color, U32 b_t_color, + U16 cell_color) +{ + if (next_xf >= max_xformats) + { + xf_attr **txf_array; + + txf_array = + (xf_attr **) realloc (xf_array, + (max_xformats + + XFORMATS_INCR) * sizeof (xf_attr *)); + if (txf_array == NULL) + { + MaxXFExceeded = 1; + return; + } + else + { + unsigned int i; + + xf_array = txf_array; + + for (i = max_xformats; i < (max_xformats + XFORMATS_INCR); i++) + xf_array[i] = 0; + + max_xformats += XFORMATS_INCR; + } + } + + if (xf_array[next_xf] == 0) + { + xf_array[next_xf] = (xf_attr *) malloc (sizeof (xf_attr)); + if (xf_array[next_xf]) + { + xf_array[next_xf]->fnt_idx = fnt_idx; + xf_array[next_xf]->fmt_idx = fmt_idx; + xf_array[next_xf]->gen = gen; + xf_array[next_xf]->align = align; + xf_array[next_xf]->indent = indent; + xf_array[next_xf]->b_style = b_style; + xf_array[next_xf]->b_l_color = b_l_color; + xf_array[next_xf]->b_t_color = b_t_color; + xf_array[next_xf]->cell_color = cell_color; + } + next_xf++; + } +} + +void +decodeBoolErr (U16 value, U16 flag, char *str) +{ + if (str == 0) + return; + + if (flag == 0) + { + if (value == 1) + strcpy (str, "TRUE"); + else + strcpy (str, "FALSE"); + } + else + { + switch (value) + { + case 0x00: + strcpy (str, "#NULL!"); + break; + case 0x07: + strcpy (str, "#DIV/0!"); + break; + case 0x0F: + strcpy (str, "#VALUE!"); + break; + case 0x17: + strcpy (str, "#REF!"); + break; + case 0x1D: + strcpy (str, "#NAME?"); + break; + case 0x24: + strcpy (str, "#NUM!"); + break; + case 0x2A: + strcpy (str, "#N/A"); + break; + default: + strcpy (str, "#ERR"); + break; + } + } +} + +int +IsCellNumeric (cell * c) +{ + int ret_val = 0; + + switch (c->type & 0x00FF) + { + case 0x02: /* Int */ + case 0x03: /* Float */ +/* case 0x06: *//* Formula */ + /* case 0x08: */ + case 0x7E: /* RK */ + /* case 0xBC: */ + /* case 0x21: */ + case 0xBD: /* MulRK */ + ret_val = 1; + break; + default: + break; + } + return ret_val; +} + +/*! \retval 0 not safe at all. + \retval 1 extended format is OK + \retval 2 Fonts OK */ +int +IsCellSafe (cell * c) +{ + int safe = 0; + + if (c->xfmt < next_xf) + { + if (xf_array[c->xfmt]) + { + safe = 1; + if (xf_array[c->xfmt]->fnt_idx < next_font) + { + if (font_array[xf_array[c->xfmt]->fnt_idx]) + safe = 2; + } + } + } + return safe; +} + +int +IsCellFormula (cell * c) +{ + if ((c->type > 0x0100) || (c->type == 0x0006)) + return 1; + else + return 0; +} + +void +output_cell (cell * c, int xml) +{ + html_attr h; + + if (c == NULL) + printf (xml ? ">" : " "); + else if (c->spanned != 0) + { + if (xml) + printf (">"); + return; + } + else + { /* Determine whether or not it is of numeric origin.. */ + int numeric = IsCellNumeric (c); /* 0=Text 1=Numeric */ + html_flag_init (&h); + if (c->xfmt == 0) + { /* Unknown format... */ + printf (xml ? ">" : ""); /* This section doesn't use Unicode */ + if (c->ustr.str) + OutputString (&(c->ustr)); + else + printf (xml ? "" : " "); + } + else + { /* This is the BIFF7 & 8 stuff... */ + int safe; + int nullString = 1; + + safe = IsCellSafe (c); + + if (c->ustr.str) + { + if (c->ustr.uni < 2) /* UNI? */ + nullString = null_string (c->ustr.str); + else + nullString = 0; + } + + /* First take care of text color & alignment */ + printf (xml ? "" : "rowspan != 0) || (c->colspan != 0)) + { + if (c->colspan) + printf (xml ? " colspan=\"%d\"" : " COLSPAN=\"%d\"", + c->colspan); + if (c->rowspan) + printf (xml ? " rowspan=\"%d\"" : " ROWSPAN=\"%d\"", + c->rowspan); + } + if ((safe > 0) && (!nullString)) + { + switch (xf_array[c->xfmt]->align & 0x0007) + { /* Override default table alignment when needed */ + case 2: + case 6: /* Center across selection */ + if (strcmp (default_alignment, "center") != 0) + printf (xml ? "" : " ALIGN=\"center\""); + break; + case 0: /* General alignment */ + if (numeric) /* Numbers */ + { + if (strcmp (default_alignment, "right") != 0) + printf (xml ? "" : " ALIGN=\"right\""); + } + else if ((c->type & 0x00FF) == 0x05) + { /* Boolean */ + if (strcmp (default_alignment, "center") != 0) + printf (xml ? "" : " ALIGN=\"center\""); + } + else + { + if (strcmp (default_alignment, "left") != 0) + printf (xml ? "" : " ALIGN=\"left\""); + } + break; + case 3: + if (strcmp (default_alignment, "right") != 0) + printf (xml ? "" : " ALIGN=\"right\""); + break; + case 1: + default: + if (strcmp (default_alignment, "left") != 0) + printf (xml ? "" : " ALIGN=\"left\""); + break; + } + switch ((xf_array[c->xfmt]->align & 0x0070) >> 4) + { + case 0: + printf (xml ? "" : " VALIGN=\"top\""); + break; + case 1: + printf (xml ? "" : " VALIGN=\"middle\""); + break; + case 2: /* General alignment */ + if (safe > 1) + { + if ((font_array[xf_array[c->xfmt]->fnt_idx]-> + super & 0x0003) == 0x0001) + printf (xml ? "" : " VALIGN=\"top\""); /* Superscript */ + } + break; + default: + if (safe > 1) + { + if ((font_array[xf_array[c->xfmt]->fnt_idx]-> + super & 0x0003) == 0x0001) + printf (xml ? "" : " VALIGN=\"top\""); /* Superscript */ + } + break; + } + } + /* Next do the bgcolor... BGCOLOR="" */ + if (safe && use_colors) + { + int fgcolor; + /* int bgcolor = (xf_array[c->xfmt]->cell_color & 0x3F80) >> 7; */ + fgcolor = (xf_array[c->xfmt]->cell_color & 0x007F); + /* printf(" XF:%X BG Color:%d, FG Color:%d", c->xfmt, bgcolor, fgcolor); */ + + /* Might be better by blending bg & fg colors? + If valid, fgcolor != black and fgcolor != white */ + if (!xml) + { + if (numCustomColors) + { + if (fgcolor < numCustomColors) { - for (j=0; jmax_rows; j++) + if (strcmp + (default_background_color, + (char *) customColors[fgcolor - 8]) != 0) + printf (" BGCOLOR=\"%s\"", + customColors[fgcolor - 8]); + } + } + else + { + if (fgcolor < MAX_COLORS) + { + if (strcmp + (default_background_color, + colorTab[fgcolor]) != 0) + printf (" BGCOLOR=\"%s\"", colorTab[fgcolor]); + } + } + } + } + + /* Next set the border color... */ + if (safe && use_colors) + { + int lcolor, rcolor, tcolor, bcolor; + lcolor = xf_array[c->xfmt]->b_l_color & 0x007F; + rcolor = (xf_array[c->xfmt]->b_l_color & 0x3F80) >> 7; + tcolor = xf_array[c->xfmt]->b_t_color & 0x007F; + bcolor = (xf_array[c->xfmt]->b_t_color & 0x3F80) >> 7; + if (((lcolor & rcolor & tcolor & bcolor) == lcolor) + && (lcolor < MAX_COLORS)) + { /* if they are all the same...do it...that is if it's different from BLACK */ + if (numCustomColors == 0) /* Don't do custom borders */ + { + if ((strcmp (colorTab[lcolor], "000000") != 0) + && (strcmp (colorTab[lcolor], "FFFFFF") != 0)) + { + if (!xml) + printf (" BORDERCOLOR=\"%s\"", colorTab[lcolor]); + } + } + } + } + + /* Close up the or ... */ + printf (">"); + + /* Next set font properties */ + if (safe > 1 && !xml) + { + if (!nullString) + output_start_font_attribute (&h, xf_array[c->xfmt]->fnt_idx); + } + + /* Finally, take care of font modifications */ + if ((safe > 1) && (!nullString)) + { + if ((font_array[xf_array[c->xfmt]->fnt_idx]-> + underline & 0x0023) > 0) + { + if (c->h_link.str) + { + printf ("h_link.uni) + { + if (memchr + ((char *) c->h_link.str, ':', + c->h_link.len) == 0) + { + if (memchr + ((char *) c->h_link.str, '@', + c->h_link.len)) + printf ("mailto:"); + } + } + OutputString (&(c->h_link)); + printf ("\">"); + h.uflag = 2; + } + else + { + printf (""); + h.uflag = 1; + } + } + output_start_html_attr (&h, xf_array[c->xfmt]->fnt_idx, 0); + } + if (c->ustr.str) + { + if (safe) + output_formatted_data (&(c->ustr), xf_array[c->xfmt]->fmt_idx, + numeric, IsCellFormula (c)); + else + OutputString (&(c->ustr)); + } + else + printf (xml ? "" : " "); +/* printf(" T:%02X", c->type & 0x00FF); */ + } + + /* Now close the tags... */ + output_end_html_attr (&h); + } + + if (!aggressive) + printf (xml ? "" : "\n"); +} + +void +output_formatted_data (uni_string * u, U16 idx, int numeric, int formula) +{ + if ((idx < max_xformats) && (u->str)) + { + if ((formula_warnings) && (formula)) + { + if (OutputXML) + printf (""); + else + printf ("** "); + notAccurate++; + } + if (numeric) + { + int year, month, date; + long num; + F64 dnum; + int hr, minu, sec, msec; + +/* printf("idx:%d ", idx); */ + switch (idx) + { + case 0x00: /* General */ + dnum = atof ((char *) u->str); + printf ("%.15g", dnum); + break; + case 0x01: /* Number 0 */ + dnum = atof ((char *) u->str); + printf ("%.0f", dnum); + break; + case 0x02: /* Number 0.00 */ + dnum = atof ((char *) u->str); + printf ("%.2f", dnum); + break; + case 0x03: /* Number w/comma 0,000 */ + PrintFloatComma ("%.0f", 0, (F64) atof ((char *) u->str)); + break; + case 0x04: /* Number w/comma 0,000.00 */ + PrintFloatComma ("%.2f", 0, (F64) atof ((char *) u->str)); + break; + case 0x05: /* Currency, no decimal */ + PrintFloatComma ("%.0f", 1, (F64) atof ((char *) u->str)); + break; + case 0x06: /* Currency, no decimal Red on Neg */ + PrintFloatComma ("%.0f", 1, (F64) atof ((char *) u->str)); + break; + case 0x07: /* Currency with decimal */ + PrintFloatComma ("%.2f", 1, (F64) atof ((char *) u->str)); + break; + case 0x08: /* Currency with decimal Red on Neg */ + PrintFloatComma ("%.2f", 1, (F64) atof ((char *) u->str)); + break; + case 0x09: /* Percent 0% */ + if (Csv) + printf ("\""); + dnum = 100.0 * atof ((char *) u->str); + printf ("%.0f%%", dnum); + if (Csv) + printf ("\""); + break; + case 0x0A: /* Percent 0.00% */ + if (Csv) + printf ("\""); + dnum = 100.0 * atof ((char *) u->str); + printf ("%.2f%%", dnum); + if (Csv) + printf ("\""); + break; + case 0x0B: /* Scientific 0.00+E00 */ + if (Csv) + printf ("\""); + dnum = atof ((char *) u->str); + printf ("%.2E", dnum); + if (Csv) + printf ("\""); + break; + case 0x0C: /* Fraction 1 number e.g. 1/2, 1/3 */ + if (Csv) + printf ("\""); + dnum = atof ((char *) u->str); + print_as_fraction (dnum, 1); + if (Csv) + printf ("\""); + break; + case 0x0D: /* Fraction 2 numbers e.g. 1/50, 25/33 */ + if (Csv) + printf ("\""); + dnum = atof ((char *) u->str); + print_as_fraction (dnum, 2); + if (Csv) + printf ("\""); + break; + case 0x0E: /* Date: m-d-y */ + if (Csv) + printf ("\""); + num = atol ((char *) u->str); + NumToDate (num, &year, &month, &date); + printf ("%d-%d-%02d", month, date, year); + if (Csv) + printf ("\""); + break; + case 0x0F: /* Date: d-mmm-yy */ + if (Csv) + printf ("\""); + num = atol ((char *) u->str); + NumToDate (num, &year, &month, &date); + printf ("%d-%s-%02d", date, month_abbr[month - 1], year); + if (Csv) + printf ("\""); + break; + case 0x10: /* Date: d-mmm */ + if (Csv) + printf ("\""); + num = atol ((char *) u->str); + NumToDate (num, &year, &month, &date); + printf ("%d-%s", date, month_abbr[month - 1]); + if (Csv) + printf ("\""); + break; + case 0x11: /* Date: mmm-yy */ + if (Csv) + printf ("\""); + num = atol ((char *) u->str); + NumToDate (num, &year, &month, &date); + printf ("%s-%02d", month_abbr[month - 1], year); + if (Csv) + printf ("\""); + break; + case 0x12: /* Time: h:mm AM/PM */ + if (Csv) + printf ("\""); + FracToTime (u->str, &hr, &minu, 0, 0); + if (hr == 0) + printf ("12:%02d AM", minu); + else if (hr < 12) + printf ("%d:%02d AM", hr, minu); + else if (hr == 12) + printf ("12:%02d PM", minu); + else + printf ("%d:%02d PM", hr - 12, minu); + if (Csv) + printf ("\""); + break; + case 0x13: /* Time: h:mm:ss AM/PM */ + if (Csv) + printf ("\""); + FracToTime (u->str, &hr, &minu, &sec, 0); + if (hr == 0) + printf ("12:%02d:%02d AM", minu, sec); + else if (hr < 12) + printf ("%d:%02d:%02d AM", hr, minu, sec); + else if (hr == 12) + printf ("12:%02d:%02d PM", minu, sec); + else + printf ("%d:%02d:%02d PM", hr - 12, minu, sec); + if (Csv) + printf ("\""); + break; + case 0x14: /* Time: h:mm */ + if (Csv) + printf ("\""); + FracToTime (u->str, &hr, &minu, 0, 0); + printf ("%d:%02d", hr, minu); + if (Csv) + printf ("\""); + break; + case 0x15: /* Time: h:mm:ss */ + if (Csv) + printf ("\""); + FracToTime (u->str, &hr, &minu, &sec, 0); + if ((hr != 0) || (minu != 0) || (sec != 0)) + printf ("%d:%02d:%02d", hr, minu, sec); + else + { + if (Ascii) + putchar (' '); + else + printf (OutputXML ? "" : " "); + } + if (Csv) + printf ("\""); + break; + case 0x25: /* Number with comma, no decimal */ + if (Csv) + printf ("\""); + PrintFloatComma ("%.0f", 0, (F64) atof ((char *) u->str)); + if (Csv) + printf ("\""); + break; + case 0x26: /* Number with comma, no decimal, red on negative */ + if (Csv) + printf ("\""); + PrintFloatComma ("%.0f", 0, (F64) atof ((char *) u->str)); + if (Csv) + printf ("\""); + break; + case 0x27: /* Number with comma & decimal */ + if (Csv) + printf ("\""); + PrintFloatComma ("%.2f", 0, (F64) atof ((char *) u->str)); + if (Csv) + printf ("\""); + break; + case 0x28: /* Number with comma & decimal, red on negative */ + if (Csv) + printf ("\""); + PrintFloatComma ("%.2f", 0, (F64) atof ((char *) u->str)); + if (Csv) + printf ("\""); + break; + case 0x29: /* Number with comma, no decimal */ + if (Csv) + printf ("\""); + PrintFloatComma ("%.2f", 0, (F64) atof ((char *) u->str)); + if (Csv) + printf ("\""); + break; + case 0x2a: /* Currency, no decimal */ + if (Csv) + printf ("\""); + PrintFloatComma ("%.0f", 1, (F64) atof ((char *) u->str)); + if (Csv) + printf ("\""); + break; + case 0x2B: /* Number w/comma & decimal 0,000.00 */ + if (Csv) + printf ("\""); + PrintFloatComma ("%.2f", 0, (F64) atof ((char *) u->str)); + if (Csv) + printf ("\""); + break; + case 0x2C: /* Accounting Currency $0,000.00 */ + { + F64 acc_val = atof ((char *) u->str); + if (Csv) + printf ("\""); + if (acc_val < 0.0) + PrintFloatComma (" (%.2f)", 1, fabs (acc_val)); + else + PrintFloatComma (" %.2f", 1, acc_val); + if (Csv) + printf ("\""); + break; + } + case 0x2D: /* Time: mm:ss */ + if (Csv) + printf ("\""); + FracToTime (u->str, &hr, &minu, &sec, 0); + printf ("%02d:%02d", minu, sec); + if (Csv) + printf ("\""); + break; + case 0x2E: /* Time: [h]:mm:ss */ + if (Csv) + printf ("\""); + FracToTime (u->str, &hr, &minu, &sec, 0); + if (hr) + printf ("%d:%02d:%02d", hr, minu, sec); + else + printf ("%02d:%02d", minu, sec); + if (Csv) + printf ("\""); + break; + case 0x2F: /* Time: mm:ss.0 */ + if (Csv) + printf ("\""); + FracToTime (u->str, &hr, &minu, &sec, &msec); + printf ("%02d:%02d.%01d", minu, sec, msec); + if (Csv) + printf ("\""); + break; + case 0x31: /* Text - if we are here...it's a number */ + dnum = atof ((char *) u->str); + printf ("%g", dnum); + break; + default: /* Unsupported...but, if we are here, it's a number */ + { + char *ptr = strchr ((char *) u->str, '.'); + if (OutputXML) + printf (""); + dnum = atof ((char *) u->str); + if (ptr) + { + if (Csv) + printf ("\"%.15g\"", dnum); + else if (OutputXML) + printf ("%.15g", dnum); + else + printf ("%.15g *", dnum); + } + else + { + num = atol ((char *) u->str); + if (Csv) + printf ("%ld", num); + else if (OutputXML) + printf ("%ld", num); + else + printf ("%ld *", num); + } + +/* printf(" F:%02X", idx); */ + NoFormat++; + } + break; + } + } + else /* Text data */ + OutputString (u); + } + else /* Error handling just dump it. */ + OutputString (u); +} + + + +void +PrintFloatComma (char *fformat, int is_currency, F64 d) +{ + int len, int_len, dec_len; + char *ptr2, buf[64]; + + sprintf (buf, fformat, fabs (d)); + len = strlen (buf); + ptr2 = strchr (buf, '.'); + if (ptr2) + { + int_len = ptr2 - buf; + dec_len = len - int_len; + if (isdigit (buf[0]) == 0) + { + char *ptr = &buf[0]; + while (isdigit (*ptr) == 0) + { + int_len--; + ptr++; + if (*ptr == 0) + break; + } + } + } + else + { + int_len = len; + dec_len = 0; + } + + if (int_len > 3) + { /* we have to do it the hard way... */ + char rbuf[64], buf2[64]; + int neg, i, j, count = 0; + + if (d < 0.0) + neg = 1; + else + neg = 0; + + /* reverse the string. It's easier to work this way. */ + for (i = 0, j = len - 1; i < len; i++, j--) + rbuf[i] = buf[j]; + rbuf[len] = 0; + if (ptr2) + { + memcpy (buf2, rbuf, dec_len); + i = dec_len; + j = dec_len; + } + else + { + i = 0; + j = 0; + } + + for (; i < len; i++, j++) + { + buf2[j] = rbuf[i]; + count++; + if ((count % 3) == 0) + { + if (isdigit (rbuf[i + 1])) + buf2[++j] = ','; + } + } + if (neg) + buf2[j++] = '-'; + if (is_currency) + buf2[j++] = (char) currency_symbol; + buf2[j] = 0; + + len = strlen (buf2); + for (i = 0, j = len - 1; i < len; i++, j--) + buf[i] = buf2[j]; + buf[len] = 0; + if (Csv) + printf ("\"%s\"", buf); + else + printf ("%s", buf); + } + else /* too short for commas, just output it as is. */ + { + if (is_currency) + putchar ((char) currency_symbol); + printf (fformat, d); + } +} + +void +print_as_fraction (F64 d, int digits) +{ + F64 i, j, w, r, closest = 1.0, lim = 9.0; + int ci = 1, cj = 1; + + /* Take care of negative sign */ + if (digits == 2) + lim = 99.0; + if (d < 0) + putchar ('-'); + + /** take care of whole number part */ + w = fabs (d); + if (w >= 1.0) + { + int n = (int) w; + printf ("%d ", n); + r = w - (F64) n; + } + else + r = w; + + /* Get closest fraction - brute force */ + for (j = lim; j > 0.0; j--) + { + for (i = lim; i >= 0.0; i--) + { + if (fabs ((i / j) - r) <= closest) + { + closest = fabs ((i / j) - r); + ci = (int) i; + cj = (int) j; + } + } + } + + /* Done, print it... */ + if (ci != 0) + printf ("%d/%d", ci, cj); +} + +void +trim_sheet_edges (unsigned int sheet) +{ + cell *ce; + int not_done = 1; + S32 r; + U16 c; + + if ((sheet >= max_worksheets) || (ws_array[sheet] == 0) || + (trim_edges == 0) || (ws_array[sheet]->spanned)) + return; + if (ws_array[sheet]->c_array == 0) + return; + if ((ws_array[sheet]->biggest_row == -1) || + (ws_array[sheet]->biggest_col == -1)) + return; + + /* First find top edge */ + for (r = ws_array[sheet]->first_row; r <= ws_array[sheet]->biggest_row; r++) + { + for (c = ws_array[sheet]->first_col; c <= ws_array[sheet]->biggest_col; + c++) + { /* This stuff happens for each cell... */ + ce = ws_array[sheet]->c_array[(r * ws_array[sheet]->max_cols) + c]; + if (ce) + { + if (ce->ustr.str) + { + if (!null_string (ce->ustr.str)) + { + not_done = 0; + break; + } + } + } + } + if (!not_done) + break; + } + if (not_done) + ws_array[sheet]->first_row = ws_array[sheet]->biggest_row; + else + ws_array[sheet]->first_row = r; + + /* Second Find bottom edge */ + not_done = 1; + for (r = ws_array[sheet]->biggest_row; r > (S32) ws_array[sheet]->first_row; + r--) + { + for (c = ws_array[sheet]->first_col; c <= ws_array[sheet]->biggest_col; + c++) + { /* This stuff happens for each cell... */ + ce = ws_array[sheet]->c_array[(r * ws_array[sheet]->max_cols) + c]; + if (ce) + { + if (ce->ustr.str) + { + if (!null_string (ce->ustr.str)) + { + not_done = 0; + break; + } + } + } + } + if (!not_done) + break; + } + ws_array[sheet]->biggest_row = r; + + /* Third find left edge */ + not_done = 1; + for (c = ws_array[sheet]->first_col; c <= ws_array[sheet]->biggest_col; c++) + { + for (r = ws_array[sheet]->first_row; r <= ws_array[sheet]->biggest_row; + r++) + { /* This stuff happens for each cell... */ + ce = ws_array[sheet]->c_array[(r * ws_array[sheet]->max_cols) + c]; + if (ce) + { + if (ce->ustr.str) + { + if (!null_string (ce->ustr.str)) + { + not_done = 0; + break; + } + } + } + } + if (!not_done) + break; + } + if (not_done) + ws_array[sheet]->first_col = ws_array[sheet]->biggest_col; + else + ws_array[sheet]->first_col = c; + + /* Last, find right edge */ + not_done = 1; + for (c = ws_array[sheet]->biggest_col; c > ws_array[sheet]->first_col; c--) + { + for (r = ws_array[sheet]->first_row; r <= ws_array[sheet]->biggest_row; + r++) + { /* This stuff happens for each cell... */ + ce = ws_array[sheet]->c_array[(r * ws_array[sheet]->max_cols) + c]; + if (ce) + { + if (ce->ustr.str) + { + if (!null_string (ce->ustr.str)) + { + not_done = 0; + break; + } + } + } + } + if (!not_done) + break; + } + ws_array[sheet]->biggest_col = c; +} + +/*************** +*! Figures out the best font & alignment for the current table. +* Also sets the default_font and default_alignment. +****************/ +void +update_default_font (unsigned int sheet) +{ + cell *ce; + int r, c, f; + + if ((sheet >= max_worksheets) || (ws_array[sheet] == 0)) + return; + if (ws_array[sheet]->c_array == 0) + return; + + /* Clear the book-keeping info... */ + for (r = 0; r < FONTS_INCR; r++) + { + f_cnt[r].cnt = 0; + if (f_cnt[r].name) + { + if (f_cnt[r].name->str) + free (f_cnt[r].name->str); + free (f_cnt[r].name); + f_cnt[r].name = 0; + } + } + if (default_font.str) + free (default_font.str); + for (r = 0; r < 7; r++) + fnt_size_cnt[r] = 0; + + /* Now check each cell to see what it's using. */ + for (r = ws_array[sheet]->first_row; r <= ws_array[sheet]->biggest_row; r++) + { + for (c = ws_array[sheet]->first_col; c <= ws_array[sheet]->biggest_col; + c++) + { /* This stuff happens for each cell... */ + ce = ws_array[sheet]->c_array[(r * ws_array[sheet]->max_cols) + c]; + if (ce) + { + if ((ce->xfmt < next_xf) && (ce->ustr.str)) + { + if (strcmp ((char *) ce->ustr.str, " ")) + { + if (ce->xfmt < next_xf) + { + if (xf_array[ce->xfmt]) + { + unsigned int fn = xf_array[ce->xfmt]->fnt_idx; + if (fn < next_font) { - for (k=0; kmax_cols; k++) + if (font_array[fn]) + { + if (font_array[fn]->name.str) { - if (ws_array[i]->c_array[(j*ws_array[i]->max_cols)+k]) - { - if (ws_array[i]->c_array[(j*ws_array[i]->max_cols)+k]->ustr.str) - free(ws_array[i]->c_array[(j*ws_array[i]->max_cols)+k]->ustr.str); - if (ws_array[i]->c_array[(j*ws_array[i]->max_cols)+k]->ustr.fmt_run) - free(ws_array[i]->c_array[(j*ws_array[i]->max_cols)+k]->ustr.fmt_run); - if (ws_array[i]->c_array[(j*ws_array[i]->max_cols)+k]->h_link.str) - free(ws_array[i]->c_array[(j*ws_array[i]->max_cols)+k]->h_link.str); - free(ws_array[i]->c_array[(j*ws_array[i]->max_cols)+k]); - } + /* Here's where we check & increment count... */ + incr_f_cnt (& + (font_array[fn]->name)); + if ((font_array[fn]->size < 8) + && (font_array[fn]->size)) + fnt_size_cnt[font_array[fn]-> + size - 1]++; } + } } - free(ws_array[i]->c_array); + } } - free(ws_array[i]); + } } + } } - + } - for (i=0; i<(int)max_xformats; i++) + f = get_default_font (); + if (f == -1) + { + default_font.str = (U8 *) malloc (6); + if (default_font.str) { - if (xf_array[i]) - free(xf_array[i]); + strcpy ((char *) default_font.str, "Arial"); + default_font.uni = 0; + default_font.len = 5; } - - if (numCustomColors) + } + else + { + default_font.str = (U8 *) malloc (f_cnt[f].name->len + 1); + if (default_font.str) { - for (i=0; istr, f_cnt[f].name->len); + default_font.str[f_cnt[f].name->len] = 0; + default_font.uni = f_cnt[f].name->uni; + default_font.len = f_cnt[f].name->len; } + } - if (default_font.str) - free(default_font.str); - if (author.str) - free(author.str); - if (title) - free(title); - if (lastUpdated) - free(lastUpdated); - - return 0; + /* Find the font size with the most counts... + Just re-using variables, c - max cnt, f = position of max cnt */ + c = 0; + f = 3; + for (r = 0; r < 7; r++) + { + if (fnt_size_cnt[r] > c) + { + c = fnt_size_cnt[r]; + f = r; + } + } + if (fnt_size_cnt[2] == c) /* favor size 3... */ + default_fontsize = 3; + else + default_fontsize = f + 1; + + for (r = 0; r < FONTS_INCR; r++) + { + if (f_cnt[r].name != 0) + { + if (f_cnt[r].name->str != 0) + free (f_cnt[r].name->str); + free (f_cnt[r].name); + f_cnt[r].name = 0; + } + } } - - -void scan_file(COLEDIRENT *cde, void *_info) +void +incr_f_cnt (uni_string * name) { - U32 count=0; - U16 target=0, opcode=0, version=0; - U8 buf[16]; - COLEFILE *cf; - COLERRNO err; + int i; - (void) _info; /*UNUSED*/ + if ((name == 0) || (name->str == 0) || (name->str[0] == 0)) + return; - cf = cole_fopen_direntry(cde, &err); - if (cf == 0) - { /* error abort processing */ - cole_perror (PRGNAME, err); - return; - } - - /* Read & process the file... */ - while (cole_fread(cf, buf, 1, &err)) + for (i = 0; i < FONTS_INCR; i++) + { + if (f_cnt[i].name) { - /* The BIFF record format: - * - byte 0: opcode - * - byte 1: version (?) - * - bytes 2 and 3: 16-bit data length - * - from byte 4: record data - */ - if (count > 3) - main_line_processor(opcode, version, count-4, target, buf[0]); - else if (count == 0) - opcode = (U16)buf[0]; - else if (count == 1) - version = (U16)buf[0]; - else if (count == 2) - target = (U16)buf[0]; - else if (count == 3) - target |= (U16)(buf[0]<<8); - if ((count >= 3) && (count == (U32)target + 3)) - count = 0; - else - count++; - - if (MaxColExceeded || MaxRowExceeded || MaxWorksheetsExceeded) - break; /* We're outta memory and therefore...done */ - + if (uni_string_comp (name, f_cnt[i].name) == 0) + f_cnt[i].cnt++; } - cole_fclose(cf, &err); - - if (Ascii) + else { - if (DumpPage) - { /* Output the XLS Parameters */ - int i; - printf("There are %d pages total.\n", sheet_count+1); - for (i=0; i<=sheet_count; i++) - { - printf("Page:%d Name:%s MaxRow:%ld MaxCol:%ld\n", i, - ws_array[i]->ws_title.str ? (char *)ws_array[i]->ws_title.str : "(Unknown Page)", - (long)ws_array[i]->biggest_row, (long)ws_array[i]->biggest_col); - } - } - else if (Xtract) - OutputPartialTableAscii(); - } - else - { - if (DumpPage) - { /* Output the XLS Parameters */ - int i; - output_header(); - printf("

There are %d pages total.

\n", sheet_count+1); - for (i=0; i<=sheet_count; i++) - { - printf("

Page:%d Name:%s MaxRow:%ld MaxCol:%ld

\n", i, - ws_array[i]->ws_title.str ? (char *)ws_array[i]->ws_title.str : "(Unknown Page)", - (long)ws_array[i]->biggest_row, (long)ws_array[i]->biggest_col); - } - - output_footer(); - } - else + f_cnt[i].name = (uni_string *) malloc (sizeof (uni_string)); + if (f_cnt[i].name) + { + f_cnt[i].name->str = (U8 *) malloc (name->len + 1); + if (f_cnt[i].name->str) { - if( OutputXML ) - OutputTableXML(); - else - OutputTableHTML(); + memcpy (f_cnt[i].name->str, name->str, name->len); + f_cnt[i].name->str[name->len] = 0; + f_cnt[i].name->uni = name->uni; + f_cnt[i].name->len = name->len; + f_cnt[i].cnt = 1; + break; } + } } + } } - - -void SetupExtraction(void) +int +get_default_font (void) { - if (Xtract) - { /* Revise the page settings... */ -/* printf("-%d %d %d %d %d
\n", xp, xr1, xr2, xc1, xc2); */ - if ((xp >= first_sheet)&&(xp <= last_sheet)&&(xp <= sheet_count)) - { - first_sheet = xp; - last_sheet = xp; - if (xr1 < 0) - { - xr1 = (S16)ws_array[xp]->first_row; - xr2 = (S16)ws_array[xp]->biggest_row; - } - else if ((xr1 >= ws_array[xp]->first_row)&&(xr1 <= ws_array[xp]->biggest_row) - &&(xr2 >= ws_array[xp]->first_row)&&(xr2 <= ws_array[xp]->biggest_row)) - { - ws_array[xp]->first_row = xr1; - ws_array[xp]->biggest_row = xr2; - } - else - { - if (Ascii) - fprintf(stderr, "Error - Row not in range during extraction" - " (%d or %d not in [%ld..%ld])\n", xr1, xr2, (long)ws_array[xp]->first_row, (long)ws_array[xp]->biggest_row); - else - { - printf("Error - Row not in range during extraction."); - output_footer(); - } - return; - } + int i, m = -1; - if (xc1 < 0) - { - xc1 = ws_array[xp]->first_col; - xc2 = ws_array[xp]->biggest_col; - } - else if((xc1 >= ws_array[xp]->first_col)&&(xc1 <= ws_array[xp]->biggest_col) - &&(xc2 >= ws_array[xp]->first_col)&&(xc2 <= ws_array[xp]->biggest_col)) - { - ws_array[xp]->first_col = xc1; - ws_array[xp]->biggest_col = xc2; - } - else - { - if (Ascii) - fprintf(stderr, "Error - Col not in range during extraction" - " (%d or %d not in [%d..%d])\n", xc1, xc2, ws_array[xp]->first_col, ws_array[xp]->biggest_col); - else - { - printf("Error - Col not in range during extraction.\n"); - output_footer(); - } - return; - } - } - else - { - if (Ascii) - fprintf(stderr, "Error - Page not in range during extraction."); - else - { - printf("Error - Page not in range during extraction."); - output_footer(); - } - return; - } + for (i = 0; i < FONTS_INCR; i++) + { + if (f_cnt[i].name) + { + if (f_cnt[i].name->str) + { + if (f_cnt[i].cnt > m) + m = i; + } } + } + return m; } +void +update_default_alignment (unsigned int sheet, int row) +{ + int i, left = 0, center = 0, right = 0; + cell *c; + + if ((sheet >= max_worksheets) || (ws_array[sheet] == 0)) + return; + if (ws_array[sheet]->c_array == 0) + return; + + for (i = ws_array[sheet]->first_col; i <= ws_array[sheet]->biggest_col; i++) + { /* This stuff happens for each cell... */ + c = ws_array[sheet]->c_array[(row * ws_array[sheet]->max_cols) + i]; + if (c) + { + int numeric = IsCellNumeric (c); + if (c->xfmt == 0) + { /* Unknown format... */ + left++; + } + else + { /* Biff 8 stuff... */ + if ((c->xfmt < next_xf) && (c->ustr.str)) + { + if (strcmp ((char *) c->ustr.str, " ")) + { + if (xf_array[c->xfmt]) + { + switch (xf_array[c->xfmt]->align & 0x0007) + { /* Override default table alignment when needed */ + case 2: + case 6: /* Center across selection */ + center++; + break; + case 0: /* General alignment */ + if (numeric) /* Numbers */ + right++; + else if ((c->type & 0x00FF) == 0x05) /* Boolean */ + center++; + else + left++; + break; + case 3: + right++; + break; + case 1: /* fall through... */ + default: + left++; + break; + } + } + } + } + } + } + } + if ((center == 0) && (left == 0) && (right == 0)) + default_alignment = ""; + else if ((center >= left) && (center >= right)) /* Favor center since it's the longest word */ + default_alignment = "center"; + else if ((right >= center) && (right >= left)) + default_alignment = "right"; /* Favor right since it's second longest */ + else + default_alignment = "left"; +} + + +void +OutputString (uni_string * u) +{ + unsigned int i; + + if (u == 0) + return; + + if (u->uni < 2) + { + if (null_string (u->str)) + { + if (Ascii == 0) + printf (OutputXML ? "" : " "); + else if (!Csv) + printf (" "); + } + else + { + if (Ascii) /* If Ascii output requested, simply output the string */ + { /* These are broken up for performance */ + if (Csv) + { + for (i = 0; i < u->len; i++) + { + if (u->str[i] == 0x22) + printf ("\"\""); + else + putchar (u->str[i]); + } + } + else + { + for (i = 0; i < u->len; i++) + putchar (u->str[i]); + } + return; + } + if (u->crun_cnt) + { + U16 loc, fnt_idx, crun_cnt = 0; + int format_changed = 0; + html_attr h_flags; + + /* read the first format run */ + update_crun_info (&loc, &fnt_idx, crun_cnt, u->fmt_run); + html_flag_init (&h_flags); + for (i = 0; i < u->len; i++) + { + if (i == loc) + { /* Time to change formats */ + if (format_changed) + { /* if old attributs, close */ + output_end_html_attr (&h_flags); + } + else + { /* FIXME: Also need to consider that a font may already be set for + the cell, in which case a closing tag should be set. */ + format_changed = 1; + } + + /* set new attr */ + output_start_font_attribute (&h_flags, fnt_idx); + output_start_html_attr (&h_flags, fnt_idx, 1); + + /* get next fmt_run */ + if (crun_cnt < u->crun_cnt) + { + crun_cnt++; + update_crun_info (&loc, &fnt_idx, crun_cnt, + u->fmt_run); + } + } + OutputCharCorrected (u->str[i]); + } + if (format_changed) + { + output_end_html_attr (&h_flags); + } + } + else + { + for (i = 0; i < u->len; i++) + OutputCharCorrected (u->str[i]); + } + } + } + else + { + if (u->len == 0) + { + if (Ascii) + printf (" "); + else + printf (OutputXML ? "" : " "); + } + else + { + if (u->len == 2) + { + if (memcmp (u->str, "& ", 2) == 0) + printf ("…"); + else + { + for (i = 0; i < u->len; i += 2) + print_utf8 (getShort (&(u->str[i]))); + } + } + else + { + for (i = 0; i < u->len; i += 2) + print_utf8 (getShort (&(u->str[i]))); + } + } + } +} + +void +OutputCharCorrected (U8 c) +{ + if (MultiByte && (c & 0x80)) + { + putchar (c); + return; + } + switch (c) + { /* Special char handlers here... */ + case 0x3C: /* '<' - less than */ + printf ("<"); + break; + case 0x3E: /* '>' - greater than */ + printf (">"); + break; + case 0x26: /* '&' - ampersand */ + printf ("&"); + break; + case 0x22: /* '"' - double quote */ + printf ("""); + break; + /* Also need to cover 128-159 since MS uses this area... */ + case 0x80: /* Euro Symbol */ + printf ("€"); + break; + case 0x82: /* baseline single quote */ + printf ("‚"); + break; + case 0x83: /* florin */ + printf ("ƒ"); + break; + case 0x84: /* baseline double quote */ + printf ("„"); + break; + case 0x85: /* ellipsis */ + printf ("…"); + break; + case 0x86: /* dagger */ + printf ("†"); + break; + case 0x87: /* double dagger */ + printf ("‡"); + break; + case 0x88: /* circumflex accent */ + printf ("ˆ"); + break; + case 0x89: /* permile */ + printf ("‰"); + break; + case 0x8A: /* S Hacek */ + printf ("Š"); + break; + case 0x8B: /* left single guillemet */ + printf ("‹"); + break; + case 0x8C: /* OE ligature */ + printf ("Œ"); + break; + case 0x8E: /* #LATIN CAPITAL LETTER Z WITH CARON */ + printf ("Ž"); + break; + case 0x91: /* left single quote ? */ + printf ("‘"); + break; + case 0x92: /* right single quote ? */ + printf ("’"); + break; + case 0x93: /* left double quote */ + printf ("“"); + break; + case 0x94: /* right double quote */ + printf ("”"); + break; + case 0x95: /* bullet */ + printf ("•"); + break; + case 0x96: /* endash */ + printf ("–"); + break; + case 0x97: /* emdash */ + printf ("—"); + break; + case 0x98: /* tilde accent */ + printf ("˜"); + break; + case 0x99: /* trademark ligature */ + printf ("™"); + break; + case 0x9A: /* s Hacek */ + printf ("š"); + break; + case 0x9B: /* right single guillemet */ + printf ("›"); + break; + case 0x9C: /* oe ligature */ + printf ("œ"); + break; + case 0x9F: /* Y Dieresis */ + printf ("Ÿ"); + break; + case 0xE1: /* a acute */ + printf ("á"); + break; + case 0xE9: /* e acute */ + printf ("é"); + break; + case 0xED: /* i acute */ + printf ("í"); + break; + case 0xF3: /* o acute */ + printf ("ó"); + break; + case 0xFA: /* u acute */ + printf ("ú"); + break; + case 0xFD: /* y acute */ + printf ("ý"); + break; + case 0xC1: /* A acute */ + printf ("Á"); + break; + case 0xC9: /* E acute */ + printf ("É"); + break; + case 0xCD: /* I acute */ + printf ("Í"); + break; + case 0xD3: /* O acute */ + printf ("Ó"); + break; + case 0xDA: /* U acute */ + printf ("Ú"); + break; + case 0xDD: /* Y acute */ + printf ("Ý"); + break; + case 0xB0: /* degrees */ + printf ("deg."); + break; + default: + putchar (c); + break; + } +} + +void +update_crun_info (U16 * loc, U16 * fmt_idx, U16 crun_cnt, U8 * fmt_run) +{ + U16 tloc, tfmt_idx; + U16 offset = (U16) (crun_cnt * 4); + + tloc = getShort (&fmt_run[offset]); + tfmt_idx = getShort (&fmt_run[offset + 2]); + *loc = tloc; + *fmt_idx = tfmt_idx; +} + +void +put_utf8 (U16 c) +{ + putchar ((int) 0x0080 | (c & 0x003F)); +} + +void +print_utf8 (U16 c) +{ + if (c < 0x80) + OutputCharCorrected (c); + else if (c < 0x800) + { + putchar (0xC0 | (c >> 6)); + put_utf8 (c); + } + else + { + putchar (0xE0 | (c >> 12)); + put_utf8 ((U16) (c >> 6)); + put_utf8 (c); + } +} + +void +uni_string_clear (uni_string * str) +{ + if (str == 0) + return; + + str->str = 0; + str->uni = 0; + str->len = 0; + str->fmt_run = 0; + str->crun_cnt = 0; +} + +int +uni_string_comp (uni_string * s1, uni_string * s2) +{ + if ((s1 == 0) || (s2 == 0)) + return -1; + if ((s1->str == 0) || (s2->str == 0)) + return -1; + + if ((s1->uni == s2->uni) && (s1->len == s2->len)) + return memcmp (s1->str, s2->str, s1->len); + else + return -1; +} + + + +void +html_flag_init (html_attr * h) +{ + h->fflag = 0; + h->bflag = 0; + h->iflag = 0; + h->sflag = 0; + h->uflag = 0; + h->sbflag = 0; + h->spflag = 0; +} + +void +output_start_font_attribute (html_attr * h, U16 fnt_idx) +{ + if (uni_string_comp (&default_font, &(font_array[fnt_idx]->name)) != 0) + { + h->fflag = 1; + printf ("name)); + printf ("\""); + } + if (font_array[fnt_idx]->c_idx != 0x7FFF) + { + char color[8]; + if (numCustomColors) + { + if ((font_array[fnt_idx]->c_idx < numCustomColors) && use_colors) + strcpy (color, + (char *) customColors[font_array[fnt_idx]->c_idx - 8]); + else + strcpy (color, "000000"); + } + else + { + if ((font_array[fnt_idx]->c_idx < MAX_COLORS) && use_colors) + strcpy (color, colorTab[font_array[fnt_idx]->c_idx]); + else + strcpy (color, "000000"); + } + if (strcmp (color, "000000") != 0) + { + if (h->fflag) + printf (" COLOR=\"%s\"", color); + else + { + h->fflag = 1; + printf ("super & 0x0003) + { + if (h->fflag) + printf (" SIZE=\"2\""); /* Sub & Superscript */ + else + { + h->fflag = 1; + printf ("fflag) + { + if (font_array[fnt_idx]->size != default_fontsize) + printf (" SIZE=\"%d\"", font_array[fnt_idx]->size); + } + else + { + if (font_array[fnt_idx]->size != default_fontsize) + { + h->fflag = 1; + printf ("size); + } + } + } + if (h->fflag) + printf (">"); +} /*! @@ -1810,2172 +3955,3 @@ void main_line_processor(U16 opcode, U16 version, U32 count, U16 last, U8 data) break; } } - - - -/*! returns 1 on error, 0 on success */ -int ws_init(int i) -{ - U32 j; - U16 k; - if (i >= (int)max_worksheets) - return 1; - - ws_array[i] = (work_sheet *)malloc(sizeof(work_sheet)); - if (ws_array[i]) - { - ws_array[i]->spanned = 0; - ws_array[i]->first_row = 0; - ws_array[i]->biggest_row = -1; - ws_array[i]->max_rows = ROWS_INCR; - ws_array[i]->first_col = 0; - ws_array[i]->biggest_col = -1; - ws_array[i]->max_cols = COLS_INCR; - uni_string_clear(&ws_array[i]->ws_title); - ws_array[i]->c_array = (cell **)malloc(ROWS_INCR*COLS_INCR*sizeof(cell *)); - if (ws_array[i]->c_array == 0) - return 1; - for (j=0; jc_array[(j*ws_array[i]->max_cols)+k] = 0; - } - else - return 1; - - return 0; -} - - - -/*! returns 1 on error, 0 on success */ -int add_more_worksheet_ptrs(void) -{ - work_sheet **tws_array; - int pages; - - if (MaxWorksheetsExceeded) - return 1; - - if (sheet_count > (int)max_worksheets) - pages = (((sheet_count - max_worksheets)/WORKSHEETS_INCR) + 1) * WORKSHEETS_INCR; - else - pages = WORKSHEETS_INCR; - tws_array = (work_sheet **)realloc(ws_array, - (max_worksheets + pages) * sizeof(work_sheet *)); - - if (tws_array == NULL) - { - MaxWorksheetsExceeded = 1; - return 1; - } - else - { /* Next init the array... */ - unsigned int i; - - ws_array = tws_array; - - for (i=max_worksheets; ic_array == 0) - return 1; - - tc_array = (cell **)malloc((ws->max_rows+new_rows)*(ws->max_cols+new_cols)*sizeof(cell *)); - - if (tc_array == NULL) - return 1; - else - { - U32 j; - U16 k; - - memset(tc_array, 0, (ws->max_rows+new_rows)*(ws->max_cols+new_cols)*sizeof(cell *)); - for (j=0; j<(ws->max_rows); j++) - { - for (k=0; kmax_cols; k++) - tc_array[(j*(ws->max_cols+new_cols))+k] = ws->c_array[(j*ws->max_cols)+k]; - } - ws->max_cols += new_cols; - ws->max_rows += new_rows; - free(ws->c_array); - ws->c_array = tc_array; - } - return 0; -} - - - -void add_wb_array(U16 r, U16 c, U16 xf, U16 type, U8 uni, - U8 *str, U16 len, U16 crun_cnt, U8 *fmt_run) -{ - work_sheet *ws; - - if ((sheet_count < 0)||(r > HARD_MAX_ROWS)||(c > HARD_MAX_COLS)) - return; - if (sheet_count >= (int)max_worksheets) - { - if (add_more_worksheet_ptrs()) - return; - } - if (ws_array[sheet_count] == 0) - { - if (ws_init(sheet_count)) - return; - } - ws = ws_array[sheet_count]; - if (r >= ws->max_rows) - { - if (MaxRowExceeded) - return; - else - { - int diff = ((r-ws->max_rows)/ROWS_INCR)+1; - if(resize_c_array(ws, ROWS_INCR*diff, 0)) - { - MaxRowExceeded = 1; - return; - } - } - } - if (c >= ws->max_cols) - { - if (MaxColExceeded) - return; - else - { - U16 diff = (U16)(((c-ws->max_cols)/COLS_INCR)+1); - if(resize_c_array(ws, 0, (U16)(COLS_INCR*diff))) - { - MaxColExceeded = 1; - return; - } - } - } - if (ws->c_array[(r*ws->max_cols)+c] == 0) - { - if (r > ws_array[sheet_count]->biggest_row) - ws_array[sheet_count]->biggest_row = r; - if (c > ws_array[sheet_count]->biggest_col) - ws_array[sheet_count]->biggest_col = c; - ws->c_array[(r*ws->max_cols)+c] = (cell *)malloc(sizeof(cell)); - if (ws->c_array[(r*ws->max_cols)+c]) - { - if (str) - { - ws->c_array[(r*ws->max_cols)+c]->ustr.str = (U8 *)malloc(len+1); - if (ws->c_array[(r*ws->max_cols)+c]->ustr.str) - { - memcpy(ws->c_array[(r*ws->max_cols)+c]->ustr.str, str, len); - ws->c_array[(r*ws->max_cols)+c]->ustr.str[len] = 0; - } - ws->c_array[(r*ws->max_cols)+c]->ustr.uni = uni; - ws->c_array[(r*ws->max_cols)+c]->ustr.len = len; - if (fmt_run && crun_cnt) - { - int rlen = crun_cnt*4; - - ws->c_array[(r*ws->max_cols)+c]->ustr.fmt_run = malloc(rlen); - if (ws->c_array[(r*ws->max_cols)+c]->ustr.fmt_run) - { - memcpy(ws->c_array[(r*ws->max_cols)+c]->ustr.fmt_run, fmt_run, rlen); - ws->c_array[(r*ws->max_cols)+c]->ustr.crun_cnt = crun_cnt; - } - else - ws->c_array[(r*ws->max_cols)+c]->ustr.crun_cnt = 0; - } - else - { - ws->c_array[(r*ws->max_cols)+c]->ustr.fmt_run = 0; - ws->c_array[(r*ws->max_cols)+c]->ustr.crun_cnt = 0; - } - } - else - uni_string_clear(&ws->c_array[(r*ws->max_cols)+c]->ustr); - - ws->c_array[(r*ws->max_cols)+c]->xfmt = xf; - ws->c_array[(r*ws->max_cols)+c]->type = type; - ws->c_array[(r*ws->max_cols)+c]->spanned = 0; - ws->c_array[(r*ws->max_cols)+c]->rowspan = 0; - ws->c_array[(r*ws->max_cols)+c]->colspan = 0; - uni_string_clear(&ws->c_array[(r*ws->max_cols)+c]->h_link); - } - } - else /* Default attributes already copied */ - { - if (r > ws_array[sheet_count]->biggest_row) - ws_array[sheet_count]->biggest_row = r; - if (c > ws_array[sheet_count]->biggest_col) - ws_array[sheet_count]->biggest_col = c; - if (str) - { /* Check if a place holder is there and free it */ - if (ws->c_array[(r*ws->max_cols)+c]->ustr.str != 0) - free(ws->c_array[(r*ws->max_cols)+c]->ustr.str); - - ws->c_array[(r*ws->max_cols)+c]->ustr.str = (U8 *)malloc(len+1); - if (ws->c_array[(r*ws->max_cols)+c]->ustr.str) - { - memcpy(ws->c_array[(r*ws->max_cols)+c]->ustr.str, str, len); - ws->c_array[(r*ws->max_cols)+c]->ustr.str[len] = 0; - } - ws->c_array[(r*ws->max_cols)+c]->ustr.len = len; - ws->c_array[(r*ws->max_cols)+c]->ustr.uni = uni; - if (fmt_run && crun_cnt) - { - int rlen = crun_cnt*4; - - ws->c_array[(r*ws->max_cols)+c]->ustr.fmt_run = malloc(rlen); - if (ws->c_array[(r*ws->max_cols)+c]->ustr.fmt_run) - { - memcpy(ws->c_array[(r*ws->max_cols)+c]->ustr.fmt_run, fmt_run, rlen); - ws->c_array[(r*ws->max_cols)+c]->ustr.crun_cnt = crun_cnt; - } - else - ws->c_array[(r*ws->max_cols)+c]->ustr.crun_cnt = 0; - } - else - { - ws->c_array[(r*ws->max_cols)+c]->ustr.fmt_run = 0; - ws->c_array[(r*ws->max_cols)+c]->ustr.crun_cnt = 0; - } - } - else - { - if (ws->c_array[(r*ws->max_cols)+c]->ustr.str == 0) - { - ws->c_array[(r*ws->max_cols)+c]->ustr.len = 0; - ws->c_array[(r*ws->max_cols)+c]->ustr.uni = 0; - ws->c_array[(r*ws->max_cols)+c]->ustr.fmt_run = 0; - ws->c_array[(r*ws->max_cols)+c]->ustr.crun_cnt = 0; - } - } - ws->c_array[(r*ws->max_cols)+c]->xfmt = xf; - ws->c_array[(r*ws->max_cols)+c]->type = type; - ws->c_array[(r*ws->max_cols)+c]->spanned = 0; - ws->c_array[(r*ws->max_cols)+c]->rowspan = 0; - ws->c_array[(r*ws->max_cols)+c]->colspan = 0; - } -} - -void update_cell_xf(U16 r, U16 c, U16 xf) -{ - work_sheet *ws; - - if ((sheet_count < 0)||(r > HARD_MAX_ROWS)||(c > HARD_MAX_COLS)) - return; - if (sheet_count >= (int)max_worksheets) - { - if (add_more_worksheet_ptrs()) - return; - } - if (ws_array[sheet_count] == 0) - { - if (ws_init(sheet_count)) - return; - } - if (r >= ws_array[sheet_count]->max_rows) - { - if (MaxRowExceeded) - return; - else - { - int diff = ((r-ws_array[sheet_count]->max_rows)/ROWS_INCR)+1; - if(resize_c_array(ws_array[sheet_count], ROWS_INCR*diff, 0)) - { - MaxRowExceeded = 1; - return; - } - } - } - if (c >= ws_array[sheet_count]->max_cols) - { - if (MaxColExceeded) - return; - else - { - int diff = ((c-ws_array[sheet_count]->max_cols)/COLS_INCR)+1; - if (resize_c_array(ws_array[sheet_count], 0, (U16)(COLS_INCR*diff))) - { - MaxColExceeded = 1; - return; - } - } - } - - ws = ws_array[sheet_count]; - if (ws->c_array[(r*ws->max_cols)+c] == 0) - { - ws->c_array[(r*ws->max_cols)+c] = (cell *)malloc(sizeof(cell)); - if (ws->c_array[(r*ws->max_cols)+c]) - { - uni_string_clear(&ws->c_array[(r*ws->max_cols)+c]->ustr); - ws->c_array[(r*ws->max_cols)+c]->xfmt = xf; - ws->c_array[(r*ws->max_cols)+c]->type = 1; /* This is the Blank Cell type */ - - if (r > ws_array[sheet_count]->biggest_row) - ws_array[sheet_count]->biggest_row = r; - if (c > ws_array[sheet_count]->biggest_col) - ws_array[sheet_count]->biggest_col = c; - ws->c_array[(r*ws->max_cols)+c]->spanned = 0; - ws->c_array[(r*ws->max_cols)+c]->rowspan = 0; - ws->c_array[(r*ws->max_cols)+c]->colspan = 0; - uni_string_clear(&ws->c_array[(r*ws->max_cols)+c]->h_link); - } - } -/* else - { - printf("R:%02X C:%02X XF:%02X is:%02X\n", - r, c, xf, ws->c_array[r][c]->xfmt); - } */ -} - -void update_cell_hyperlink(U16 r, U16 c, U8 *hyperlink, int len, U16 uni) -{ - work_sheet *ws; - - if (sheet_count < 0) /* Used to do a "0 <" check on r & c */ - return; - if (sheet_count >= (int)max_worksheets) - { - if (add_more_worksheet_ptrs()) - return; - } - if (ws_array[sheet_count] == 0) - { - if (ws_init(sheet_count)) - return; - } - if (r >= ws_array[sheet_count]->max_rows) - { - if (MaxRowExceeded) - return; - else - { - int diff = ((r-ws_array[sheet_count]->max_rows)/ROWS_INCR)+1; - if(resize_c_array(ws_array[sheet_count], ROWS_INCR*diff, 0)) - { - MaxRowExceeded = 1; - return; - } - } - } - if (c >= ws_array[sheet_count]->max_cols) - { - if (MaxColExceeded) - return; - else - { - int diff = ((c-ws_array[sheet_count]->max_cols)/COLS_INCR)+1; - if(resize_c_array(ws_array[sheet_count], 0, (U16)(COLS_INCR*diff))) - { - MaxColExceeded = 1; - return; - } - } - } - - ws = ws_array[sheet_count]; - if (ws->c_array[(r*ws->max_cols)+c] == 0) - { /* should not get here, but just in case */ - return; - } - if (ws->c_array[(r*ws->max_cols)+c]->h_link.str == 0) - { - ws->c_array[(r*ws->max_cols)+c]->h_link.str = (U8 *)malloc(len); - if (ws->c_array[(r*ws->max_cols)+c]->h_link.str) - memcpy(ws->c_array[(r*ws->max_cols)+c]->h_link.str, hyperlink, len); - ws->c_array[(r*ws->max_cols)+c]->h_link.uni = uni; - if (len) - { - if (uni < 2) - ws->c_array[(r*ws->max_cols)+c]->h_link.len = (U16)(len-1); - else - ws->c_array[(r*ws->max_cols)+c]->h_link.len = (U16)(len-2); - } - } -/* else - { - printf("R:%02X C:%02X XF:%02X is:%s\n", - r, c, xf, ws->c_array[r][c]->h_link.str); - } */ -} - -void add_str_array(U8 uni, U8 *str, U16 len, U8 *fmt_run, U8 crun_cnt) -{ - - if ((str == 0)||(len == 0)) - { - next_string++; /* increment for empty strings, too */ - return; - } - if (next_string >= max_strings) - { - uni_string **tstr_array; - unsigned long new_max_str; - size_t new_size; - - new_max_str = max_strings + STRINGS_INCR; - while (next_string >= new_max_str) - { /* who knows how many empty strings (see above) we got in a row - * - better make sure there's enough space allocated - */ - new_max_str += STRINGS_INCR; - } - - new_size = new_max_str * sizeof(uni_string *); - tstr_array = (uni_string **)realloc(str_array, new_size); - - if (tstr_array == NULL) - { - MaxStringsExceeded = 1; -/* fprintf(stderr, "%s: cannot allocate %d bytes for string storage %d: %s", - PRGNAME, new_size, errno, strerror(errno)); */ - return; - } - else - { - unsigned long i; - - str_array = tstr_array; - - /* Clear the new string slots */ - for (i = max_strings; i < new_max_str; i++) - str_array[i] = 0; - - max_strings = new_max_str; - } - } - - if (str_array[next_string] == 0) - { /* Can this ever be false? If yes, wouldn't that be a bug? -- VDv */ - str_array[next_string] = (uni_string *)malloc(sizeof(uni_string)); - if (str_array[next_string]) - { - str_array[next_string]->str = (U8 *)malloc(len+1); - if (str_array[next_string]->str) - { - memcpy(str_array[next_string]->str, str, len); - str_array[next_string]->str[len] = 0; - str_array[next_string]->len = len; - str_array[next_string]->uni = uni; - if (fmt_run && crun_cnt) - { - int rlen = crun_cnt*4; - - str_array[next_string]->fmt_run = malloc(rlen); - if (str_array[next_string]->fmt_run) - { - memcpy(str_array[next_string]->fmt_run, fmt_run, rlen); - str_array[next_string]->crun_cnt = crun_cnt; - } - else - { - str_array[next_string]->crun_cnt = 0; - MaxStringsExceeded = 1; - } - } - else - { - str_array[next_string]->fmt_run = 0; - str_array[next_string]->crun_cnt = 0; - } - } - else - { - MaxStringsExceeded = 1; -/* fprintf(stderr, "%s: cannot allocate %d bytes for string storage %d: %s", - PRGNAME, len+1, errno, strerror(errno)); */ - } - } - else - { - MaxStringsExceeded = 1; -/* fprintf(stderr, "%s: cannot allocate %d bytes for string storage %d: %s", - PRGNAME, sizeof(uni_string), errno, strerror(errno)); */ - } - } - next_string++; -} - -void add_font(U16 size, U16 attr, U16 c_idx, U16 bold, U16 super, U8 underline, - U16 uni, U8 *n, U16 len) -{ - if (n == 0) - return; - if (next_font >= max_fonts) - { - font_attr **tfont_array; - fnt_cnt *tf_cnt; - tfont_array = (font_attr **)realloc(font_array, (max_fonts * FONTS_INCR) * sizeof(font_attr *)); - tf_cnt = (fnt_cnt *)realloc(f_cnt, (max_fonts * FONTS_INCR) * sizeof(fnt_cnt)); - - if ((tf_cnt == NULL) || (tfont_array == NULL)) - { - MaxFontsExceeded = 1; - return; - } - else - { /* Next init the array... */ - unsigned int i; - - font_array = tfont_array; - f_cnt = tf_cnt; - - for (i=max_fonts; iname.str = (U8 *)malloc(len+1); - if (font_array[next_font]->name.str) - { - font_array[next_font]->attr = attr; - font_array[next_font]->c_idx = c_idx; - font_array[next_font]->bold = bold; - font_array[next_font]->super = super; - font_array[next_font]->underline = underline; - font_array[next_font]->name.uni = uni; - memcpy(font_array[next_font]->name.str, n, len); - font_array[next_font]->name.str[len] = 0; - font_array[next_font]->name.len = len; - font_array[next_font]->name.fmt_run = 0; - font_array[next_font]->name.crun_cnt = 0; - - /* We will "pre-digest" the font size.. */ - if (size >= 0x02D0) /* 36 pts */ - font_array[next_font]->size = 7; - else if (size >= 0x01E0) /* 24 pts */ - font_array[next_font]->size = 6; - else if (size >= 0x0168) /* 18 pts */ - font_array[next_font]->size = 5; - else if (size >= 0x00F0) /* 12 pts */ - font_array[next_font]->size = 4; - else if (size >= 0x00C8) /* 10 pts */ - font_array[next_font]->size = 3; - else if (size >= 0x00A0) /* 8 pts */ - font_array[next_font]->size = 2; - else - font_array[next_font]->size = 1; - } - } - } - next_font++; - if (next_font == 4) /* Per the doc's - number 4 doesn't exist. */ - next_font++; -} - -void add_ws_title(U16 uni, U8 *n, U16 len) -{ - if (n == 0) - return; - - if (next_ws_title >= max_worksheets) - { - if (add_more_worksheet_ptrs()) - return; - } - - if (ws_array[next_ws_title] == 0) - { - if (ws_init(next_ws_title)) - return; - } - if (ws_array[next_ws_title]->ws_title.str == 0) - { - ws_array[next_ws_title]->ws_title.str = (U8 *)malloc(len+1); - if (ws_array[next_ws_title]->ws_title.str) - { - ws_array[next_ws_title]->ws_title.uni = uni; - memcpy(ws_array[next_ws_title]->ws_title.str, n, len); - ws_array[next_ws_title]->ws_title.str[len] = 0; - ws_array[next_ws_title]->ws_title.len = len; - ws_array[next_ws_title]->ws_title.crun_cnt = 0; - ws_array[next_ws_title]->ws_title.fmt_run = 0; - } - } - next_ws_title++; -} - -void add_xf_array(U16 fnt_idx, U16 fmt_idx, U16 gen, U16 align, - U16 indent, U16 b_style, U16 b_l_color, U32 b_t_color, U16 cell_color) -{ - if (next_xf >= max_xformats) - { - xf_attr **txf_array; - - txf_array = (xf_attr **)realloc(xf_array, (max_xformats + XFORMATS_INCR) * sizeof(xf_attr *)); - if (txf_array == NULL) - { - MaxXFExceeded = 1; - return; - } - else - { - unsigned int i; - - xf_array = txf_array; - - for (i=max_xformats; i<(max_xformats + XFORMATS_INCR); i++) - xf_array[i] = 0; - - max_xformats += XFORMATS_INCR; - } - } - - if (xf_array[next_xf] == 0) - { - xf_array[next_xf] = (xf_attr *)malloc(sizeof(xf_attr)); - if (xf_array[next_xf]) - { - xf_array[next_xf]->fnt_idx = fnt_idx; - xf_array[next_xf]->fmt_idx = fmt_idx; - xf_array[next_xf]->gen = gen; - xf_array[next_xf]->align = align; - xf_array[next_xf]->indent = indent; - xf_array[next_xf]->b_style = b_style; - xf_array[next_xf]->b_l_color = b_l_color; - xf_array[next_xf]->b_t_color = b_t_color; - xf_array[next_xf]->cell_color = cell_color; - } - next_xf++; - } -} - -void decodeBoolErr(U16 value, U16 flag, char *str) -{ - if (str == 0) - return; - - if (flag == 0) - { - if (value == 1) - strcpy(str, "TRUE"); - else - strcpy(str, "FALSE"); - } - else - { - switch(value) - { - case 0x00: - strcpy(str, "#NULL!"); - break; - case 0x07: - strcpy(str, "#DIV/0!"); - break; - case 0x0F: - strcpy(str, "#VALUE!"); - break; - case 0x17: - strcpy(str, "#REF!"); - break; - case 0x1D: - strcpy(str, "#NAME?"); - break; - case 0x24: - strcpy(str, "#NUM!"); - break; - case 0x2A: - strcpy(str, "#N/A"); - break; - default: - strcpy(str, "#ERR"); - break; - } - } -} - -int IsCellNumeric(cell *c) -{ - int ret_val = 0; - - switch (c->type & 0x00FF) - { - case 0x02: /* Int */ - case 0x03: /* Float */ - /* case 0x06: */ /* Formula */ - /* case 0x08: */ - case 0x7E: /* RK */ - /* case 0xBC: */ - /* case 0x21: */ - case 0xBD: /* MulRK */ - ret_val = 1; - break; - default: - break; - } - return ret_val; -} - -/*! \retval 0 not safe at all. - \retval 1 extended format is OK - \retval 2 Fonts OK */ -int IsCellSafe(cell *c) -{ - int safe = 0; - - if (c->xfmt < next_xf) - { - if (xf_array[c->xfmt]) - { - safe = 1; - if (xf_array[c->xfmt]->fnt_idx < next_font) - { - if (font_array[xf_array[c->xfmt]->fnt_idx]) - safe = 2; - } - } - } - return safe; -} - -int IsCellFormula(cell *c) -{ - if ((c->type > 0x0100)||(c->type == 0x0006)) - return 1; - else - return 0; -} - -void output_cell(cell *c, int xml) -{ - html_attr h; - - if (c == NULL) - printf( xml ? ">" : " "); - else if (c->spanned != 0) - { - if (xml) - printf(">"); - return; - } - else - { /* Determine whether or not it is of numeric origin.. */ - int numeric = IsCellNumeric(c); /* 0=Text 1=Numeric */ - html_flag_init(&h); - if (c->xfmt == 0) - { /* Unknown format... */ - printf( xml ? ">" : ""); /* This section doesn't use Unicode */ - if (c->ustr.str) - OutputString(&(c->ustr)); - else - printf( xml ? "" : " "); - } - else - { /* This is the BIFF7 & 8 stuff... */ - int safe; - int nullString = 1; - - safe = IsCellSafe(c); - - if (c->ustr.str) - { - if (c->ustr.uni < 2) /* UNI? */ - nullString = null_string(c->ustr.str); - else - nullString = 0; - } - - /* First take care of text color & alignment */ - printf( xml ? "" : "rowspan != 0)||(c->colspan != 0)) - { - if (c->colspan) - printf( xml ? " colspan=\"%d\"" : " COLSPAN=\"%d\"", c->colspan); - if (c->rowspan) - printf( xml ? " rowspan=\"%d\"" : " ROWSPAN=\"%d\"", c->rowspan); - } - if ((safe > 0)&&(!nullString)) - { - switch(xf_array[c->xfmt]->align & 0x0007) - { /* Override default table alignment when needed */ - case 2: - case 6: /* Center across selection */ - if (strcmp(default_alignment, "center") != 0) - printf( xml ? "" : " ALIGN=\"center\""); - break; - case 0: /* General alignment */ - if (numeric) /* Numbers */ - { - if (strcmp(default_alignment, "right") != 0) - printf( xml ? "" : " ALIGN=\"right\""); - } - else if ((c->type & 0x00FF) == 0x05) - { /* Boolean */ - if (strcmp(default_alignment, "center") != 0) - printf( xml ? "" : " ALIGN=\"center\""); - } - else - { - if (strcmp(default_alignment, "left") != 0) - printf( xml ? "" : " ALIGN=\"left\""); - } - break; - case 3: - if (strcmp(default_alignment, "right") != 0) - printf( xml ? "" : " ALIGN=\"right\""); - break; - case 1: - default: - if (strcmp(default_alignment, "left") != 0) - printf( xml ? "" : " ALIGN=\"left\""); - break; - } - switch((xf_array[c->xfmt]->align & 0x0070)>>4) - { - case 0: - printf( xml ? "" : " VALIGN=\"top\""); - break; - case 1: - printf( xml ? "" : " VALIGN=\"middle\""); - break; - case 2: /* General alignment */ - if (safe > 1) - { - if ((font_array[xf_array[c->xfmt]->fnt_idx]->super & 0x0003) == 0x0001) - printf( xml ? "" : " VALIGN=\"top\""); /* Superscript */ - } - break; - default: - if (safe > 1) - { - if ((font_array[xf_array[c->xfmt]->fnt_idx]->super & 0x0003) == 0x0001) - printf( xml ? "" : " VALIGN=\"top\""); /* Superscript */ - } - break; - } - } - /* Next do the bgcolor... BGCOLOR="" */ - if (safe && use_colors) - { - int fgcolor; - /* int bgcolor = (xf_array[c->xfmt]->cell_color & 0x3F80) >> 7; */ - fgcolor = (xf_array[c->xfmt]->cell_color & 0x007F); - /* printf(" XF:%X BG Color:%d, FG Color:%d", c->xfmt, bgcolor, fgcolor); */ - - /* Might be better by blending bg & fg colors? - If valid, fgcolor != black and fgcolor != white */ - if( ! xml ) - { - if (numCustomColors) - { - if (fgcolor < numCustomColors) - { - if (strcmp(default_background_color, (char *)customColors[fgcolor-8]) != 0) - printf(" BGCOLOR=\"%s\"", customColors[fgcolor-8]); - } - } - else - { - if (fgcolor < MAX_COLORS) - { - if (strcmp(default_background_color, colorTab[fgcolor]) != 0) - printf(" BGCOLOR=\"%s\"", colorTab[fgcolor]); - } - } - } - } - - /* Next set the border color... */ - if (safe && use_colors) - { - int lcolor, rcolor, tcolor, bcolor; - lcolor = xf_array[c->xfmt]->b_l_color & 0x007F; - rcolor = (xf_array[c->xfmt]->b_l_color & 0x3F80) >> 7; - tcolor = xf_array[c->xfmt]->b_t_color & 0x007F; - bcolor = (xf_array[c->xfmt]->b_t_color & 0x3F80) >> 7; - if (((lcolor & rcolor & tcolor & bcolor) == lcolor)&&(lcolor < MAX_COLORS)) - { /* if they are all the same...do it...that is if it's different from BLACK */ - if (numCustomColors == 0) /* Don't do custom borders */ - { - if ((strcmp(colorTab[lcolor], "000000") != 0)&&(strcmp(colorTab[lcolor], "FFFFFF") != 0)) - { - if( !xml ) - printf(" BORDERCOLOR=\"%s\"", colorTab[lcolor]); - } - } - } - } - - /* Close up the or ... */ - printf(">"); - - /* Next set font properties */ - if (safe > 1 && !xml ) - { - if (!nullString) - output_start_font_attribute(&h, xf_array[c->xfmt]->fnt_idx); - } - - /* Finally, take care of font modifications */ - if ((safe > 1)&&(!nullString)) - { - if ((font_array[xf_array[c->xfmt]->fnt_idx]->underline&0x0023) > 0) - { - if (c->h_link.str) - { - printf("
h_link.uni) - { - if (memchr((char *)c->h_link.str, ':', c->h_link.len) == 0) - { - if (memchr((char *)c->h_link.str, '@', c->h_link.len)) - printf("mailto:"); - } - } - OutputString(&(c->h_link)); - printf("\">"); - h.uflag = 2; - } - else - { - printf(""); - h.uflag = 1; - } - } - output_start_html_attr(&h, xf_array[c->xfmt]->fnt_idx, 0); - } - if (c->ustr.str) - { - if (safe) - output_formatted_data(&(c->ustr), xf_array[c->xfmt]->fmt_idx, numeric, IsCellFormula(c)); - else - OutputString(&(c->ustr)); - } - else - printf( xml ? "" : " "); -/* printf(" T:%02X", c->type & 0x00FF); */ - } - - /* Now close the tags... */ - output_end_html_attr(&h); - } - - if (!aggressive) - printf( xml ? "" : "\n"); -} - -void output_formatted_data(uni_string *u, U16 idx, int numeric, int formula) -{ - if ((idx < max_xformats)&&(u->str)) - { - if ((formula_warnings)&&(formula)) - { - if( OutputXML ) - printf( "" ); - else - printf("** "); - notAccurate++; - } - if (numeric) - { - int year, month, date; - long num; - F64 dnum; - int hr, minu, sec, msec; - -/* printf("idx:%d ", idx); */ - switch (idx) - { - case 0x00: /* General */ - dnum = atof((char *)u->str); - printf("%.15g", dnum); - break; - case 0x01: /* Number 0 */ - dnum = atof((char *)u->str); - printf("%.0f", dnum); - break; - case 0x02: /* Number 0.00 */ - dnum = atof((char *)u->str); - printf("%.2f", dnum); - break; - case 0x03: /* Number w/comma 0,000 */ - PrintFloatComma("%.0f", 0, (F64)atof((char *)u->str)); - break; - case 0x04: /* Number w/comma 0,000.00 */ - PrintFloatComma("%.2f", 0, (F64)atof((char *)u->str)); - break; - case 0x05: /* Currency, no decimal */ - PrintFloatComma("%.0f", 1, (F64)atof((char *)u->str)); - break; - case 0x06: /* Currency, no decimal Red on Neg */ - PrintFloatComma("%.0f", 1, (F64)atof((char *)u->str)); - break; - case 0x07: /* Currency with decimal */ - PrintFloatComma("%.2f", 1, (F64)atof((char *)u->str)); - break; - case 0x08: /* Currency with decimal Red on Neg */ - PrintFloatComma("%.2f", 1, (F64)atof((char *)u->str)); - break; - case 0x09: /* Percent 0% */ - if (Csv) - printf("\""); - dnum = 100.0*atof((char *)u->str); - printf("%.0f%%", dnum); - if (Csv) - printf("\""); - break; - case 0x0A: /* Percent 0.00% */ - if (Csv) - printf("\""); - dnum = 100.0*atof((char *)u->str); - printf("%.2f%%", dnum); - if (Csv) - printf("\""); - break; - case 0x0B: /* Scientific 0.00+E00 */ - if (Csv) - printf("\""); - dnum = atof((char *)u->str); - printf("%.2E", dnum); - if (Csv) - printf("\""); - break; - case 0x0C: /* Fraction 1 number e.g. 1/2, 1/3 */ - if (Csv) - printf("\""); - dnum = atof((char *)u->str); - print_as_fraction(dnum, 1); - if (Csv) - printf("\""); - break; - case 0x0D: /* Fraction 2 numbers e.g. 1/50, 25/33 */ - if (Csv) - printf("\""); - dnum = atof((char *)u->str); - print_as_fraction(dnum, 2); - if (Csv) - printf("\""); - break; - case 0x0E: /* Date: m-d-y */ - if (Csv) - printf("\""); - num = atol((char *)u->str); - NumToDate(num, &year, &month, &date); - printf("%d-%d-%02d", month, date, year); - if (Csv) - printf("\""); - break; - case 0x0F: /* Date: d-mmm-yy */ - if (Csv) - printf("\""); - num = atol((char *)u->str); - NumToDate(num, &year, &month, &date); - printf("%d-%s-%02d", date, month_abbr[month-1], year); - if (Csv) - printf("\""); - break; - case 0x10: /* Date: d-mmm */ - if (Csv) - printf("\""); - num = atol((char *)u->str); - NumToDate(num, &year, &month, &date); - printf("%d-%s", date, month_abbr[month-1]); - if (Csv) - printf("\""); - break; - case 0x11: /* Date: mmm-yy */ - if (Csv) - printf("\""); - num = atol((char *)u->str); - NumToDate(num, &year, &month, &date); - printf("%s-%02d", month_abbr[month-1], year); - if (Csv) - printf("\""); - break; - case 0x12: /* Time: h:mm AM/PM */ - if (Csv) - printf("\""); - FracToTime(u->str, &hr, &minu, 0, 0); - if (hr == 0) - printf("12:%02d AM", minu); - else if (hr < 12) - printf("%d:%02d AM", hr, minu); - else if (hr == 12) - printf("12:%02d PM", minu); - else - printf("%d:%02d PM", hr-12, minu); - if (Csv) - printf("\""); - break; - case 0x13: /* Time: h:mm:ss AM/PM */ - if (Csv) - printf("\""); - FracToTime(u->str, &hr, &minu, &sec, 0); - if (hr == 0) - printf("12:%02d:%02d AM", minu, sec); - else if (hr < 12) - printf("%d:%02d:%02d AM", hr, minu, sec); - else if (hr == 12) - printf("12:%02d:%02d PM", minu, sec); - else - printf("%d:%02d:%02d PM", hr-12, minu, sec); - if (Csv) - printf("\""); - break; - case 0x14: /* Time: h:mm */ - if (Csv) - printf("\""); - FracToTime(u->str, &hr, &minu, 0, 0); - printf("%d:%02d", hr, minu); - if (Csv) - printf("\""); - break; - case 0x15: /* Time: h:mm:ss */ - if (Csv) - printf("\""); - FracToTime(u->str, &hr, &minu, &sec, 0); - if ((hr != 0)||(minu != 0)||(sec != 0)) - printf("%d:%02d:%02d", hr, minu, sec); - else - { - if (Ascii) - putchar(' '); - else - printf(OutputXML ? "" : " "); - } - if (Csv) - printf("\""); - break; - case 0x25: /* Number with comma, no decimal */ - if (Csv) - printf("\""); - PrintFloatComma("%.0f", 0, (F64)atof((char *)u->str)); - if (Csv) - printf("\""); - break; - case 0x26: /* Number with comma, no decimal, red on negative */ - if (Csv) - printf("\""); - PrintFloatComma("%.0f", 0, (F64)atof((char *)u->str)); - if (Csv) - printf("\""); - break; - case 0x27: /* Number with comma & decimal */ - if (Csv) - printf("\""); - PrintFloatComma("%.2f", 0, (F64)atof((char *)u->str)); - if (Csv) - printf("\""); - break; - case 0x28: /* Number with comma & decimal, red on negative */ - if (Csv) - printf("\""); - PrintFloatComma("%.2f", 0, (F64)atof((char *)u->str)); - if (Csv) - printf("\""); - break; - case 0x29: /* Number with comma, no decimal */ - if (Csv) - printf("\""); - PrintFloatComma("%.2f", 0, (F64)atof((char *)u->str)); - if (Csv) - printf("\""); - break; - case 0x2a: /* Currency, no decimal */ - if (Csv) - printf("\""); - PrintFloatComma("%.0f", 1, (F64)atof((char *)u->str)); - if (Csv) - printf("\""); - break; - case 0x2B: /* Number w/comma & decimal 0,000.00 */ - if (Csv) - printf("\""); - PrintFloatComma("%.2f", 0, (F64)atof((char *)u->str)); - if (Csv) - printf("\""); - break; - case 0x2C: /* Accounting Currency $0,000.00 */ - { - F64 acc_val = atof((char *)u->str); - if (Csv) - printf("\""); - if (acc_val < 0.0) - PrintFloatComma(" (%.2f)", 1, fabs(acc_val)); - else - PrintFloatComma(" %.2f", 1, acc_val); - if (Csv) - printf("\""); - break; - } - case 0x2D: /* Time: mm:ss */ - if (Csv) - printf("\""); - FracToTime(u->str, &hr, &minu, &sec, 0); - printf("%02d:%02d", minu, sec); - if (Csv) - printf("\""); - break; - case 0x2E: /* Time: [h]:mm:ss */ - if (Csv) - printf("\""); - FracToTime(u->str, &hr, &minu, &sec, 0); - if (hr) - printf("%d:%02d:%02d", hr, minu, sec); - else - printf("%02d:%02d", minu, sec); - if (Csv) - printf("\""); - break; - case 0x2F: /* Time: mm:ss.0 */ - if (Csv) - printf("\""); - FracToTime(u->str, &hr, &minu, &sec, &msec); - printf("%02d:%02d.%01d", minu, sec, msec); - if (Csv) - printf("\""); - break; - case 0x31: /* Text - if we are here...it's a number */ - dnum = atof((char *)u->str); - printf("%g", dnum); - break; - default: /* Unsupported...but, if we are here, it's a number */ - { - char *ptr = strchr((char *)u->str, '.'); - if( OutputXML ) - printf( "" ); - dnum = atof((char *)u->str); - if (ptr) - { - if (Csv) - printf("\"%.15g\"", dnum ); - else if (OutputXML) - printf("%.15g", dnum ); - else - printf("%.15g *", dnum ); - } - else - { - num = atol((char *)u->str); - if (Csv) - printf("%ld", num); - else if (OutputXML) - printf("%ld", num ); - else - printf("%ld *", num ); - } - -/* printf(" F:%02X", idx); */ - NoFormat++ ; - } - break; - } - } - else /* Text data */ - OutputString(u); - } - else /* Error handling just dump it. */ - OutputString(u); -} - - - -void PrintFloatComma(char *fformat, int is_currency, F64 d) -{ - int len, int_len, dec_len; - char *ptr2, buf[64]; - - sprintf(buf, fformat, fabs(d)); - len = strlen(buf); - ptr2 = strchr(buf, '.'); - if (ptr2) - { - int_len = ptr2 - buf; - dec_len = len - int_len; - if (isdigit(buf[0]) == 0) - { - char *ptr = &buf[0]; - while (isdigit(*ptr) == 0) - { - int_len--; - ptr++; - if (*ptr == 0) - break; - } - } - } - else - { - int_len = len; - dec_len = 0; - } - - if (int_len > 3) - { /* we have to do it the hard way... */ - char rbuf[64], buf2[64]; - int neg, i, j, count=0; - - if (d < 0.0) - neg = 1; - else - neg = 0; - - /* reverse the string. It's easier to work this way. */ - for (i=0, j=len-1; i= 1.0) - { - int n = (int)w; - printf("%d ", n); - r = w - (F64)n; - } - else - r = w; - - /* Get closest fraction - brute force */ - for (j=lim; j>0.0; j--) - { - for (i=lim; i>=0.0; i--) - { - if ( fabs((i/j)-r) <= closest) - { - closest = fabs((i/j)-r); - ci = (int)i; - cj = (int)j; - } - } - } - - /* Done, print it... */ - if (ci != 0) - printf("%d/%d", ci, cj); -} - -void trim_sheet_edges(unsigned int sheet) -{ - cell *ce; - int not_done = 1; - S32 r; - U16 c; - - if ((sheet >= max_worksheets)||(ws_array[sheet] == 0)|| - (trim_edges == 0)||(ws_array[sheet]->spanned)) - return; - if (ws_array[sheet]->c_array == 0) - return; - if ( (ws_array[sheet]->biggest_row == -1) || - (ws_array[sheet]->biggest_col == -1) ) - return; - - /* First find top edge */ - for (r=ws_array[sheet]->first_row; r<=ws_array[sheet]->biggest_row; r++) - { - for (c=ws_array[sheet]->first_col; c<=ws_array[sheet]->biggest_col; c++) - { /* This stuff happens for each cell... */ - ce = ws_array[sheet]->c_array[(r*ws_array[sheet]->max_cols)+c]; - if (ce) - { - if (ce->ustr.str) - { - if (!null_string(ce->ustr.str)) - { - not_done = 0; - break; - } - } - } - } - if (!not_done) - break; - } - if (not_done) - ws_array[sheet]->first_row = ws_array[sheet]->biggest_row; - else - ws_array[sheet]->first_row = r; - - /* Second Find bottom edge */ - not_done = 1; - for (r=ws_array[sheet]->biggest_row; r>(S32)ws_array[sheet]->first_row; r--) - { - for (c=ws_array[sheet]->first_col; c<=ws_array[sheet]->biggest_col; c++) - { /* This stuff happens for each cell... */ - ce = ws_array[sheet]->c_array[(r*ws_array[sheet]->max_cols)+c]; - if (ce) - { - if (ce->ustr.str) - { - if (!null_string(ce->ustr.str)) - { - not_done = 0; - break; - } - } - } - } - if (!not_done) - break; - } - ws_array[sheet]->biggest_row = r; - - /* Third find left edge */ - not_done = 1; - for (c=ws_array[sheet]->first_col; c<=ws_array[sheet]->biggest_col; c++) - { - for (r=ws_array[sheet]->first_row; r<=ws_array[sheet]->biggest_row; r++) - { /* This stuff happens for each cell... */ - ce = ws_array[sheet]->c_array[(r*ws_array[sheet]->max_cols)+c]; - if (ce) - { - if (ce->ustr.str) - { - if (!null_string(ce->ustr.str)) - { - not_done = 0; - break; - } - } - } - } - if (!not_done) - break; - } - if (not_done) - ws_array[sheet]->first_col = ws_array[sheet]->biggest_col; - else - ws_array[sheet]->first_col = c; - - /* Last, find right edge */ - not_done = 1; - for (c=ws_array[sheet]->biggest_col; c>ws_array[sheet]->first_col; c--) - { - for (r=ws_array[sheet]->first_row; r<=ws_array[sheet]->biggest_row; r++) - { /* This stuff happens for each cell... */ - ce = ws_array[sheet]->c_array[(r*ws_array[sheet]->max_cols)+c]; - if (ce) - { - if (ce->ustr.str) - { - if (!null_string(ce->ustr.str)) - { - not_done = 0; - break; - } - } - } - } - if (!not_done) - break; - } - ws_array[sheet]->biggest_col = c; -} - -/*************** -*! Figures out the best font & alignment for the current table. -* Also sets the default_font and default_alignment. -****************/ -void update_default_font(unsigned int sheet) -{ - cell *ce; - int r, c, f; - - if ((sheet >= max_worksheets)||(ws_array[sheet] == 0)) - return; - if (ws_array[sheet]->c_array == 0) - return; - - /* Clear the book-keeping info... */ - for (r=0; rstr) - free(f_cnt[r].name->str); - free(f_cnt[r].name); - f_cnt[r].name = 0; - } - } - if (default_font.str) - free(default_font.str); - for (r=0; r<7; r++) - fnt_size_cnt[r] = 0; - - /* Now check each cell to see what it's using. */ - for (r=ws_array[sheet]->first_row; r<=ws_array[sheet]->biggest_row; r++) - { - for (c=ws_array[sheet]->first_col; c<=ws_array[sheet]->biggest_col; c++) - { /* This stuff happens for each cell... */ - ce = ws_array[sheet]->c_array[(r*ws_array[sheet]->max_cols)+c]; - if (ce) - { - if ((ce->xfmt < next_xf)&&(ce->ustr.str)) - { - if (strcmp((char *)ce->ustr.str, " ")) - { - if (ce->xfmt < next_xf) - { - if (xf_array[ce->xfmt]) - { - unsigned int fn = xf_array[ce->xfmt]->fnt_idx; - if (fn < next_font) - { - if (font_array[fn]) - { - if (font_array[fn]->name.str) - { - /* Here's where we check & increment count... */ - incr_f_cnt(&(font_array[fn]->name)); - if ((font_array[fn]->size < 8)&&(font_array[fn]->size)) - fnt_size_cnt[font_array[fn]->size-1]++; - } - } - } - } - } - } - } - } - } - } - - f = get_default_font(); - if (f == -1) - { - default_font.str = (U8 *)malloc(6); - if (default_font.str) - { - strcpy((char *)default_font.str, "Arial"); - default_font.uni = 0; - default_font.len = 5; - } - } - else - { - default_font.str = (U8 *)malloc(f_cnt[f].name->len+1); - if (default_font.str) - { - memcpy(default_font.str, f_cnt[f].name->str, f_cnt[f].name->len); - default_font.str[f_cnt[f].name->len] = 0; - default_font.uni = f_cnt[f].name->uni; - default_font.len = f_cnt[f].name->len; - } - } - - /* Find the font size with the most counts... - Just re-using variables, c - max cnt, f = position of max cnt */ - c = 0; - f = 3; - for (r=0; r<7; r++) - { - if (fnt_size_cnt[r] > c) - { - c = fnt_size_cnt[r]; - f = r; - } - } - if (fnt_size_cnt[2] == c) /* favor size 3... */ - default_fontsize = 3; - else - default_fontsize = f+1; - - for (r=0; rstr != 0) - free(f_cnt[r].name->str); - free(f_cnt[r].name); - f_cnt[r].name= 0; - } - } -} - -void incr_f_cnt(uni_string *name) -{ - int i; - - if ((name == 0)||(name->str == 0)||(name->str[0] == 0)) - return; - - for (i=0; istr = (U8 *)malloc(name->len+1); - if (f_cnt[i].name->str) - { - memcpy(f_cnt[i].name->str, name->str, name->len); - f_cnt[i].name->str[name->len] = 0; - f_cnt[i].name->uni = name->uni; - f_cnt[i].name->len = name->len; - f_cnt[i].cnt = 1; - break; - } - } - } - } -} - -int get_default_font(void) -{ - int i, m = -1; - - for (i=0; istr) - { - if (f_cnt[i].cnt > m) - m = i; - } - } - } - return m; -} - -void update_default_alignment(unsigned int sheet, int row) -{ - int i, left = 0, center = 0, right = 0; - cell *c; - - if ((sheet >= max_worksheets)||(ws_array[sheet] == 0)) - return; - if (ws_array[sheet]->c_array == 0) - return; - - for (i=ws_array[sheet]->first_col; i<=ws_array[sheet]->biggest_col; i++) - { /* This stuff happens for each cell... */ - c = ws_array[sheet]->c_array[(row*ws_array[sheet]->max_cols)+i]; - if (c) - { - int numeric = IsCellNumeric(c); - if (c->xfmt == 0) - { /* Unknown format... */ - left++; - } - else - { /* Biff 8 stuff... */ - if ((c->xfmt < next_xf)&&(c->ustr.str)) - { - if (strcmp((char *)c->ustr.str, " ")) - { - if (xf_array[c->xfmt]) - { - switch(xf_array[c->xfmt]->align & 0x0007) - { /* Override default table alignment when needed */ - case 2: - case 6: /* Center across selection */ - center++; - break; - case 0: /* General alignment */ - if (numeric) /* Numbers */ - right++; - else if ((c->type & 0x00FF) == 0x05) /* Boolean */ - center++; - else - left++; - break; - case 3: - right++; - break; - case 1: /* fall through... */ - default: - left++; - break; - } - } - } - } - } - } - } - if ((center == 0)&&(left == 0)&&(right == 0)) - default_alignment = ""; - else if ((center >= left)&&(center >= right)) /* Favor center since it's the longest word */ - default_alignment = "center"; - else if ((right >= center)&&(right >= left)) - default_alignment = "right"; /* Favor right since it's second longest */ - else - default_alignment = "left"; -} - - -void OutputString(uni_string *u) -{ - unsigned int i; - - if (u == 0) - return; - - if (u->uni < 2) - { - if (null_string(u->str)) - { - if (Ascii == 0) - printf(OutputXML ? "" : " "); - else if (!Csv) - printf(" "); - } - else - { - if (Ascii) /* If Ascii output requested, simply output the string */ - { /* These are broken up for performance */ - if (Csv) - { - for (i=0; ilen; i++) - { - if (u->str[i] == 0x22) - printf("\"\""); - else - putchar(u->str[i]); - } - } - else - { - for (i=0; ilen; i++) - putchar(u->str[i]); - } - return; - } - if (u->crun_cnt) - { - U16 loc, fnt_idx, crun_cnt=0; - int format_changed = 0; - html_attr h_flags; - - /* read the first format run */ - update_crun_info(&loc, &fnt_idx, crun_cnt, u->fmt_run); - html_flag_init(&h_flags); - for (i=0; ilen; i++) - { - if (i == loc) - { /* Time to change formats */ - if (format_changed) - { /* if old attributs, close */ - output_end_html_attr(&h_flags); - } - else - { /* FIXME: Also need to consider that a font may already be set for - the cell, in which case a closing tag should be set. */ - format_changed = 1; - } - - /* set new attr */ - output_start_font_attribute(&h_flags, fnt_idx); - output_start_html_attr(&h_flags, fnt_idx, 1); - - /* get next fmt_run */ - if (crun_cnt < u->crun_cnt) - { - crun_cnt++; - update_crun_info(&loc, &fnt_idx, crun_cnt, u->fmt_run); - } - } - OutputCharCorrected(u->str[i]); - } - if (format_changed) - { - output_end_html_attr(&h_flags); - } - } - else - { - for (i=0; ilen; i++) - OutputCharCorrected(u->str[i]); - } - } - } - else - { - if (u->len == 0) - { - if (Ascii) - printf(" "); - else - printf(OutputXML ? "" : " "); - } - else - { - if (u->len == 2) - { - if (memcmp(u->str, "& ", 2) == 0) - printf("…"); - else - { - for (i=0; ilen; i+=2) - print_utf8(getShort(&(u->str[i]))); - } - } - else - { - for (i=0; ilen; i+=2) - print_utf8(getShort(&(u->str[i]))); - } - } - } -} - -void OutputCharCorrected(U8 c) -{ - if (MultiByte && (c & 0x80)) - { - putchar(c); - return; - } - switch (c) - { /* Special char handlers here... */ - case 0x3C: /* '<' - less than */ - printf("<"); - break; - case 0x3E: /* '>' - greater than */ - printf(">"); - break; - case 0x26: /* '&' - ampersand */ - printf("&"); - break; - case 0x22: /* '"' - double quote */ - printf("""); - break; - /* Also need to cover 128-159 since MS uses this area... */ - case 0x80: /* Euro Symbol */ - printf("€"); - break; - case 0x82: /* baseline single quote */ - printf("‚"); - break; - case 0x83: /* florin */ - printf("ƒ"); - break; - case 0x84: /* baseline double quote */ - printf("„"); - break; - case 0x85: /* ellipsis */ - printf("…"); - break; - case 0x86: /* dagger */ - printf("†"); - break; - case 0x87: /* double dagger */ - printf("‡"); - break; - case 0x88: /* circumflex accent */ - printf("ˆ"); - break; - case 0x89: /* permile */ - printf("‰"); - break; - case 0x8A: /* S Hacek */ - printf("Š"); - break; - case 0x8B: /* left single guillemet */ - printf("‹"); - break; - case 0x8C: /* OE ligature */ - printf("Œ"); - break; - case 0x8E: /* #LATIN CAPITAL LETTER Z WITH CARON */ - printf("Ž"); - break; - case 0x91: /* left single quote ? */ - printf("‘"); - break; - case 0x92: /* right single quote ? */ - printf("’"); - break; - case 0x93: /* left double quote */ - printf("“"); - break; - case 0x94: /* right double quote */ - printf("”"); - break; - case 0x95: /* bullet */ - printf("•"); - break; - case 0x96: /* endash */ - printf("–"); - break; - case 0x97: /* emdash */ - printf("—"); - break; - case 0x98: /* tilde accent */ - printf("˜"); - break; - case 0x99: /* trademark ligature */ - printf("™"); - break; - case 0x9A: /* s Hacek */ - printf("š"); - break; - case 0x9B: /* right single guillemet */ - printf("›"); - break; - case 0x9C: /* oe ligature */ - printf("œ"); - break; - case 0x9F: /* Y Dieresis */ - printf("Ÿ"); - break; - case 0xE1: /* a acute */ - printf("á"); - break; - case 0xE9: /* e acute */ - printf("é"); - break; - case 0xED: /* i acute */ - printf("í"); - break; - case 0xF3: /* o acute */ - printf("ó"); - break; - case 0xFA: /* u acute */ - printf("ú"); - break; - case 0xFD: /* y acute */ - printf("ý"); - break; - case 0xC1: /* A acute */ - printf("Á"); - break; - case 0xC9: /* E acute */ - printf("É"); - break; - case 0xCD: /* I acute */ - printf("Í"); - break; - case 0xD3: /* O acute */ - printf("Ó"); - break; - case 0xDA: /* U acute */ - printf("Ú"); - break; - case 0xDD: /* Y acute */ - printf("Ý"); - break; - case 0xB0: /* degrees */ - printf("deg."); - break; - default: - putchar(c); - break; - } -} - -void update_crun_info(U16 *loc, U16 *fmt_idx, U16 crun_cnt, U8 *fmt_run) -{ - U16 tloc, tfmt_idx; - U16 offset = (U16)(crun_cnt*4); - - tloc = getShort(&fmt_run[offset]); - tfmt_idx = getShort(&fmt_run[offset+2]); - *loc = tloc; - *fmt_idx = tfmt_idx; -} - -void put_utf8(U16 c) -{ - putchar((int)0x0080 | (c & 0x003F)); -} - -void print_utf8(U16 c) -{ - if (c < 0x80) - OutputCharCorrected(c); - else if (c < 0x800) - { - putchar(0xC0 | (c >> 6)); - put_utf8(c); - } - else - { - putchar(0xE0 | (c >> 12)); - put_utf8((U16)(c >> 6)); - put_utf8(c); - } -} - -void uni_string_clear(uni_string *str) -{ - if (str == 0) - return; - - str->str = 0; - str->uni = 0; - str->len = 0; - str->fmt_run = 0; - str->crun_cnt = 0; -} - -int uni_string_comp(uni_string *s1, uni_string *s2) -{ - if ((s1 == 0)||(s2 == 0)) - return -1; - if ((s1->str == 0)||(s2->str == 0)) - return -1; - - if ((s1->uni == s2->uni) && (s1->len == s2->len)) - return memcmp(s1->str, s2->str, s1->len); - else - return -1; -} - - - -void html_flag_init(html_attr *h) -{ - h->fflag = 0; - h->bflag = 0; - h->iflag = 0; - h->sflag = 0; - h->uflag = 0; - h->sbflag = 0; - h->spflag = 0; -} - -void output_start_font_attribute(html_attr *h, U16 fnt_idx) -{ - if (uni_string_comp(&default_font, &(font_array[fnt_idx]->name)) != 0) - { - h->fflag = 1; - printf("name)); - printf("\""); - } - if (font_array[fnt_idx]->c_idx != 0x7FFF) - { - char color[8]; - if (numCustomColors) - { - if ((font_array[fnt_idx]->c_idx < numCustomColors)&&use_colors) - strcpy(color, (char *)customColors[font_array[fnt_idx]->c_idx-8]); - else - strcpy(color, "000000"); - } - else - { - if ((font_array[fnt_idx]->c_idx < MAX_COLORS)&&use_colors) - strcpy(color, colorTab[font_array[fnt_idx]->c_idx]); - else - strcpy(color, "000000"); - } - if (strcmp(color, "000000") != 0) - { - if (h->fflag) - printf(" COLOR=\"%s\"", color); - else - { - h->fflag = 1; - printf("super & 0x0003) - { - if (h->fflag) - printf(" SIZE=\"2\""); /* Sub & Superscript */ - else - { - h->fflag = 1; - printf("fflag) - { - if (font_array[fnt_idx]->size != default_fontsize) - printf(" SIZE=\"%d\"", font_array[fnt_idx]->size); - } - else - { - if (font_array[fnt_idx]->size != default_fontsize) - { - h->fflag = 1; - printf("size); - } - } - } - if (h->fflag) - printf(">"); -} - - diff --git a/xlhtml/xml.c b/xlhtml/xml.c index 342c6de..58feabe 100644 --- a/xlhtml/xml.c +++ b/xlhtml/xml.c @@ -25,143 +25,168 @@ -void OutputTableXML(void) +void +OutputTableXML (void) { - int i, j, k; + int i, j, k; - printf( "\n"); /* Latin-1 */ + break; + case 1: + printf ("windows-1252\"?>\n"); /* Microsoft */ + break; + default: + printf ("utf-8\"?>\n"); /* Unicode */ + break; + } + + SetupExtraction (); + + printf ("\n"); + printf (""); + if (title) + printf ("%s", title); + else + printf ("%s", filename); + printf ("\n"); + + + printf ("\t\n"); + + /* Here's where we dump the Html Page out */ + for (i = first_sheet; i <= last_sheet; i++) /* For each worksheet */ + { + trim_sheet_edges (i); + update_default_font (i); + if (ws_array[i] == 0) + continue; + if ((ws_array[i]->biggest_row == -1) + || (ws_array[i]->biggest_col == -1)) + continue; + if (ws_array[i]->c_array == 0) + continue; + + printf ("\t\t\n"); + printf ("\t\t\t%d\n", i); + + /* Print its name */ + if (next_ws_title > 0) { - case 0: - printf("iso-8859-1\" ?>\n"); /* Latin-1 */ - break; - case 1: - printf("windows-1252\"?>\n"); /* Microsoft */ - break; - default: - printf("utf-8\"?>\n"); /* Unicode */ - break; + if (ws_array[i]->ws_title.str) + { + printf ("\t\t\t"); + OutputString (&ws_array[i]->ws_title); + printf ("\n"); + } + else + printf ("\t\t\t(Unknown Page)\n"); } - SetupExtraction(); + printf ("\t\t\t%ld\n", + (unsigned long) ws_array[i]->first_row); + printf ("\t\t\t%d\n", + (int) ws_array[i]->biggest_row); + printf ("\t\t\t%ld\n", + (long) ws_array[i]->first_col); + printf ("\t\t\t%d\n", + (int) ws_array[i]->biggest_col); + printf ("\t\t\t\n"); - printf( "\n" ); - printf( "\t\n" ); - - /* Here's where we dump the Html Page out */ - for (i=first_sheet; i<=last_sheet; i++) /* For each worksheet */ + for (j = ws_array[i]->first_row; j <= ws_array[i]->biggest_row; j++) { - trim_sheet_edges(i); - update_default_font(i); - if (ws_array[i] == 0) - continue; - if ((ws_array[i]->biggest_row == -1)||(ws_array[i]->biggest_col == -1)) - continue; - if (ws_array[i]->c_array == 0) - continue; - - printf( "\t\t\n" ); - printf( "\t\t\t%d\n", i ); - - /* Print its name */ - if (next_ws_title > 0) + update_default_alignment (i, j); + printf ("\t\t\t\t\n"); + for (k = ws_array[i]->first_col; k <= ws_array[i]->biggest_col; k++) + { + printf ("\t\t\t\t\tc_array[(j * ws_array[i]->max_cols) + k], 1); /* This stuff happens for each cell... */ + printf ("\n"); + if (ws_array[i]->c_array[(j * ws_array[i]->max_cols) + k]) { - if (ws_array[i]->ws_title.str) - { - printf("\t\t\t"); - OutputString(&ws_array[i]->ws_title); - printf("\n"); - } - else - printf("\t\t\t(Unknown Page)\n"); + if (ws_array[i]->c_array[(j * ws_array[i]->max_cols) + k]-> + colspan != 0) + k += + ws_array[i]->c_array[(j * ws_array[i]->max_cols) + + k]->colspan - 1; } - printf( "\t\t\t%ld\n", (unsigned long)ws_array[i]->first_row ); - printf( "\t\t\t%d\n", (int) ws_array[i]->biggest_row ); - printf( "\t\t\t%ld\n", (long) ws_array[i]->first_col ); - printf( "\t\t\t%d\n", (int)ws_array[i]->biggest_col ); - printf( "\t\t\t\n" ); + } - for (j=ws_array[i]->first_row; j<=ws_array[i]->biggest_row; j++) - { - update_default_alignment(i, j); - printf("\t\t\t\t\n"); - for (k=ws_array[i]->first_col; k<=ws_array[i]->biggest_col; k++) - { - printf("\t\t\t\t\tc_array[(j*ws_array[i]->max_cols)+k], 1); /* This stuff happens for each cell... */ - printf("\n" ); - if (ws_array[i]->c_array[(j*ws_array[i]->max_cols)+k]) - { - if (ws_array[i]->c_array[(j*ws_array[i]->max_cols)+k]->colspan != 0) - k += ws_array[i]->c_array[(j*ws_array[i]->max_cols)+k]->colspan-1; - } - - } - - printf("\t\t\t\t\n"); - } - printf( "\t\t\t\n" ); - printf("\t\t\n"); + printf ("\t\t\t\t\n"); } - printf( "\t\n" ); + printf ("\t\t\t\n"); + printf ("\t\t\n"); + } + printf ("\t\n"); - /* Print the author's name in itallics... */ - if (author.str) - { - printf("\t"); - OutputString(&author); - printf("\n"); - } + /* Print the author's name in itallics... */ + if (author.str) + { + printf ("\t"); + OutputString (&author); + printf ("\n"); + } - /* Print when & how the file was last updated. */ - if (lastUpdated) - printf("\t%s", lastUpdated); - printf( "\t" ); - switch (file_version) - { - case EXCEL95: - printf("using Excel 5.0 or 95"); - break; - case EXCEL97: - printf("using Excel 97/2000"); - break; - default: - printf("using Excel ????"); - break; - } - printf("\n"); - - /* Next print Disclaimers... */ - if (NoFormat) - printf("\t%d\n", NoFormat ); - if ((notAccurate)&&(formula_warnings)) - printf("\t%d\n", notAccurate ); - if (NotImplemented) - printf("\t%d\n", NotImplemented ); - if (Unsupported) - printf("\t%d\n", Unsupported ); + /* Print when & how the file was last updated. */ + if (lastUpdated) + printf ("\t%s", lastUpdated); + printf ("\t"); + switch (file_version) + { + case EXCEL95: + printf ("using Excel 5.0 or 95"); + break; + case EXCEL97: + printf ("using Excel 97/2000"); + break; + default: + printf ("using Excel ????"); + break; + } + printf ("\n"); - /* Now out exceeded capacity warnings... */ - if (MaxWorksheetsExceeded) - printf("\tThe Maximum Number of Worksheets were exceeded, you might want to increase it.\n "); - if (MaxRowExceeded) - printf("\tThe Maximum Number of Rows were exceeded, you might want to increase it.\n "); - if (MaxColExceeded) - printf("\tThe Maximum Number of Columns were exceeded, you might want to increase it.\n"); - if (MaxStringsExceeded) - printf("\tThe Maximum Number of Strings were exceeded, you might want to increase it.\n"); - if (MaxFontsExceeded) - printf("\tThe Maximum Number of Fonts were exceeded, you might want to increase it.\n"); - if (MaxPalExceeded) - printf("\tThe Maximum Number of Color Palettes were exceeded, you might want to increase it.\n"); - if (MaxXFExceeded) - printf("\tThe Maximum Number of Extended Formats were exceeded, you might want to increase it.\n"); - if (MaxFormatsExceeded) - printf("\tThe Maximum Number of Formats were exceeded, you might want to increase it.\n"); + /* Next print Disclaimers... */ + if (NoFormat) + printf ("\t%d\n", NoFormat); + if ((notAccurate) && (formula_warnings)) + printf ("\t%d\n", notAccurate); + if (NotImplemented) + printf ("\t%d\n", NotImplemented); + if (Unsupported) + printf ("\t%d\n", Unsupported); - /* Output Credit */ - printf("\tCreated with xlhtml %s\n", VERSION); - printf("\thttp://chicago.sf.net/xlhtml/\n"); - printf( "\n" ); + /* Now out exceeded capacity warnings... */ + if (MaxWorksheetsExceeded) + printf + ("\tThe Maximum Number of Worksheets were exceeded, you might want to increase it.\n "); + if (MaxRowExceeded) + printf + ("\tThe Maximum Number of Rows were exceeded, you might want to increase it.\n "); + if (MaxColExceeded) + printf + ("\tThe Maximum Number of Columns were exceeded, you might want to increase it.\n"); + if (MaxStringsExceeded) + printf + ("\tThe Maximum Number of Strings were exceeded, you might want to increase it.\n"); + if (MaxFontsExceeded) + printf + ("\tThe Maximum Number of Fonts were exceeded, you might want to increase it.\n"); + if (MaxPalExceeded) + printf + ("\tThe Maximum Number of Color Palettes were exceeded, you might want to increase it.\n"); + if (MaxXFExceeded) + printf + ("\tThe Maximum Number of Extended Formats were exceeded, you might want to increase it.\n"); + if (MaxFormatsExceeded) + printf + ("\tThe Maximum Number of Formats were exceeded, you might want to increase it.\n"); + + /* Output Credit */ + printf ("\tCreated with xlhtml %s\n", VERSION); + printf ("\thttp://chicago.sf.net/xlhtml/\n"); + printf ("\n"); }