Commit 6058dd50 authored by Michael Meeks's avatar Michael Meeks
Browse files

Excel plugin formula support

parent 89b125a7
1999-03-12 Michael Meeks <michael@imaginator.com>
* ms-excel.c (biff_name_data_new, biff_name_data_get_name),
(biff_name_data_destroy, ms_excel_read_cell): Implemented
the BIFF_EXTERNNAME case.
(ms_excel_workbook_new, ms_excel_workbook_destroy):
Name table hashing functions.
(ms_excel_read_cell): Cleaned debug on BIFF_HEADER / FOOTER.
* ms-formula.c (ms_excel_parse_formula): Large API change to
simplify several cases, and clean dirty code.
(make_function): Special 0xff case on functions. For use with
external functions, the names of which come in via:
(_excel_parse_formula): FORMULA_PTG_NAME_X, hacked into
rough shape.
* ms-excel.c: All instances of ms_excel_parse_formula updated.
1999-03-11 Michael Meeks <michael@imaginator.com>
* ms-ole.c (ms_ole_destroy, ms_ole_new): Killed debug
......
......@@ -76,6 +76,7 @@ extern void free_ms_biff_bof_data (BIFF_BOF_DATA *data) ;
#define BIFF_EXTERNSHEET 0x17
#define BIFF_FORMAT 0x1e
#define BIFF_ARRAY 0x21
#define BIFF_EXTERNNAME 0x23
#define BIFF_FONT 0x31
#define BIFF_XF_OLD 0x43
......@@ -99,3 +100,4 @@ extern void free_ms_biff_bof_data (BIFF_BOF_DATA *data) ;
#define BIFF_STRING 0x207
#define BIFF_NAME 0x218
#endif
......@@ -562,6 +562,54 @@ biff_format_data_destroy (gpointer key, BIFF_FORMAT_DATA *d, gpointer userdata)
return 1 ;
}
typedef struct {
guint16 idx ;
char *name ;
guint8 *formula ;
guint16 formula_len ;
} BIFF_NAME_DATA ;
/**
* A copy of name is kept but
* formula is g_malloc'd and copied
**/
static void
biff_name_data_new (MS_EXCEL_SHEET *sheet, char *name, guint8 *formula, guint16 len)
{
BIFF_NAME_DATA *bnd = g_new (BIFF_NAME_DATA, 1) ;
bnd->idx = g_hash_table_size (sheet->wb->name_data) + 1 ;
bnd->name = name ;
if (formula) {
bnd->formula = g_new (guint8, len) ;
memcpy (bnd->formula, formula, len) ;
bnd->formula_len = len ;
} else {
bnd->formula = 0 ;
bnd->formula_len = 0 ;
}
g_hash_table_insert (sheet->wb->name_data, &bnd->idx, bnd) ;
/* printf ("Inserting '%s' into externname table at (%d)\n", bnd->name, bnd->idx) ; */
}
char *
biff_name_data_get_name (MS_EXCEL_SHEET *sheet, guint16 idx)
{
BIFF_NAME_DATA *ptr = g_hash_table_lookup (sheet->wb->name_data, &idx) ;
if (ptr)
return ptr->name ;
else
return 0 ;
}
static gboolean
biff_name_data_destroy (gpointer key, BIFF_NAME_DATA *bnd, gpointer userdata)
{
g_free (bnd->name) ;
g_free (bnd->formula) ;
g_free (bnd) ;
return 1 ;
}
static MS_EXCEL_PALETTE *
ms_excel_palette_new (BIFF_QUERY * q)
{
......@@ -1081,6 +1129,8 @@ ms_excel_workbook_new ()
(GCompareFunc)biff_guint16_equal) ;
ans->format_data = g_hash_table_new ((GHashFunc)biff_guint16_hash,
(GCompareFunc)biff_guint16_equal) ;
ans->name_data = g_hash_table_new ((GHashFunc)biff_guint16_hash,
(GCompareFunc)biff_guint16_equal) ;
ans->palette = NULL;
ans->global_strings = NULL;
ans->global_string_max = 0;
......@@ -1162,7 +1212,12 @@ ms_excel_workbook_destroy (MS_EXCEL_WORKBOOK * wb)
g_hash_table_foreach_remove (wb->format_data,
(GHRFunc)biff_format_data_destroy,
wb) ;
g_hash_table_destroy (wb->font_data) ;
g_hash_table_destroy (wb->format_data) ;
g_hash_table_foreach_remove (wb->name_data,
(GHRFunc)biff_name_data_destroy,
wb) ;
g_hash_table_destroy (wb->name_data) ;
if (wb->palette)
ms_excel_palette_destroy (wb->palette);
......@@ -1268,9 +1323,11 @@ ms_excel_read_cell (BIFF_QUERY * q, MS_EXCEL_SHEET * sheet)
char *str ;
if (q->length)
{
printf ("Header '%s'\n", (str=biff_get_text (q->data+1,
BIFF_GETBYTE(q->data)))) ;
g_free(str) ;
if (EXCEL_DEBUG>0) {
printf ("Header '%s'\n", (str=biff_get_text (q->data+1,
BIFF_GETBYTE(q->data)))) ;
g_free(str) ;
}
}
break;
}
......@@ -1279,9 +1336,11 @@ ms_excel_read_cell (BIFF_QUERY * q, MS_EXCEL_SHEET * sheet)
char *str ;
if (q->length)
{
printf ("Footer '%s'\n", (str=biff_get_text (q->data+1,
if (EXCEL_DEBUG>0) {
printf ("Footer '%s'\n", (str=biff_get_text (q->data+1,
BIFF_GETBYTE(q->data)))) ;
g_free(str) ;
g_free(str) ;
}
}
break;
}
......@@ -1384,7 +1443,7 @@ ms_excel_read_cell (BIFF_QUERY * q, MS_EXCEL_SHEET * sheet)
/* printf ("Row %d formatting 0x%x\n", BIFF_GETWORD(q->data), height); */
if ((height&0x8000) == 0) /* Fudge Factor */
{
printf ("Row height : %f points\n", BIFF_GETWORD(q->data+6)/20.0) ;
/* printf ("Row height : %f points\n", BIFF_GETWORD(q->data+6)/20.0) ;*/
sheet_row_set_height (sheet->gnum_sheet, BIFF_GETWORD(q->data), BIFF_GETWORD(q->data+6)/15, TRUE) ;
}
break;
......@@ -1403,12 +1462,24 @@ ms_excel_read_cell (BIFF_QUERY * q, MS_EXCEL_SHEET * sheet)
printf ("Array Formula\n") ;
for (xlp=array_col_first;xlp<=array_col_last;xlp++)
for (ylp=array_row_first;ylp<=array_row_last;ylp++)
ms_excel_parse_formula (sheet, q, xlp, ylp);
{
char *txt = ms_excel_parse_formula (sheet, (q->data + 14),
xlp, ylp, BIFF_GETWORD(q->data+12)) ;
/* FIXME: Magic XF number: 0 */
ms_excel_sheet_insert (sheet, 0, xlp, ylp, txt) ;
g_free(txt) ;
}
break ;
}
case BIFF_FORMULA: /* See: S59D8F.HTM */
ms_excel_parse_formula (sheet, q, EX_GETCOL (q), EX_GETROW (q));
{
char *txt = ms_excel_parse_formula (sheet, (q->data + 22),
EX_GETCOL (q), EX_GETROW (q),
BIFF_GETWORD(q->data+20));
ms_excel_sheet_insert (sheet, EX_GETXF(q), EX_GETCOL(q), EX_GETROW(q), txt) ;
g_free (txt) ;
break;
}
case BIFF_LABELSST:
{
char *str;
......@@ -1423,6 +1494,38 @@ ms_excel_read_cell (BIFF_QUERY * q, MS_EXCEL_SHEET * sheet)
}
break;
}
case BIFF_EXTERNNAME: /* FIXME: S59D7E.HTM */
{
char *externname ;
if ( sheet->ver >= eBiffV7) {
guint16 options = BIFF_GETWORD(q->data) ;
guint8 namelen = BIFF_GETBYTE(q->data+6) ;
guint16 defnlen = BIFF_GETWORD(q->data + 7 + namelen) ;
char *definition = 0 ;
externname = biff_get_text (q->data+7, namelen) ;
if ((options & 0xffe0) != 0) {
printf ("Duff externname\n") ; break ;
}
if ((options & 0x0001) != 0)
printf ("fBuiltin\n") ;
/* Copy the definition to storage to parse at run-time in the formula */
biff_name_data_new (sheet, externname, definition, defnlen) ;
} else { /* Ancient Papyrus spec. */
guint8 data[] = { 0x1c, 0x17 } ;
printf ("Externname Data:\n") ;
dump (q->data, q->length) ;
externname = biff_get_text (q->data+1, BIFF_GETBYTE(q->data)) ;
biff_name_data_new (sheet, externname, data, 2) ;
}
if (EXCEL_DEBUG>1)
{
printf ("Externname '%s'\n", externname) ;
dump (q->data, q->length) ;
}
break ;
}
default:
switch (q->opcode)
{
......
......@@ -77,6 +77,7 @@ typedef struct _MS_EXCEL_WORKBOOK
GHashTable *XF_style_records ;
GHashTable *font_data ;
GHashTable *format_data ;
GHashTable *name_data ;
GList *excel_sheets ;
BIFF_EXTERNSHEET_DATA *extern_sheets ;
guint16 num_extern_sheets ;
......@@ -93,4 +94,5 @@ typedef struct _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) ;
extern char* biff_get_error_text (guint8 err) ;
extern char* biff_name_data_get_name (MS_EXCEL_SHEET *sheet, guint16 idx) ;
#endif
......@@ -562,6 +562,54 @@ biff_format_data_destroy (gpointer key, BIFF_FORMAT_DATA *d, gpointer userdata)
return 1 ;
}
typedef struct {
guint16 idx ;
char *name ;
guint8 *formula ;
guint16 formula_len ;
} BIFF_NAME_DATA ;
/**
* A copy of name is kept but
* formula is g_malloc'd and copied
**/
static void
biff_name_data_new (MS_EXCEL_SHEET *sheet, char *name, guint8 *formula, guint16 len)
{
BIFF_NAME_DATA *bnd = g_new (BIFF_NAME_DATA, 1) ;
bnd->idx = g_hash_table_size (sheet->wb->name_data) + 1 ;
bnd->name = name ;
if (formula) {
bnd->formula = g_new (guint8, len) ;
memcpy (bnd->formula, formula, len) ;
bnd->formula_len = len ;
} else {
bnd->formula = 0 ;
bnd->formula_len = 0 ;
}
g_hash_table_insert (sheet->wb->name_data, &bnd->idx, bnd) ;
/* printf ("Inserting '%s' into externname table at (%d)\n", bnd->name, bnd->idx) ; */
}
char *
biff_name_data_get_name (MS_EXCEL_SHEET *sheet, guint16 idx)
{
BIFF_NAME_DATA *ptr = g_hash_table_lookup (sheet->wb->name_data, &idx) ;
if (ptr)
return ptr->name ;
else
return 0 ;
}
static gboolean
biff_name_data_destroy (gpointer key, BIFF_NAME_DATA *bnd, gpointer userdata)
{
g_free (bnd->name) ;
g_free (bnd->formula) ;
g_free (bnd) ;
return 1 ;
}
static MS_EXCEL_PALETTE *
ms_excel_palette_new (BIFF_QUERY * q)
{
......@@ -1081,6 +1129,8 @@ ms_excel_workbook_new ()
(GCompareFunc)biff_guint16_equal) ;
ans->format_data = g_hash_table_new ((GHashFunc)biff_guint16_hash,
(GCompareFunc)biff_guint16_equal) ;
ans->name_data = g_hash_table_new ((GHashFunc)biff_guint16_hash,
(GCompareFunc)biff_guint16_equal) ;
ans->palette = NULL;
ans->global_strings = NULL;
ans->global_string_max = 0;
......@@ -1162,7 +1212,12 @@ ms_excel_workbook_destroy (MS_EXCEL_WORKBOOK * wb)
g_hash_table_foreach_remove (wb->format_data,
(GHRFunc)biff_format_data_destroy,
wb) ;
g_hash_table_destroy (wb->font_data) ;
g_hash_table_destroy (wb->format_data) ;
g_hash_table_foreach_remove (wb->name_data,
(GHRFunc)biff_name_data_destroy,
wb) ;
g_hash_table_destroy (wb->name_data) ;
if (wb->palette)
ms_excel_palette_destroy (wb->palette);
......@@ -1268,9 +1323,11 @@ ms_excel_read_cell (BIFF_QUERY * q, MS_EXCEL_SHEET * sheet)
char *str ;
if (q->length)
{
printf ("Header '%s'\n", (str=biff_get_text (q->data+1,
BIFF_GETBYTE(q->data)))) ;
g_free(str) ;
if (EXCEL_DEBUG>0) {
printf ("Header '%s'\n", (str=biff_get_text (q->data+1,
BIFF_GETBYTE(q->data)))) ;
g_free(str) ;
}
}
break;
}
......@@ -1279,9 +1336,11 @@ ms_excel_read_cell (BIFF_QUERY * q, MS_EXCEL_SHEET * sheet)
char *str ;
if (q->length)
{
printf ("Footer '%s'\n", (str=biff_get_text (q->data+1,
if (EXCEL_DEBUG>0) {
printf ("Footer '%s'\n", (str=biff_get_text (q->data+1,
BIFF_GETBYTE(q->data)))) ;
g_free(str) ;
g_free(str) ;
}
}
break;
}
......@@ -1384,7 +1443,7 @@ ms_excel_read_cell (BIFF_QUERY * q, MS_EXCEL_SHEET * sheet)
/* printf ("Row %d formatting 0x%x\n", BIFF_GETWORD(q->data), height); */
if ((height&0x8000) == 0) /* Fudge Factor */
{
printf ("Row height : %f points\n", BIFF_GETWORD(q->data+6)/20.0) ;
/* printf ("Row height : %f points\n", BIFF_GETWORD(q->data+6)/20.0) ;*/
sheet_row_set_height (sheet->gnum_sheet, BIFF_GETWORD(q->data), BIFF_GETWORD(q->data+6)/15, TRUE) ;
}
break;
......@@ -1403,12 +1462,24 @@ ms_excel_read_cell (BIFF_QUERY * q, MS_EXCEL_SHEET * sheet)
printf ("Array Formula\n") ;
for (xlp=array_col_first;xlp<=array_col_last;xlp++)
for (ylp=array_row_first;ylp<=array_row_last;ylp++)
ms_excel_parse_formula (sheet, q, xlp, ylp);
{
char *txt = ms_excel_parse_formula (sheet, (q->data + 14),
xlp, ylp, BIFF_GETWORD(q->data+12)) ;
/* FIXME: Magic XF number: 0 */
ms_excel_sheet_insert (sheet, 0, xlp, ylp, txt) ;
g_free(txt) ;
}
break ;
}
case BIFF_FORMULA: /* See: S59D8F.HTM */
ms_excel_parse_formula (sheet, q, EX_GETCOL (q), EX_GETROW (q));
{
char *txt = ms_excel_parse_formula (sheet, (q->data + 22),
EX_GETCOL (q), EX_GETROW (q),
BIFF_GETWORD(q->data+20));
ms_excel_sheet_insert (sheet, EX_GETXF(q), EX_GETCOL(q), EX_GETROW(q), txt) ;
g_free (txt) ;
break;
}
case BIFF_LABELSST:
{
char *str;
......@@ -1423,6 +1494,38 @@ ms_excel_read_cell (BIFF_QUERY * q, MS_EXCEL_SHEET * sheet)
}
break;
}
case BIFF_EXTERNNAME: /* FIXME: S59D7E.HTM */
{
char *externname ;
if ( sheet->ver >= eBiffV7) {
guint16 options = BIFF_GETWORD(q->data) ;
guint8 namelen = BIFF_GETBYTE(q->data+6) ;
guint16 defnlen = BIFF_GETWORD(q->data + 7 + namelen) ;
char *definition = 0 ;
externname = biff_get_text (q->data+7, namelen) ;
if ((options & 0xffe0) != 0) {
printf ("Duff externname\n") ; break ;
}
if ((options & 0x0001) != 0)
printf ("fBuiltin\n") ;
/* Copy the definition to storage to parse at run-time in the formula */
biff_name_data_new (sheet, externname, definition, defnlen) ;
} else { /* Ancient Papyrus spec. */
guint8 data[] = { 0x1c, 0x17 } ;
printf ("Externname Data:\n") ;
dump (q->data, q->length) ;
externname = biff_get_text (q->data+1, BIFF_GETBYTE(q->data)) ;
biff_name_data_new (sheet, externname, data, 2) ;
}
if (EXCEL_DEBUG>1)
{
printf ("Externname '%s'\n", externname) ;
dump (q->data, q->length) ;
}
break ;
}
default:
switch (q->opcode)
{
......
......@@ -77,6 +77,7 @@ typedef struct _MS_EXCEL_WORKBOOK
GHashTable *XF_style_records ;
GHashTable *font_data ;
GHashTable *format_data ;
GHashTable *name_data ;
GList *excel_sheets ;
BIFF_EXTERNSHEET_DATA *extern_sheets ;
guint16 num_extern_sheets ;
......@@ -93,4 +94,5 @@ typedef struct _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) ;
extern char* biff_get_error_text (guint8 err) ;
extern char* biff_name_data_get_name (MS_EXCEL_SHEET *sheet, guint16 idx) ;
#endif
......@@ -215,6 +215,7 @@ FORMULA_FUNC_DATA formula_func_data[] =
{ 0xea, "ATANH (", 0, ")", 1, 0 },
{ 0xf4, "INFO (", 0, ")", 1, 0 },
{ 0xfc, "FREQUENCY (", 0, ")", 2, 0 },
{ 0xff, "MAGIC (", 0, ")", -1, 0 }, /* Dodgy Special Case ! */
{ 0x105, "ERROR.TYPE (", 0, ")", 1, 0 },
{ 0x10d, "AVEDEV (", 0, ")", -1, 0 },
{ 0x10e, "BETADIST (", 0, ")", 3, 0 },
......@@ -423,7 +424,7 @@ parse_list_comma_delimit_n (PARSE_LIST *stack, char *prefix,
put = ans + strlen(ans) ;
for (lp=0;lp<n;lp++)
put += sprintf (put, "%c%s", lp?',':' ', args[lp]) ;
put += g_snprintf (put, slen, "%c%s", lp?',':' ', args[lp]) ;
strcat (put, suffix) ;
parse_list_push_raw (stack, ans, precedence) ;
......@@ -505,22 +506,40 @@ static gboolean
make_function (PARSE_LIST *stack, int fn_idx, int numargs)
{
int lp ;
for (lp=0;lp<FORMULA_FUNC_DATA_LEN;lp++)
if (fn_idx == 0xff && numargs>1) /* Dodgy Special Case */
{
if (formula_func_data[lp].function_idx == fn_idx)
{
const FORMULA_FUNC_DATA *fd = &formula_func_data[lp] ;
if (fd->num_args != -1)
numargs = fd->num_args ;
parse_list_comma_delimit_n (stack, (fd->prefix)?fd->prefix:"",
numargs,
fd->suffix?fd->suffix:"", fd->precedence) ;
return 1 ;
PARSE_DATA *fn, *args ;
parse_list_comma_delimit_n (stack, "(", numargs-1, ")", NO_PRECEDENCE) ;
args = parse_list_pop (stack) ;
fn = parse_list_pop (stack) ;
if (!args || !fn || !args->name || !fn->name)
parse_list_push_raw (stack, g_strdup (_("Broken function")), NO_PRECEDENCE) ;
else {
/* printf ("Fn : '%s', '%s'\n", fn->name, args->name) ; */
parse_list_push_raw (stack, g_strconcat (fn->name, args->name, 0), NO_PRECEDENCE) ;
parse_data_free (args) ;
parse_data_free (fn) ;
}
return 1 ;
}
else
for (lp=0;lp<FORMULA_FUNC_DATA_LEN;lp++)
{
if (formula_func_data[lp].function_idx == fn_idx)
{
const FORMULA_FUNC_DATA *fd = &formula_func_data[lp] ;
if (fd->num_args != -1)
numargs = fd->num_args ;
parse_list_comma_delimit_n (stack, (fd->prefix)?fd->prefix:"",
numargs,
fd->suffix?fd->suffix:"", fd->precedence) ;
return 1 ;
}
}
if (lp==FORMULA_FUNC_DATA_LEN)
printf ("FIXME, unimplemented fn 0x%x, with %d args\n", fn_idx, numargs) ;
return 0 ;
......@@ -528,41 +547,35 @@ make_function (PARSE_LIST *stack, int fn_idx, int numargs)
/**
* Parse that RP Excel formula, see S59E2B.HTM
* Sadly has to be parsed to text and back !
* Return a dynamicaly allocated string containing the formula
**/
void ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, BIFF_QUERY *q,
int fn_col, int fn_row)
char *ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, guint8 *mem,
int fn_col, int fn_row, guint16 length)
{
Cell *cell ;
BYTE *cur ;
int length ;
int len_left = length ;
guint8 *cur = mem + 1 ; /* this is so that the offsets and lengths
are identical to those in the documentation */
PARSE_LIST *stack ;
int error = 0 ;
char *ans ;
int fn_xf ;
if (q->ls_op == BIFF_FORMULA)
/* if (q->ls_op == BIFF_FORMULA)
{
fn_xf = EX_GETXF(q) ;
/* This will be safe when we collate continuation records in get_query */
length = BIFF_GETWORD(q->data + 20) ;
/* NB. the effective '+1' here is so that the offsets and lengths
are identical to those in the documentation */
cur = q->data + 22 + 1 ;
}
else
{
g_assert (q->ls_op == BIFF_ARRAY) ;
fn_xf = 0 ;
/* This will be safe when we collate continuation records in get_query */
length = BIFF_GETWORD(q->data + 12) ;
/* NB. the effective '+1' here is so that the offsets and lengths
are identical to those in the documentation */
cur = q->data + 14 + 1 ;
}
} */
stack = parse_list_new() ;
while (length>0 && !error)
while (len_left>0 && !error)
{
int ptg_length = 0 ;
int ptg = BIFF_GETBYTE(cur-1) ;
......@@ -589,8 +602,33 @@ void ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, BIFF_QUERY *q,
parse_list_push_raw (stack, buffer, NO_PRECEDENCE) ;
/* printf ("%s\n", buffer) ; */
g_free (ref) ;
break ;
}
case FORMULA_PTG_NAME_X: /* FIXME: Not using sheet_idx at all ... */
{
char *txt ;
guint16 extn_sheet_idx, extn_name_idx ;
if (sheet->ver == eBiffV8)
{
extn_sheet_idx = BIFF_GETWORD(cur) ;
extn_name_idx = BIFF_GETWORD(cur+2) ;
/* printf ("FIXME: v8 NameX : %d %d\n", extn_sheet_idx, extn_name_idx) ; */
ptg_length = 6 ;
}
else
{
extn_sheet_idx = BIFF_GETWORD(cur) ;
extn_name_idx = BIFF_GETWORD(cur+10) ;
/* printf ("FIXME: v7 NameX : %d %d\n", extn_sheet_idx, extn_name_idx) ; */
ptg_length = 24 ;
}
if ((txt = biff_name_data_get_name (sheet, extn_name_idx)))
parse_list_push_raw (stack, g_strdup (txt), NO_PRECEDENCE) ;
else
parse_list_push_raw (stack, g_strdup(_("no such name")), NO_PRECEDENCE) ;
break ;
}
break ;
case FORMULA_PTG_REF_3D: /* see S59E2B.HTM */
{
CellRef *ref=0 ;
......@@ -727,21 +765,13 @@ void ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, BIFF_QUERY *q,
else
name_idx = BIFF_GETWORD(cur) ;
printf ("FIXME: Ptg Name: %d\n", name_idx) ;
dump(q->data, q->length) ;
dump(mem, length) ;
parse_list_push_raw (stack, g_strdup("Unknown name"), NO_PRECEDENCE) ;
}
case FORMULA_PTG_EXP: /* FIXME: the formula is the same as another record ... we need a cell_get_funtion call ! */
{
printf ("FIXME: Array formula\n") ;
cell = sheet_cell_fetch (sheet->gnum_sheet, fn_col, fn_row) ;
if (!cell->text)
cell_set_text_simple(cell, "") ;
else
cell_set_text_simple(cell, cell->text->str) ;
ms_excel_set_cell_xf (sheet, cell, fn_xf) ;
return ;
}
break ;
error = 1 ;
break ;
case FORMULA_PTG_PAREN:
/* printf ("Ignoring redundant parenthesis ptg\n") ; */
ptg_length = 0 ;
......@@ -801,7 +831,7 @@ void ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, BIFF_QUERY *q,
{
double tmp = BIFF_GETDOUBLE(cur) ;
char buf[65] ; /* should be long enough? */
snprintf (buf, 64, "%f", tmp) ;
g_snprintf (buf, 64, "%f", tmp) ;
parse_list_push_raw (stack, g_strdup(buf), NO_PRECEDENCE) ;