From 618efe9bd2b3fdaf7e5ad6be6301ffd1ee241435 Mon Sep 17 00:00:00 2001 From: Michael Meeks Date: Sun, 8 Nov 1998 23:48:44 +0000 Subject: [PATCH] Fixed minor bug in cell text splitting, Implemented very hacked version of formula support: very ugly code indeed :-) intended as a proof of concept thing, 1 working function = 'SUM' Removed misc. debug, and added more elsewhere --- ChangeLog-1999-07-09 | 10 ++ ChangeLog-2000-02-23 | 10 ++ OChangeLog-1999-07-09 | 10 ++ OChangeLog-2000-02-23 | 10 ++ TODO | 4 + plugins/excel/ms-excel-read.c | 9 +- plugins/excel/ms-excel-read.h | 3 +- plugins/excel/ms-excel.c | 9 +- plugins/excel/ms-excel.h | 3 +- plugins/excel/ms-formula-read.c | 196 ++++++++++++++++++++++++++++---- plugins/excel/ms-formula-read.h | 5 +- plugins/excel/ms-formula.c | 196 ++++++++++++++++++++++++++++---- plugins/excel/ms-formula.h | 5 +- 13 files changed, 412 insertions(+), 58 deletions(-) diff --git a/ChangeLog-1999-07-09 b/ChangeLog-1999-07-09 index a9f6f0aec..3f5de804a 100644 --- a/ChangeLog-1999-07-09 +++ b/ChangeLog-1999-07-09 @@ -1,3 +1,13 @@ +1998-11-08 Michael Meeks + + * plugins/excel/ms-formula.c: Major top to bottom changes + basic hacked RPN to Infix parsing started in a rather nasty + fashion. Much more work needed only 1 ( the SUM ) function + supported. + + * src/cell.c (cell_split_text): Fixed string length malloc + bug, out by 1 trashing stack. + 1998-11-08 Michael Meeks * src/workbook.c, src/sheet.h, src/main.c (workbook_read): diff --git a/ChangeLog-2000-02-23 b/ChangeLog-2000-02-23 index a9f6f0aec..3f5de804a 100644 --- a/ChangeLog-2000-02-23 +++ b/ChangeLog-2000-02-23 @@ -1,3 +1,13 @@ +1998-11-08 Michael Meeks + + * plugins/excel/ms-formula.c: Major top to bottom changes + basic hacked RPN to Infix parsing started in a rather nasty + fashion. Much more work needed only 1 ( the SUM ) function + supported. + + * src/cell.c (cell_split_text): Fixed string length malloc + bug, out by 1 trashing stack. + 1998-11-08 Michael Meeks * src/workbook.c, src/sheet.h, src/main.c (workbook_read): diff --git a/OChangeLog-1999-07-09 b/OChangeLog-1999-07-09 index a9f6f0aec..3f5de804a 100644 --- a/OChangeLog-1999-07-09 +++ b/OChangeLog-1999-07-09 @@ -1,3 +1,13 @@ +1998-11-08 Michael Meeks + + * plugins/excel/ms-formula.c: Major top to bottom changes + basic hacked RPN to Infix parsing started in a rather nasty + fashion. Much more work needed only 1 ( the SUM ) function + supported. + + * src/cell.c (cell_split_text): Fixed string length malloc + bug, out by 1 trashing stack. + 1998-11-08 Michael Meeks * src/workbook.c, src/sheet.h, src/main.c (workbook_read): diff --git a/OChangeLog-2000-02-23 b/OChangeLog-2000-02-23 index a9f6f0aec..3f5de804a 100644 --- a/OChangeLog-2000-02-23 +++ b/OChangeLog-2000-02-23 @@ -1,3 +1,13 @@ +1998-11-08 Michael Meeks + + * plugins/excel/ms-formula.c: Major top to bottom changes + basic hacked RPN to Infix parsing started in a rather nasty + fashion. Much more work needed only 1 ( the SUM ) function + supported. + + * src/cell.c (cell_split_text): Fixed string length malloc + bug, out by 1 trashing stack. + 1998-11-08 Michael Meeks * src/workbook.c, src/sheet.h, src/main.c (workbook_read): diff --git a/TODO b/TODO index acf188a7d..659af63b4 100644 --- a/TODO +++ b/TODO @@ -86,3 +86,7 @@ GNOME Spread Sheet task list It does not shrink. +* Excel importing + + Add collation of BIFF continuation records to the + previous record, to save many checks in the code. diff --git a/plugins/excel/ms-excel-read.c b/plugins/excel/ms-excel-read.c index 519357661..07827ba5d 100644 --- a/plugins/excel/ms-excel-read.c +++ b/plugins/excel/ms-excel-read.c @@ -242,7 +242,7 @@ static void ms_excel_set_cell_colors (MS_EXCEL_SHEET *sheet, Cell *cell, BIFF_XF col = xf->foregnd_col ; if (col>=0 && col < sheet->wb->palette->length) { - printf ("FG set to %d = (%d,%d,%d)\n", col, p->red[col], p->green[col], p->blue[col]) ; + /* printf ("FG set to %d = (%d,%d,%d)\n", col, p->red[col], p->green[col], p->blue[col]) ; */ cell_set_foreground (cell, p->red[col], p->green[col], p->blue[col]) ; } else @@ -250,7 +250,7 @@ static void ms_excel_set_cell_colors (MS_EXCEL_SHEET *sheet, Cell *cell, BIFF_XF col = xf->backgnd_col ; if (col>=0 && col < sheet->wb->palette->length) { - printf ("BG set to %d = (%d,%d,%d)\n", col, p->red[col], p->green[col], p->blue[col]) ; + /* printf ("BG set to %d = (%d,%d,%d)\n", col, p->red[col], p->green[col], p->blue[col]) ; */ cell_set_background (cell, p->red[col], p->green[col], p->blue[col]) ; } else @@ -283,7 +283,7 @@ static void ms_excel_set_cell_font (MS_EXCEL_SHEET *sheet, Cell *cell, BIFF_XF_D printf ("Unknown fount idx %d\n", xf->font_idx) ; } -static void ms_excel_set_cell_xf(MS_EXCEL_SHEET *sheet, Cell *cell, int xfidx) +void ms_excel_set_cell_xf(MS_EXCEL_SHEET *sheet, Cell *cell, int xfidx) { GList *ptr ; int cnt ; @@ -699,7 +699,7 @@ static void ms_excel_read_cell (BIFF_QUERY *q, MS_EXCEL_SHEET *sheet) /* printf ("Row %d formatting\n", BIFF_GETROW(q)) ; */ break ; case BIFF_FORMULA: /* FIXME: S59D8F.HTM */ - ms_excel_parse_formular (sheet, q) ; + ms_excel_parse_formula (sheet, q) ; break ; default: printf ("Opcode : 0x%x, length 0x%x\n", q->opcode, q->length) ; @@ -847,6 +847,7 @@ Workbook *ms_excelReadWorkbook(MS_OLE_FILE *file) if (ver) free_ms_biff_bof_data(ver) ; } + workbook_recalc (wb->gnum_wb) ; return wb->gnum_wb ; } diff --git a/plugins/excel/ms-excel-read.h b/plugins/excel/ms-excel-read.h index e0dc1d9a5..a6b2e3e6b 100644 --- a/plugins/excel/ms-excel-read.h +++ b/plugins/excel/ms-excel-read.h @@ -27,7 +27,8 @@ typedef struct _MS_EXCEL_SHEET eBiff_version ver ; } MS_EXCEL_SHEET ; -void ms_excel_sheet_insert (MS_EXCEL_SHEET *sheet, int xfidx, int col, int row, char *text) ; +extern void ms_excel_sheet_insert (MS_EXCEL_SHEET *sheet, int xfidx, int col, int row, char *text) ; +extern void ms_excel_set_cell_xf(MS_EXCEL_SHEET *sheet, Cell *cell, int xfidx) ; typedef struct _MS_EXCEL_PALETTE { diff --git a/plugins/excel/ms-excel.c b/plugins/excel/ms-excel.c index 519357661..07827ba5d 100644 --- a/plugins/excel/ms-excel.c +++ b/plugins/excel/ms-excel.c @@ -242,7 +242,7 @@ static void ms_excel_set_cell_colors (MS_EXCEL_SHEET *sheet, Cell *cell, BIFF_XF col = xf->foregnd_col ; if (col>=0 && col < sheet->wb->palette->length) { - printf ("FG set to %d = (%d,%d,%d)\n", col, p->red[col], p->green[col], p->blue[col]) ; + /* printf ("FG set to %d = (%d,%d,%d)\n", col, p->red[col], p->green[col], p->blue[col]) ; */ cell_set_foreground (cell, p->red[col], p->green[col], p->blue[col]) ; } else @@ -250,7 +250,7 @@ static void ms_excel_set_cell_colors (MS_EXCEL_SHEET *sheet, Cell *cell, BIFF_XF col = xf->backgnd_col ; if (col>=0 && col < sheet->wb->palette->length) { - printf ("BG set to %d = (%d,%d,%d)\n", col, p->red[col], p->green[col], p->blue[col]) ; + /* printf ("BG set to %d = (%d,%d,%d)\n", col, p->red[col], p->green[col], p->blue[col]) ; */ cell_set_background (cell, p->red[col], p->green[col], p->blue[col]) ; } else @@ -283,7 +283,7 @@ static void ms_excel_set_cell_font (MS_EXCEL_SHEET *sheet, Cell *cell, BIFF_XF_D printf ("Unknown fount idx %d\n", xf->font_idx) ; } -static void ms_excel_set_cell_xf(MS_EXCEL_SHEET *sheet, Cell *cell, int xfidx) +void ms_excel_set_cell_xf(MS_EXCEL_SHEET *sheet, Cell *cell, int xfidx) { GList *ptr ; int cnt ; @@ -699,7 +699,7 @@ static void ms_excel_read_cell (BIFF_QUERY *q, MS_EXCEL_SHEET *sheet) /* printf ("Row %d formatting\n", BIFF_GETROW(q)) ; */ break ; case BIFF_FORMULA: /* FIXME: S59D8F.HTM */ - ms_excel_parse_formular (sheet, q) ; + ms_excel_parse_formula (sheet, q) ; break ; default: printf ("Opcode : 0x%x, length 0x%x\n", q->opcode, q->length) ; @@ -847,6 +847,7 @@ Workbook *ms_excelReadWorkbook(MS_OLE_FILE *file) if (ver) free_ms_biff_bof_data(ver) ; } + workbook_recalc (wb->gnum_wb) ; return wb->gnum_wb ; } diff --git a/plugins/excel/ms-excel.h b/plugins/excel/ms-excel.h index e0dc1d9a5..a6b2e3e6b 100644 --- a/plugins/excel/ms-excel.h +++ b/plugins/excel/ms-excel.h @@ -27,7 +27,8 @@ typedef struct _MS_EXCEL_SHEET eBiff_version ver ; } MS_EXCEL_SHEET ; -void ms_excel_sheet_insert (MS_EXCEL_SHEET *sheet, int xfidx, int col, int row, char *text) ; +extern void ms_excel_sheet_insert (MS_EXCEL_SHEET *sheet, int xfidx, int col, int row, char *text) ; +extern void ms_excel_set_cell_xf(MS_EXCEL_SHEET *sheet, Cell *cell, int xfidx) ; typedef struct _MS_EXCEL_PALETTE { diff --git a/plugins/excel/ms-formula-read.c b/plugins/excel/ms-formula-read.c index e0151165d..4b8f4f50b 100644 --- a/plugins/excel/ms-formula-read.c +++ b/plugins/excel/ms-formula-read.c @@ -12,45 +12,195 @@ #include #include "gnumeric.h" +#include "utils.h" #include "ms-formula.h" -void ms_excel_parse_formular (MS_EXCEL_SHEET *sheet, BIFF_QUERY *q) +/* FIXME these probably don't work weel with negative numbers ! */ +/** + * A useful routine for extracting data from a common + * storage structure. + **/ +static CellRef *getRefV7(BYTE col, WORD gbitrw) { + CellRef *cr = (CellRef *)malloc(sizeof(CellRef)) ; + cr->col = col ; + cr->row = (gbitrw & 0x3fff) ; + cr->row_relative = (gbitrw & 0x8000) ; + cr->col_relative = (gbitrw & 0x4000) ; + return cr ; +} +/** + * A useful routine for extracting data from a common + * storage structure. + **/ +static CellRef *getRefV8(WORD row, WORD gbitcl) +{ + CellRef *cr = (CellRef *)malloc(sizeof(CellRef)) ; + cr->row = row ; + cr->col = (gbitcl & 0x3fff) ; + cr->row_relative = (gbitcl & 0x8000) ; + cr->col_relative = (gbitcl & 0x4000) ; + return cr ; +} + +/** + * Parse that RP Excel formula, see S59E2B.HTM + * Sadly has to be parsed to text and back ! + **/ +void ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, BIFF_QUERY *q) +{ + Cell *cell ; BYTE *cur ; - int length ; + int length, fn_row, fn_col ; + GList *stack = 0 ; /* A whole load of Text arguments */ g_assert (q->ls_op == BIFF_FORMULA) ; - printf ("Formular:\n") ; - dump (q->data, q->length) ; - printf ("Formula at [%d, %d] XF %d :\n", BIFF_GETCOL(q), BIFF_GETROW(q), - BIFF_GETXF(q)) ; - + fn_col = BIFF_GETCOL(q) ; + fn_row = BIFF_GETROW(q) ; + printf ("Formula at [%d, %d] XF %d :\n", fn_row, fn_col, BIFF_GETXF(q)) ; + printf ("formula data : \n") ; + dump (q->data +22, q->length-22) ; + /* This will be safe when we collate continuation records in get_query */ length = BIFF_GETWORD(q->data + 20) ; - cur = q->data + 22 ; + /* NB. the effective '-1' here is so that the offsets and lengths + are identical to those in the documentation */ + cur = q->data + 23 ; while (length>0) { - if (BIFF_GETBYTE(cur) > FORMULA_PTG_MAX) + int ptg_length = 0 ; + int ptg = BIFF_GETBYTE(cur-1) ; + int ptgbase = ((ptg & 0x40) ? (ptg | 0x20): ptg) & 0x3F ; + if (ptg > FORMULA_PTG_MAX) break ; - switch (BIFF_GETBYTE(cur)) + switch (ptgbase) { case FORMULA_PTG_REF: { - int row, col, relrow, relcol ; - g_assert (sheet->ver == eBiffV8) ; - col = BIFF_GETWORD(cur+1) ; - row = BIFF_GETWORD(cur+3) ; - relrow = row&0x8000 ; - relcol = row&0x4000 ; - row = row&0x3fff ; - printf ("Cell [%d,%d] PTG ref! relative col? %d, row?%d\n", col, row, relcol, relrow) ; + CellRef *ref ; + char *buffer ; + if (sheet->ver == eBiffV8) + { + ref = getRefV8 (BIFF_GETWORD(cur), BIFF_GETWORD(cur + 2)) ; + ptg_length = 4 ; + } + else + { + ref = getRefV7 (BIFF_GETBYTE(cur+2), BIFF_GETWORD(cur)) ; + ptg_length = 3 ; + } + buffer = cellref_name (ref, fn_col, fn_row) ; + stack = g_list_append (stack, strdup (buffer)) ; + printf ("%s\n", buffer) ; } break ; - default: - length = 0 ; + case FORMULA_PTG_AREA: + { + CellRef *first, *last ; + char buffer[128] ; + if (sheet->ver == eBiffV8) + { + first = getRefV8(BIFF_GETBYTE(cur+0), BIFF_GETWORD(cur+4)) ; + last = getRefV8(BIFF_GETBYTE(cur+2), BIFF_GETWORD(cur+6)) ; + ptg_length = 8 ; + } + else + { + first = getRefV7(BIFF_GETBYTE(cur+4), BIFF_GETWORD(cur+0)) ; + last = getRefV7(BIFF_GETBYTE(cur+5), BIFF_GETWORD(cur+2)) ; + ptg_length = 6 ; + } + strcpy (buffer, cellref_name (first, fn_col, fn_row)) ; + strcat (buffer, ":") ; + strcat (buffer, cellref_name (last, fn_col, fn_row)) ; + stack = g_list_append (stack, strdup(buffer)) ; + printf ("%s\n", buffer) ; + } + break ; + /* FIXME: the standard function indexes need to be found from xlcall.h */ + case FORMULA_PTG_FUNC_VAR: + { + int numargs = (BIFF_GETBYTE( cur ) & 0x7f) ; + int prompt = (BIFF_GETBYTE( cur ) & 0x80) ; /* Prompts the user ? */ + int iftab = (BIFF_GETWORD(cur+1) & 0x7fff) ; /* index into fn table */ + int cmdquiv = (BIFF_GETWORD(cur+1) & 0x8000) ; /* is a command equiv.?*/ + GList *args=0, *tmp ; + int lp ; + char buffer[4096] ; /* Nasty ! */ + char *ptr ; + printf ("Found formula %d with %d args\n", iftab, numargs) ; + /* Whack those arguments on an arg list */ + for (lp=0;lpdata) ; + g_list_free (tmp) ; + } + /* The arguments are now in reverse order in 'args' */ + if (iftab == 4) /* Guess at a SUM fn */ + { + sprintf (buffer, "SUM( ") ; + tmp = g_list_first (args) ; + for (lp=0;lpdata) ; + tmp=tmp->next ; + } + g_list_free (args) ; + ptg_length = 3 ; + } break ; + case FORMULA_PTG_EXP: /* FIXME: the formula is the same as another record ... we need a cell_get_funtion call ! */ + { + int row, col ; + row = BIFF_GETWORD(cur) ; + col = BIFF_GETWORD(cur+2) ; + printf ("Unimplemented ARARY formula at [%d,%d]\n", row, col) ; + return ; + ptg_length = 4 ; + } + break ; + case FORMULA_PTG_FUNC: + { + int iftab = BIFF_GETWORD(cur) ; + printf ("FIXME, unimplemented function table pointer %d\n", iftab) ; + return ; + ptg_length = 2 ; + } + break ; + default: + printf ("Unknown PTG 0x%x base %x\n", ptg, ptgbase) ; + ms_excel_sheet_insert (sheet, BIFF_GETXF(q), BIFF_GETCOL(q), BIFF_GETROW(q), "Unknown formula") ; + return ; } + cur+= (ptg_length+1) ; + length-= (ptg_length+1) ; + } + printf ("--------- Found valid formula !---------\n") ; + cell = sheet_cell_fetch (sheet->gnum_sheet, BIFF_GETCOL(q), BIFF_GETROW(q)) ; + if (stack) + { + char *init = g_list_first (stack)->data ; + char *ptr = (char *)malloc(strlen(init)+2) ; + strcpy (ptr, "=") ; + strcat (ptr, init) ; + printf ("The answer is : '%s'\n", ptr) ; + /* FIXME: this _should_ be a set_formula with the formula, and a + set_text_simple with the current value */ + cell_set_text(cell, ptr) ; + /* Set up cell stuff */ + ms_excel_set_cell_xf (sheet, cell, BIFF_GETXF(q)) ; } - printf ("Unknown PTG 0x%x\n", BIFF_GETBYTE(cur)) ; - ms_excel_sheet_insert (sheet, BIFF_GETXF(q), BIFF_GETCOL(q), BIFF_GETROW(q), "Unknown formular") ; } - diff --git a/plugins/excel/ms-formula-read.h b/plugins/excel/ms-formula-read.h index 49a0b5f3a..12456e8d2 100644 --- a/plugins/excel/ms-formula-read.h +++ b/plugins/excel/ms-formula-read.h @@ -10,10 +10,13 @@ #include "ms-excel.h" #include "ms-biff.h" -void ms_excel_parse_formular (MS_EXCEL_SHEET *sheet, BIFF_QUERY *q) ; +void ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, BIFF_QUERY *q) ; #define FORMULA_PTG_MAX 0x7f +#define FORMULA_PTG_EXP 0x01 +#define FORMULA_PTG_FUNC 0x21 +#define FORMULA_PTG_FUNC_VAR 0x22 #define FORMULA_PTG_REF 0x24 #define FORMULA_PTG_AREA 0x25 #define FORMULA_PTG_MEM_AREA 0x26 diff --git a/plugins/excel/ms-formula.c b/plugins/excel/ms-formula.c index e0151165d..4b8f4f50b 100644 --- a/plugins/excel/ms-formula.c +++ b/plugins/excel/ms-formula.c @@ -12,45 +12,195 @@ #include #include "gnumeric.h" +#include "utils.h" #include "ms-formula.h" -void ms_excel_parse_formular (MS_EXCEL_SHEET *sheet, BIFF_QUERY *q) +/* FIXME these probably don't work weel with negative numbers ! */ +/** + * A useful routine for extracting data from a common + * storage structure. + **/ +static CellRef *getRefV7(BYTE col, WORD gbitrw) { + CellRef *cr = (CellRef *)malloc(sizeof(CellRef)) ; + cr->col = col ; + cr->row = (gbitrw & 0x3fff) ; + cr->row_relative = (gbitrw & 0x8000) ; + cr->col_relative = (gbitrw & 0x4000) ; + return cr ; +} +/** + * A useful routine for extracting data from a common + * storage structure. + **/ +static CellRef *getRefV8(WORD row, WORD gbitcl) +{ + CellRef *cr = (CellRef *)malloc(sizeof(CellRef)) ; + cr->row = row ; + cr->col = (gbitcl & 0x3fff) ; + cr->row_relative = (gbitcl & 0x8000) ; + cr->col_relative = (gbitcl & 0x4000) ; + return cr ; +} + +/** + * Parse that RP Excel formula, see S59E2B.HTM + * Sadly has to be parsed to text and back ! + **/ +void ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, BIFF_QUERY *q) +{ + Cell *cell ; BYTE *cur ; - int length ; + int length, fn_row, fn_col ; + GList *stack = 0 ; /* A whole load of Text arguments */ g_assert (q->ls_op == BIFF_FORMULA) ; - printf ("Formular:\n") ; - dump (q->data, q->length) ; - printf ("Formula at [%d, %d] XF %d :\n", BIFF_GETCOL(q), BIFF_GETROW(q), - BIFF_GETXF(q)) ; - + fn_col = BIFF_GETCOL(q) ; + fn_row = BIFF_GETROW(q) ; + printf ("Formula at [%d, %d] XF %d :\n", fn_row, fn_col, BIFF_GETXF(q)) ; + printf ("formula data : \n") ; + dump (q->data +22, q->length-22) ; + /* This will be safe when we collate continuation records in get_query */ length = BIFF_GETWORD(q->data + 20) ; - cur = q->data + 22 ; + /* NB. the effective '-1' here is so that the offsets and lengths + are identical to those in the documentation */ + cur = q->data + 23 ; while (length>0) { - if (BIFF_GETBYTE(cur) > FORMULA_PTG_MAX) + int ptg_length = 0 ; + int ptg = BIFF_GETBYTE(cur-1) ; + int ptgbase = ((ptg & 0x40) ? (ptg | 0x20): ptg) & 0x3F ; + if (ptg > FORMULA_PTG_MAX) break ; - switch (BIFF_GETBYTE(cur)) + switch (ptgbase) { case FORMULA_PTG_REF: { - int row, col, relrow, relcol ; - g_assert (sheet->ver == eBiffV8) ; - col = BIFF_GETWORD(cur+1) ; - row = BIFF_GETWORD(cur+3) ; - relrow = row&0x8000 ; - relcol = row&0x4000 ; - row = row&0x3fff ; - printf ("Cell [%d,%d] PTG ref! relative col? %d, row?%d\n", col, row, relcol, relrow) ; + CellRef *ref ; + char *buffer ; + if (sheet->ver == eBiffV8) + { + ref = getRefV8 (BIFF_GETWORD(cur), BIFF_GETWORD(cur + 2)) ; + ptg_length = 4 ; + } + else + { + ref = getRefV7 (BIFF_GETBYTE(cur+2), BIFF_GETWORD(cur)) ; + ptg_length = 3 ; + } + buffer = cellref_name (ref, fn_col, fn_row) ; + stack = g_list_append (stack, strdup (buffer)) ; + printf ("%s\n", buffer) ; } break ; - default: - length = 0 ; + case FORMULA_PTG_AREA: + { + CellRef *first, *last ; + char buffer[128] ; + if (sheet->ver == eBiffV8) + { + first = getRefV8(BIFF_GETBYTE(cur+0), BIFF_GETWORD(cur+4)) ; + last = getRefV8(BIFF_GETBYTE(cur+2), BIFF_GETWORD(cur+6)) ; + ptg_length = 8 ; + } + else + { + first = getRefV7(BIFF_GETBYTE(cur+4), BIFF_GETWORD(cur+0)) ; + last = getRefV7(BIFF_GETBYTE(cur+5), BIFF_GETWORD(cur+2)) ; + ptg_length = 6 ; + } + strcpy (buffer, cellref_name (first, fn_col, fn_row)) ; + strcat (buffer, ":") ; + strcat (buffer, cellref_name (last, fn_col, fn_row)) ; + stack = g_list_append (stack, strdup(buffer)) ; + printf ("%s\n", buffer) ; + } + break ; + /* FIXME: the standard function indexes need to be found from xlcall.h */ + case FORMULA_PTG_FUNC_VAR: + { + int numargs = (BIFF_GETBYTE( cur ) & 0x7f) ; + int prompt = (BIFF_GETBYTE( cur ) & 0x80) ; /* Prompts the user ? */ + int iftab = (BIFF_GETWORD(cur+1) & 0x7fff) ; /* index into fn table */ + int cmdquiv = (BIFF_GETWORD(cur+1) & 0x8000) ; /* is a command equiv.?*/ + GList *args=0, *tmp ; + int lp ; + char buffer[4096] ; /* Nasty ! */ + char *ptr ; + printf ("Found formula %d with %d args\n", iftab, numargs) ; + /* Whack those arguments on an arg list */ + for (lp=0;lpdata) ; + g_list_free (tmp) ; + } + /* The arguments are now in reverse order in 'args' */ + if (iftab == 4) /* Guess at a SUM fn */ + { + sprintf (buffer, "SUM( ") ; + tmp = g_list_first (args) ; + for (lp=0;lpdata) ; + tmp=tmp->next ; + } + g_list_free (args) ; + ptg_length = 3 ; + } break ; + case FORMULA_PTG_EXP: /* FIXME: the formula is the same as another record ... we need a cell_get_funtion call ! */ + { + int row, col ; + row = BIFF_GETWORD(cur) ; + col = BIFF_GETWORD(cur+2) ; + printf ("Unimplemented ARARY formula at [%d,%d]\n", row, col) ; + return ; + ptg_length = 4 ; + } + break ; + case FORMULA_PTG_FUNC: + { + int iftab = BIFF_GETWORD(cur) ; + printf ("FIXME, unimplemented function table pointer %d\n", iftab) ; + return ; + ptg_length = 2 ; + } + break ; + default: + printf ("Unknown PTG 0x%x base %x\n", ptg, ptgbase) ; + ms_excel_sheet_insert (sheet, BIFF_GETXF(q), BIFF_GETCOL(q), BIFF_GETROW(q), "Unknown formula") ; + return ; } + cur+= (ptg_length+1) ; + length-= (ptg_length+1) ; + } + printf ("--------- Found valid formula !---------\n") ; + cell = sheet_cell_fetch (sheet->gnum_sheet, BIFF_GETCOL(q), BIFF_GETROW(q)) ; + if (stack) + { + char *init = g_list_first (stack)->data ; + char *ptr = (char *)malloc(strlen(init)+2) ; + strcpy (ptr, "=") ; + strcat (ptr, init) ; + printf ("The answer is : '%s'\n", ptr) ; + /* FIXME: this _should_ be a set_formula with the formula, and a + set_text_simple with the current value */ + cell_set_text(cell, ptr) ; + /* Set up cell stuff */ + ms_excel_set_cell_xf (sheet, cell, BIFF_GETXF(q)) ; } - printf ("Unknown PTG 0x%x\n", BIFF_GETBYTE(cur)) ; - ms_excel_sheet_insert (sheet, BIFF_GETXF(q), BIFF_GETCOL(q), BIFF_GETROW(q), "Unknown formular") ; } - diff --git a/plugins/excel/ms-formula.h b/plugins/excel/ms-formula.h index 49a0b5f3a..12456e8d2 100644 --- a/plugins/excel/ms-formula.h +++ b/plugins/excel/ms-formula.h @@ -10,10 +10,13 @@ #include "ms-excel.h" #include "ms-biff.h" -void ms_excel_parse_formular (MS_EXCEL_SHEET *sheet, BIFF_QUERY *q) ; +void ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, BIFF_QUERY *q) ; #define FORMULA_PTG_MAX 0x7f +#define FORMULA_PTG_EXP 0x01 +#define FORMULA_PTG_FUNC 0x21 +#define FORMULA_PTG_FUNC_VAR 0x22 #define FORMULA_PTG_REF 0x24 #define FORMULA_PTG_AREA 0x25 #define FORMULA_PTG_MEM_AREA 0x26 -- GitLab