Commit f33a9a6e authored by Michael Meeks's avatar Michael Meeks

fixes to 'IF', excel string tables, implemented importing IF, and several

other 'optimised' ptgs.
parent d58ed610
1999-04-02 Michael Meeks <michael@imaginator.com>
* src/fn-sheet.c (gnumeric_if): Fix to allow variable
arguments, updated help & struct to comply, removed
possible memory leak. ( Luke 17:3,4 )
1999-04-01 Michael Meeks <michael@imaginator.com>
* src/workbook.c (sheet_action_delete_sheet): Fix docs.
......
1999-04-02 Michael Meeks <michael@imaginator.com>
* src/fn-sheet.c (gnumeric_if): Fix to allow variable
arguments, updated help & struct to comply, removed
possible memory leak. ( Luke 17:3,4 )
1999-04-01 Michael Meeks <michael@imaginator.com>
* src/workbook.c (sheet_action_delete_sheet): Fix docs.
......
1999-04-02 Michael Meeks <michael@imaginator.com>
* src/fn-sheet.c (gnumeric_if): Fix to allow variable
arguments, updated help & struct to comply, removed
possible memory leak. ( Luke 17:3,4 )
1999-04-01 Michael Meeks <michael@imaginator.com>
* src/workbook.c (sheet_action_delete_sheet): Fix docs.
......
1999-04-02 Michael Meeks <michael@imaginator.com>
* src/fn-sheet.c (gnumeric_if): Fix to allow variable
arguments, updated help & struct to comply, removed
possible memory leak. ( Luke 17:3,4 )
1999-04-01 Michael Meeks <michael@imaginator.com>
* src/workbook.c (sheet_action_delete_sheet): Fix docs.
......
1999-04-02 Michael Meeks <michael@imaginator.com>
* ms-formula.c (ms_excel_parse_formula): PTG_ATTR: corrected
debug output semantics.
Set IF to var-arg ( fn: 0x1 ).
Various Debug bits made conditional.
Implemented 'optimised' = 'hopelessly obfuscated' IF function.
Ignored 'Volatile' PTG_ATTR.
Added INT to table.
* ms-excel.c (ms_excel_set_cell_xf): Made static for safety.
(ms_excelReadWorkbook): BIFF_SST: fixed up a few types.
(biff_get_text): Fixed types.
* ms-excel.h: removed prototype for same.
fixed biff_get_text type.
1999-04-01 Michael Meeks <michael@imaginator.com>
* ms-excel.c (ms_excelReadWorkbook): Major string table fix
......
......@@ -85,6 +85,7 @@ extern void free_ms_biff_bof_data (BIFF_BOF_DATA *data) ;
#define BIFF_RK 0x7e
#define BIFF_BOUNDSHEET 0x85
#define BIFF_PALETTE 0x92
#define BIFF_SHRFMLA 0xbc
#define BIFF_MULRK 0xbd
#define BIFF_MULBLANK 0xbe
#define BIFF_RSTRING 0xd6
......
......@@ -99,7 +99,7 @@ biff_string_get_flags (BYTE *ptr,
* FIXME: see S59D47.HTM for full description
**/
char *
biff_get_text (BYTE *pos, int length, guint32* byte_length)
biff_get_text (BYTE *pos, guint32 length, guint32* byte_length)
{
int lp ;
char *ans;
......@@ -751,7 +751,8 @@ ms_excel_set_cell_colors (MS_EXCEL_SHEET * sheet, Cell * cell, BIFF_XF_DATA * xf
int col;
if (!p || !xf) {
printf ("Internal Error: No palette !\n") ;
if (EXCEL_DEBUG>0)
printf ("Internal Error: No palette !\n") ;
return;
}
......@@ -787,7 +788,7 @@ ms_excel_set_cell_font (MS_EXCEL_SHEET * sheet, Cell * cell, BIFF_XF_DATA * xf)
printf ("Duff StyleFont\n") ;
}
void
static void
ms_excel_set_cell_xf (MS_EXCEL_SHEET * sheet, Cell * cell, guint16 xfidx)
{
GList *ptr;
......@@ -1504,24 +1505,40 @@ ms_excel_read_cell (BIFF_QUERY * q, MS_EXCEL_SHEET * sheet)
}
break;
}
case BIFF_SHRFMLA: /* See: S59DE4.HTM */
case BIFF_ARRAY: /* See: S59D57.HTM */
{
int array_col_first, array_col_last ;
int array_row_first, array_row_last ;
int xlp, ylp ;
BYTE *data ;
int data_len ;
array_row_first = BIFF_GETWORD(q->data + 0) ;
array_row_last = BIFF_GETWORD(q->data + 2) ;
array_col_first = BIFF_GETBYTE(q->data + 4) ;
array_col_last = BIFF_GETBYTE(q->data + 5) ;
printf ("Array Formula of extent %d %d %d %d\n",
switch (q->ls_op) {
case BIFF_SHRFMLA:
data = q->data + 10 ;
data_len = BIFF_GETWORD(q->data + 8) ;
break ;
default:{
/* int options = BIFF_GETWORD(q->data + 6) ; not so useful */
g_assert (q->ls_op == BIFF_ARRAY) ;
data = q->data + 14 ;
data_len = BIFF_GETWORD(q->data + 12) ;
break ;
}
}
printf ("%s Formula of extent %d %d %d %d\n", q->ls_op==BIFF_ARRAY?"Array":"Shrfmla",
array_col_first, array_row_first, array_col_last, array_row_last) ;
for (xlp=array_col_first;xlp<=array_col_last;xlp++)
for (ylp=array_row_first;ylp<=array_row_last;ylp++)
{
char *txt = ms_excel_parse_formula (sheet, (q->data + 14),
xlp, ylp, BIFF_GETWORD(q->data+12)) ;
char *txt = ms_excel_parse_formula (sheet, data,
xlp, ylp, data_len) ;
/* FIXME: Magic XF number: 0 */
ms_excel_sheet_insert (sheet, 0, xlp, ylp, txt) ;
g_free(txt) ;
......@@ -1680,6 +1697,8 @@ ms_excel_read_sheet (MS_EXCEL_SHEET *sheet, BIFF_QUERY * q, MS_EXCEL_WORKBOOK *
printf ("----------------- Sheet -------------\n");
while (ms_biff_query_next (q)){
if (EXCEL_DEBUG>5)
printf ("Opcode : 0x%x\n", q->opcode) ;
switch (q->ls_op){
case BIFF_EOF:
if (q->streamPos == blankSheetPos || sheet->blank)
......@@ -1850,6 +1869,8 @@ ms_excelReadWorkbook (MS_OLE * file)
while (ms_biff_query_next (q))
{
if (EXCEL_DEBUG>5)
printf ("Opcode : 0x%x\n", q->opcode) ;
switch (q->ls_op)
{
case BIFF_BOF:
......@@ -1919,8 +1940,8 @@ ms_excelReadWorkbook (MS_OLE * file)
break;
case BIFF_SST: /* see S59DE7.HTM */
{
int length, k ;
char *tmp ;
guint32 length, k ;
BYTE *tmp ;
if (EXCEL_DEBUG>4) {
printf ("SST\n") ;
......@@ -2002,7 +2023,7 @@ ms_excelReadWorkbook (MS_OLE * file)
dump (q->data, q->length);
break ;
default:
if (EXCEL_DEBUG>0)
if (EXCEL_DEBUG>0 && EXCEL_DEBUG<=5)
printf ("Opcode : 0x%x, length 0x%x\n", q->opcode, q->length);
if (EXCEL_DEBUG>2)
dump (q->data, q->length);
......
......@@ -33,7 +33,6 @@ typedef struct _MS_EXCEL_SHEET
} MS_EXCEL_SHEET ;
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, guint16 xfidx) ;
typedef struct _MS_EXCEL_PALETTE
{
......@@ -92,7 +91,7 @@ typedef struct _MS_EXCEL_WORKBOOK
} MS_EXCEL_WORKBOOK ;
extern char* biff_get_externsheet_name (MS_EXCEL_WORKBOOK *wb, guint16 idx, gboolean get_first) ;
extern char* biff_get_text (BYTE *ptr, int length, guint32 *byte_length) ;
extern char* biff_get_text (BYTE *ptr, guint32 length, guint32 *byte_length) ;
extern char* biff_get_error_text (guint8 err) ;
extern char* biff_name_data_get_name (MS_EXCEL_SHEET *sheet, guint16 idx) ;
#endif
......@@ -99,7 +99,7 @@ biff_string_get_flags (BYTE *ptr,
* FIXME: see S59D47.HTM for full description
**/
char *
biff_get_text (BYTE *pos, int length, guint32* byte_length)
biff_get_text (BYTE *pos, guint32 length, guint32* byte_length)
{
int lp ;
char *ans;
......@@ -751,7 +751,8 @@ ms_excel_set_cell_colors (MS_EXCEL_SHEET * sheet, Cell * cell, BIFF_XF_DATA * xf
int col;
if (!p || !xf) {
printf ("Internal Error: No palette !\n") ;
if (EXCEL_DEBUG>0)
printf ("Internal Error: No palette !\n") ;
return;
}
......@@ -787,7 +788,7 @@ ms_excel_set_cell_font (MS_EXCEL_SHEET * sheet, Cell * cell, BIFF_XF_DATA * xf)
printf ("Duff StyleFont\n") ;
}
void
static void
ms_excel_set_cell_xf (MS_EXCEL_SHEET * sheet, Cell * cell, guint16 xfidx)
{
GList *ptr;
......@@ -1504,24 +1505,40 @@ ms_excel_read_cell (BIFF_QUERY * q, MS_EXCEL_SHEET * sheet)
}
break;
}
case BIFF_SHRFMLA: /* See: S59DE4.HTM */
case BIFF_ARRAY: /* See: S59D57.HTM */
{
int array_col_first, array_col_last ;
int array_row_first, array_row_last ;
int xlp, ylp ;
BYTE *data ;
int data_len ;
array_row_first = BIFF_GETWORD(q->data + 0) ;
array_row_last = BIFF_GETWORD(q->data + 2) ;
array_col_first = BIFF_GETBYTE(q->data + 4) ;
array_col_last = BIFF_GETBYTE(q->data + 5) ;
printf ("Array Formula of extent %d %d %d %d\n",
switch (q->ls_op) {
case BIFF_SHRFMLA:
data = q->data + 10 ;
data_len = BIFF_GETWORD(q->data + 8) ;
break ;
default:{
/* int options = BIFF_GETWORD(q->data + 6) ; not so useful */
g_assert (q->ls_op == BIFF_ARRAY) ;
data = q->data + 14 ;
data_len = BIFF_GETWORD(q->data + 12) ;
break ;
}
}
printf ("%s Formula of extent %d %d %d %d\n", q->ls_op==BIFF_ARRAY?"Array":"Shrfmla",
array_col_first, array_row_first, array_col_last, array_row_last) ;
for (xlp=array_col_first;xlp<=array_col_last;xlp++)
for (ylp=array_row_first;ylp<=array_row_last;ylp++)
{
char *txt = ms_excel_parse_formula (sheet, (q->data + 14),
xlp, ylp, BIFF_GETWORD(q->data+12)) ;
char *txt = ms_excel_parse_formula (sheet, data,
xlp, ylp, data_len) ;
/* FIXME: Magic XF number: 0 */
ms_excel_sheet_insert (sheet, 0, xlp, ylp, txt) ;
g_free(txt) ;
......@@ -1680,6 +1697,8 @@ ms_excel_read_sheet (MS_EXCEL_SHEET *sheet, BIFF_QUERY * q, MS_EXCEL_WORKBOOK *
printf ("----------------- Sheet -------------\n");
while (ms_biff_query_next (q)){
if (EXCEL_DEBUG>5)
printf ("Opcode : 0x%x\n", q->opcode) ;
switch (q->ls_op){
case BIFF_EOF:
if (q->streamPos == blankSheetPos || sheet->blank)
......@@ -1850,6 +1869,8 @@ ms_excelReadWorkbook (MS_OLE * file)
while (ms_biff_query_next (q))
{
if (EXCEL_DEBUG>5)
printf ("Opcode : 0x%x\n", q->opcode) ;
switch (q->ls_op)
{
case BIFF_BOF:
......@@ -1919,8 +1940,8 @@ ms_excelReadWorkbook (MS_OLE * file)
break;
case BIFF_SST: /* see S59DE7.HTM */
{
int length, k ;
char *tmp ;
guint32 length, k ;
BYTE *tmp ;
if (EXCEL_DEBUG>4) {
printf ("SST\n") ;
......@@ -2002,7 +2023,7 @@ ms_excelReadWorkbook (MS_OLE * file)
dump (q->data, q->length);
break ;
default:
if (EXCEL_DEBUG>0)
if (EXCEL_DEBUG>0 && EXCEL_DEBUG<=5)
printf ("Opcode : 0x%x, length 0x%x\n", q->opcode, q->length);
if (EXCEL_DEBUG>2)
dump (q->data, q->length);
......
......@@ -33,7 +33,6 @@ typedef struct _MS_EXCEL_SHEET
} MS_EXCEL_SHEET ;
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, guint16 xfidx) ;
typedef struct _MS_EXCEL_PALETTE
{
......@@ -92,7 +91,7 @@ typedef struct _MS_EXCEL_WORKBOOK
} MS_EXCEL_WORKBOOK ;
extern char* biff_get_externsheet_name (MS_EXCEL_WORKBOOK *wb, guint16 idx, gboolean get_first) ;
extern char* biff_get_text (BYTE *ptr, int length, guint32 *byte_length) ;
extern char* biff_get_text (BYTE *ptr, guint32 length, guint32 *byte_length) ;
extern char* biff_get_error_text (guint8 err) ;
extern char* biff_name_data_get_name (MS_EXCEL_SHEET *sheet, guint16 idx) ;
#endif
......@@ -18,6 +18,8 @@
#include "ms-excel-biff.h"
#include "ms-formula.h"
#define FORMULA_DEBUG 0
#define NO_PRECEDENCE 256
/**
......@@ -58,7 +60,7 @@ FORMULA_OP_DATA formula_op_data[] = {
FORMULA_FUNC_DATA formula_func_data[] =
{
{ "COUNT", 2 },
{ "IF", 8 },
{ "IF", -1 },
{ "ISNA", 1 },
{ "ISERROR", 1 },
{ "SUM", -1 },
......@@ -81,8 +83,8 @@ FORMULA_FUNC_DATA formula_func_data[] =
{ "EXP", 1 },
{ "LN", 1 },
{ "LOG10", 1 },
{ "0x18", 8 },
{ "0x19", 8 },
{ "ABS", 1 },
{ "INT", 1 },
{ "SIGN", 1 },
{ "0x1b", 8 },
{ "0x1c", 8 },
......@@ -424,7 +426,8 @@ FORMULA_FUNC_DATA formula_func_data[] =
* A useful routine for extracting data from a common
* storage structure.
**/
static CellRef *getRefV7(MS_EXCEL_SHEET *sheet, BYTE col, WORD gbitrw, int curcol, int currow)
static CellRef *
getRefV7(MS_EXCEL_SHEET *sheet, BYTE col, WORD gbitrw, int curcol, int currow)
{
CellRef *cr = (CellRef *)g_malloc(sizeof(CellRef)) ;
cr->col = col ;
......@@ -443,7 +446,8 @@ static CellRef *getRefV7(MS_EXCEL_SHEET *sheet, BYTE col, WORD gbitrw, int curco
* A useful routine for extracting data from a common
* storage structure.
**/
static CellRef *getRefV8(MS_EXCEL_SHEET *sheet, WORD row, WORD gbitcl, int curcol, int currow)
static CellRef *
getRefV8(MS_EXCEL_SHEET *sheet, WORD row, WORD gbitcl, int curcol, int currow)
{
CellRef *cr = (CellRef *)g_malloc(sizeof(CellRef)) ;
cr->row = row ;
......@@ -465,7 +469,8 @@ typedef struct _PARSE_DATA
int precedence ;
} PARSE_DATA ;
static PARSE_DATA *parse_data_new (char *buffer, int precedence)
static PARSE_DATA *
parse_data_new (char *buffer, int precedence)
{
PARSE_DATA *ans = g_new (PARSE_DATA, 1) ;
if (!buffer)
......@@ -476,7 +481,8 @@ static PARSE_DATA *parse_data_new (char *buffer, int precedence)
return ans ;
}
static void parse_data_free (PARSE_DATA *ptr)
static void
parse_data_free (PARSE_DATA *ptr)
{
if (ptr->name)
g_free (ptr->name) ;
......@@ -489,7 +495,8 @@ typedef struct _PARSE_LIST
int length ;
} PARSE_LIST ;
static PARSE_LIST *parse_list_new ()
static PARSE_LIST *
parse_list_new ()
{
PARSE_LIST *ans = (PARSE_LIST *)g_malloc (sizeof(PARSE_LIST)) ;
ans->data = 0 ;
......@@ -497,19 +504,23 @@ static PARSE_LIST *parse_list_new ()
return ans ;
}
static void parse_list_push (PARSE_LIST *list, PARSE_DATA *pd)
static void
parse_list_push (PARSE_LIST *list, PARSE_DATA *pd)
{
/* printf ("Pushing '%s'\n", pd->name) ; */
if (FORMULA_DEBUG>0)
printf ("Pushing '%s'\n", pd->name) ;
list->data = g_list_append (list->data, pd) ;
list->length++ ;
}
static void parse_list_push_raw (PARSE_LIST *list, char *buffer, int precedence)
static void
parse_list_push_raw (PARSE_LIST *list, char *buffer, int precedence)
{
parse_list_push(list, parse_data_new (buffer, precedence)) ;
}
static PARSE_DATA *parse_list_pop (PARSE_LIST *list)
static PARSE_DATA *
parse_list_pop (PARSE_LIST *list)
{
GList *tmp ;
PARSE_DATA *ans ;
......@@ -523,7 +534,8 @@ static PARSE_DATA *parse_list_pop (PARSE_LIST *list)
return ans ;
}
static void parse_list_free (PARSE_LIST *list)
static void
parse_list_free (PARSE_LIST *list)
{
while (list->data)
parse_data_free (parse_list_pop(list)) ;
......@@ -591,7 +603,8 @@ static char *parse_list_to_equation (PARSE_LIST *list)
strcpy (formula, "=") ;
strcat (formula, pd->name) ;
/* printf ("Formula : '%s'\n", formula) ; */
if (FORMULA_DEBUG>1)
printf ("Formula : '%s'\n", formula) ;
return formula ;
}
else
......@@ -715,6 +728,8 @@ char *ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, guint8 *mem,
int ptgbase = ((ptg & 0x40) ? (ptg | 0x20): ptg) & 0x3F ;
if (ptg > FORMULA_PTG_MAX)
break ;
if (FORMULA_DEBUG>0)
printf ("Ptg : 0x%x -> 0x%x\n", ptg, ptgbase) ;
switch (ptgbase)
{
case FORMULA_PTG_REF:
......@@ -925,23 +940,45 @@ char *ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, guint8 *mem,
guint8 grbit = BIFF_GETBYTE(cur) ;
guint16 w = BIFF_GETWORD(cur+1) ;
ptg_length = 3 ;
if (grbit & 0x40) /* AttrSpace */
{
guint8 num_space = BIFF_GETBYTE(cur+2) ;
guint8 attrs = BIFF_GETBYTE(cur+1) ;
if (attrs == 00) /* bitFSpace : ignore it */
/* Could perhaps pop top arg & append space ? */ ;
if (grbit & 0x01) {
if (FORMULA_DEBUG>0)
printf ("A volatile function: so what\n") ;
} else if (grbit & 0x02) { /* AttrIf: 'optimised' IF function */
/* Who cares if the TRUE expr has a goto at the end */
char *txt ;
printf ("Optimised IF 0x%x 0x%x\n", grbit, w) ;
dump (mem, length) ;
if (w)
txt = ms_excel_parse_formula (sheet, cur+ptg_length,
fn_col, fn_row, w) ;
else
printf ("Redundant whitespace in formula 0x%x count %d\n", attrs, num_space) ;
}
if (grbit & 0x10) { /* AttrSum: Optimised SUM function */
txt = g_strdup(" ") ;
txt[0] = ' ' ; /* Kill the = */
parse_list_push_raw (stack, txt, NO_PRECEDENCE) ;
ptg_length += w ;
} else if (grbit & 0x08) { /* AttrGoto */
if (FORMULA_DEBUG>2) {
printf ("Goto %d: cur = 0x%x\n", w, (int)(cur-mem)) ;
dump (mem, length) ;
}
ptg_length = w ;
} else if (grbit & 0x10) { /* AttrSum: 'optimised' SUM function */
if (!make_function (stack, 0x04, 1))
{
error = 1 ;
printf ("Error in optimised SUM\n") ;
}
} else
} else if (grbit & 0x40) { /* AttrSpace */
guint8 num_space = BIFF_GETBYTE(cur+2) ;
guint8 attrs = BIFF_GETBYTE(cur+1) ;
if (attrs == 00) /* bitFSpace : ignore it */
/* Could perhaps pop top arg & append space ? */ ;
else
printf ("Redundant whitespace in formula 0x%x count %d\n", attrs, num_space) ;
} else {
printf ("Unknown PTG Attr 0x%x 0x%x\n", grbit, w) ;
error = 1 ;
}
break ;
}
case FORMULA_PTG_ERR:
......
......@@ -18,6 +18,8 @@
#include "ms-excel-biff.h"
#include "ms-formula.h"
#define FORMULA_DEBUG 0
#define NO_PRECEDENCE 256
/**
......@@ -58,7 +60,7 @@ FORMULA_OP_DATA formula_op_data[] = {
FORMULA_FUNC_DATA formula_func_data[] =
{
{ "COUNT", 2 },
{ "IF", 8 },
{ "IF", -1 },
{ "ISNA", 1 },
{ "ISERROR", 1 },
{ "SUM", -1 },
......@@ -81,8 +83,8 @@ FORMULA_FUNC_DATA formula_func_data[] =
{ "EXP", 1 },
{ "LN", 1 },
{ "LOG10", 1 },
{ "0x18", 8 },
{ "0x19", 8 },
{ "ABS", 1 },
{ "INT", 1 },
{ "SIGN", 1 },
{ "0x1b", 8 },
{ "0x1c", 8 },
......@@ -424,7 +426,8 @@ FORMULA_FUNC_DATA formula_func_data[] =
* A useful routine for extracting data from a common
* storage structure.
**/
static CellRef *getRefV7(MS_EXCEL_SHEET *sheet, BYTE col, WORD gbitrw, int curcol, int currow)
static CellRef *
getRefV7(MS_EXCEL_SHEET *sheet, BYTE col, WORD gbitrw, int curcol, int currow)
{
CellRef *cr = (CellRef *)g_malloc(sizeof(CellRef)) ;
cr->col = col ;
......@@ -443,7 +446,8 @@ static CellRef *getRefV7(MS_EXCEL_SHEET *sheet, BYTE col, WORD gbitrw, int curco
* A useful routine for extracting data from a common
* storage structure.
**/
static CellRef *getRefV8(MS_EXCEL_SHEET *sheet, WORD row, WORD gbitcl, int curcol, int currow)
static CellRef *
getRefV8(MS_EXCEL_SHEET *sheet, WORD row, WORD gbitcl, int curcol, int currow)
{
CellRef *cr = (CellRef *)g_malloc(sizeof(CellRef)) ;
cr->row = row ;
......@@ -465,7 +469,8 @@ typedef struct _PARSE_DATA
int precedence ;
} PARSE_DATA ;
static PARSE_DATA *parse_data_new (char *buffer, int precedence)
static PARSE_DATA *
parse_data_new (char *buffer, int precedence)
{
PARSE_DATA *ans = g_new (PARSE_DATA, 1) ;
if (!buffer)
......@@ -476,7 +481,8 @@ static PARSE_DATA *parse_data_new (char *buffer, int precedence)
return ans ;
}
static void parse_data_free (PARSE_DATA *ptr)
static void
parse_data_free (PARSE_DATA *ptr)
{
if (ptr->name)
g_free (ptr->name) ;
......@@ -489,7 +495,8 @@ typedef struct _PARSE_LIST
int length ;
} PARSE_LIST ;
static PARSE_LIST *parse_list_new ()
static PARSE_LIST *
parse_list_new ()
{
PARSE_LIST *ans = (PARSE_LIST *)g_malloc (sizeof(PARSE_LIST)) ;
ans->data = 0 ;
......@@ -497,19 +504,23 @@ static PARSE_LIST *parse_list_new ()
return ans ;
}
static void parse_list_push (PARSE_LIST *list, PARSE_DATA *pd)
static void
parse_list_push (PARSE_LIST *list, PARSE_DATA *pd)
{
/* printf ("Pushing '%s'\n", pd->name) ; */
if (FORMULA_DEBUG>0)
printf ("Pushing '%s'\n", pd->name) ;
list->data = g_list_append (list->data, pd) ;
list->length++ ;
}
static void parse_list_push_raw (PARSE_LIST *list, char *buffer, int precedence)
static void
parse_list_push_raw (PARSE_LIST *list, char *buffer, int precedence)
{
parse_list_push(list, parse_data_new (buffer, precedence)) ;
}
static PARSE_DATA *parse_list_pop (PARSE_LIST *list)
static PARSE_DATA *
parse_list_pop (PARSE_LIST *list)
{
GList *tmp ;
PARSE_DATA *ans ;
......@@ -523,7 +534,8 @@ static PARSE_DATA *parse_list_pop (PARSE_LIST *list)
return ans ;
}
static void parse_list_free (PARSE_LIST *list)
static void
parse_list_free (PARSE_LIST *list)
{
while (list->data)
parse_data_free (parse_list_pop(list)) ;
......@@ -591,7 +603,8 @@ static char *parse_list_to_equation (PARSE_LIST *list)
strcpy (formula, "=") ;
strcat (formula, pd->name) ;
/* printf ("Formula : '%s'\n", formula) ; */
if (FORMULA_DEBUG>1)
printf ("Formula : '%s'\n", formula) ;
return formula ;
}
else
......@@ -715,6 +728,8 @@ char *ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, guint8 *mem,
int ptgbase = ((ptg & 0x40) ? (ptg | 0x20): ptg) & 0x3F ;
if (ptg > FORMULA_PTG_MAX)
break ;
if (FORMULA_DEBUG>0)
printf ("Ptg : 0x%x -> 0x%x\n", ptg, ptgbase) ;
switch (ptgbase)
{
case FORMULA_PTG_REF:
......@@ -925,23 +940,45 @@ char *ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, guint8 *mem,
guint8 grbit = BIFF_GETBYTE(cur) ;
guint16 w = BIFF_GETWORD(cur+1) ;
ptg_length = 3 ;
if (grbit & 0x40) /* AttrSpace */
{
guint8 num_space = BIFF_GETBYTE(cur+2) ;
guint8 attrs = BIFF_GETBYTE(cur+1) ;
if (attrs == 00) /* bitFSpace : ignore it */
/* Could perhaps pop top arg & append space ? */ ;
if (grbit & 0x01) {
if (FORMULA_DEBUG>0)
printf ("A volatile function: so what\n") ;
} else if (grbit & 0x02) { /* AttrIf: 'optimised' IF function */
/* Who cares if the TRUE expr has a goto at the end */
char *txt ;
printf ("Optimised IF 0x%x 0x%x\n", grbit, w) ;
dump (mem, length) ;
if (w)
txt = ms_excel_parse_formula (sheet, cur+ptg_length,
fn_col, fn_row, w) ;
else
printf ("Redundant whitespace in formula 0x%x count %d\n", attrs, num_space) ;
}
if (grbit & 0x10) { /* AttrSum: Optimised SUM function */
txt = g_strdup(" ") ;
txt[0] = ' ' ; /* Kill the = */
parse_list_push_raw (stack, txt, NO_PRECEDENCE) ;
ptg_length += w ;
} else if (grbit & 0x08) { /* AttrGoto */
if (FORMULA_DEBUG>2) {
printf ("Goto %d: cur = 0x%x\n", w, (int)(cur-mem)) ;
dump (mem, length) ;
}
ptg_length = w ;
} else if (grbit & 0x10) { /* AttrSum: 'optimised' SUM function */
if (!make_function (stack, 0x04, 1))
{
error = 1 ;
printf ("Error in optimised SUM\n") ;
}
} else
} else if (grbit & 0x40) { /* AttrSpace */
guint8 num_space = BIFF_GETBYTE(cur+2) ;
guint8 attrs = BIFF_GETBYTE(cur+1) ;
if (attrs == 00) /* bitFSpace : ignore it */
/* Could perhaps pop top arg & append space ? */ ;
else
printf ("Redundant whitespace in formula 0x%x count %d\n", attrs, num_space) ;
} else {
printf ("Unknown PTG Attr 0x%x 0x%x\n", grbit, w) ;
error = 1 ;
}
break ;
}
case FORMULA_PTG_ERR:
......
......@@ -15,13 +15,14 @@
static char *help_if = {
N_("@FUNCTION=IF\n"
"@SYNTAX=IF(condition,if-true,if-false)\n"
"@SYNTAX=IF(condition[,if-true,if-false])\n"
"@DESCRIPTION="
"Use the IF statement to evaluate conditionally other expressions "
"IF evaluates @condition. If @condition returns a non-zero value "
"the result of the IF expression is the @if-true expression, otherwise "
"IF evaluates to the value of @if-false"
"IF evaluates to the value of @if-false."
"If ommitted if-true defaults to TRUE and if-false to FALSE."
"\n"
"@SEEALSO=")
};
......@@ -31,10 +32,11 @@ gnumeric_if (void *tsheet, GList *expr_node_list, int eval_col, int eval_row, ch
{
ExprTree *expr;
Value *value;
int err, ret;
int err, ret, args;
/* Type checking */
if (g_list_length (expr_node_list) != 3){
args = g_list_length (expr_node_list) ;
if (args < 1 || args > 3) {
*error_string = _("Invalid number of arguments");
return NULL;
}
......@@ -46,15 +48,22 @@ gnumeric_if (void *tsheet, GList *expr_node_list, int eval_col, int eval_row, ch
/* Choose which expression we will evaluate */
ret = value_get_bool (value, &err);
value_release (value);
if (err)
return NULL;
if (ret)
expr = (ExprTree *) expr_node_list->next->data;
else
expr = (ExprTree *) expr_node_list->next->next->data;
value_release (value);