Commit a55abafe authored by Michael Meeks's avatar Michael Meeks
Browse files

Lots more excel functionality...

parent 56900f48
1999-02-04 Michael Meeks <michael@imaginator.com>
* plugins/excel/ms-biff.h: Added a biff_getdouble function for
G_BIG_ENDIAN machines, since I don't have one... [begs forgiveness]
1999-02-03 Sean Atkinson <sca20@cam.ac.uk>
* plugins/excel/ms-formula.c (ms_excel_parse_formula):
FORMULA_PTG_INT and FORMULA_PTG_BOOL added
* plugins/excel/ms-formula.c:
Implemented remaining binary operators and unary operators +,-,%
interpolated operator precedences.
formula_func_data[] : added AND, OR, V/H LOOKUP functions
1999-02-03 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/workbook.c (workbook_configure_minimized_pixmap): Provide an
......
1999-02-04 Michael Meeks <michael@imaginator.com>
* plugins/excel/ms-biff.h: Added a biff_getdouble function for
G_BIG_ENDIAN machines, since I don't have one... [begs forgiveness]
1999-02-03 Sean Atkinson <sca20@cam.ac.uk>
* plugins/excel/ms-formula.c (ms_excel_parse_formula):
FORMULA_PTG_INT and FORMULA_PTG_BOOL added
* plugins/excel/ms-formula.c:
Implemented remaining binary operators and unary operators +,-,%
interpolated operator precedences.
formula_func_data[] : added AND, OR, V/H LOOKUP functions
1999-02-03 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/workbook.c (workbook_configure_minimized_pixmap): Provide an
......
1999-02-04 Michael Meeks <michael@imaginator.com>
* plugins/excel/ms-biff.h: Added a biff_getdouble function for
G_BIG_ENDIAN machines, since I don't have one... [begs forgiveness]
1999-02-03 Sean Atkinson <sca20@cam.ac.uk>
* plugins/excel/ms-formula.c (ms_excel_parse_formula):
FORMULA_PTG_INT and FORMULA_PTG_BOOL added
* plugins/excel/ms-formula.c:
Implemented remaining binary operators and unary operators +,-,%
interpolated operator precedences.
formula_func_data[] : added AND, OR, V/H LOOKUP functions
1999-02-03 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/workbook.c (workbook_configure_minimized_pixmap): Provide an
......
1999-02-04 Michael Meeks <michael@imaginator.com>
* plugins/excel/ms-biff.h: Added a biff_getdouble function for
G_BIG_ENDIAN machines, since I don't have one... [begs forgiveness]
1999-02-03 Sean Atkinson <sca20@cam.ac.uk>
* plugins/excel/ms-formula.c (ms_excel_parse_formula):
FORMULA_PTG_INT and FORMULA_PTG_BOOL added
* plugins/excel/ms-formula.c:
Implemented remaining binary operators and unary operators +,-,%
interpolated operator precedences.
formula_func_data[] : added AND, OR, V/H LOOKUP functions
1999-02-03 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/workbook.c (workbook_configure_minimized_pixmap): Provide an
......
......@@ -21,9 +21,22 @@ typedef guint64 DLONG ;
(*(p+2)<<16)+ \
(*(p+3)<<24))
#define BIFF_GETDLONG(p) (DLONG)(BIFF_GETLONG(p)+(((DLONG)BIFF_GETLONG(p+4))<<32))
/* Endianness hack only work on Intel ! */
#define BIFF_GETDOUBLE(p) (*((double*)(p)))
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
#define BIFF_GETDOUBLE(p) (*((double*)(p)))
#else
static double biff_getdouble(guint8 *p)
{
double d;
int i;
guint8 *t = (guint8 *)&d + 8;
for (i = 0; i < 8; i++)
*--t = *p++;
return d;
}
#define BIFF_GETDOUBLE(p) (biff_getdouble(p))
#endif
/**
* Returns query data, it is imperative that copies of
* 'data *' should _not_ be kept.
......@@ -39,7 +52,7 @@ typedef struct _BIFF_QUERY
guint32 streamPos ; /* count of bytes into the stream */
MS_OLE_STREAM *pos ;
} BIFF_QUERY ;
/* Sets up a query on a stream */
extern BIFF_QUERY *ms_biff_query_new (MS_OLE_STREAM *) ;
/* Duplicates this query, so chaining can re-commence here */
......
......@@ -26,10 +26,25 @@
* formula PTG, prefix, middle, suffix, precedence
**/
FORMULA_OP_DATA formula_op_data[] = {
{ 0x03, 0, "+", 0, 8 },
{ 0x04, 0, "-", 0, 8 },
{ 0x05, 0, "*", 0, 32 },
{ 0x06, 0, "/", 0, 16 }
/* Binary operator tokens */
{ 0x03, 1, "+", 30 }, /* ptgAdd : Addition */
{ 0x04, 1, "-", 30 }, /* ptgSub : Subtraction */
{ 0x05, 1, "*", 48 }, /* ptgMul : Multiplication */
{ 0x06, 1, "/", 32 }, /* ptgDiv : Division */
{ 0x07, 1, "^", 60 }, /* ptgPower : Exponentiation */
{ 0x09, 1, "<", 24 }, /* ptgLT : Less Than */
{ 0x0a, 1, "<=", 24 }, /* ptgLTE : Less Than or Equal */
{ 0x0b, 1, "=", 20 }, /* ptgEQ : Equal */
{ 0x0c, 1, ">=", 24 }, /* ptgGTE : Greater Than or Equal */
{ 0x0d, 1, ">" , 24 }, /* ptgGT : Greater Than */
{ 0x0e, 1, "<>", 20 }, /* ptgNE : Not Equal */
{ 0x0f, 1, " " , 62 }, /* ptgIsect : Intersection */
{ 0x10, 1, "," , 62 }, /* ptgUnion : Union */
{ 0x11, 1, ":" , 63 }, /* ptgRange : Range */
/* Unary operator tokens */
{ 0x12, 0, "+", 64 }, /* ptgUplus : Unary Plus */
{ 0x13, 0, "-", 64 }, /* ptgUminux : Unary Minus */
{ 0x14, 0, "%", 64 } /* ptgPercent : Percent Sign */
} ;
#define FORMULA_OP_DATA_LEN (sizeof(formula_op_data)/sizeof(FORMULA_OP_DATA))
......@@ -43,7 +58,11 @@ FORMULA_FUNC_DATA formula_func_data[] =
{ 0x04, "SUM (", 0, ")", 1, 0 },
{ 0x05, "AVERAGE (", 0, ")", 1, 0 },
{ 0x06, "MIN (", 0, ")", 1, 0 },
{ 0x07, "MAX (", 0, ")", 1, 0 }
{ 0x07, "MAX (", 0, ")", 1, 0 },
{ 0x24, "AND (", 0, ")", 1, 0 },
{ 0x25, "OR (", 0, ")", 1, 0 },
{ 0x65, "HLOOKUP (", 0, ")", 1, 0 },
{ 0x66, "VLOOKUP (", 0, ")", 1, 0 }
};
#define FORMULA_FUNC_DATA_LEN (sizeof(formula_func_data)/sizeof(FORMULA_FUNC_DATA))
......@@ -211,6 +230,8 @@ static char *parse_list_to_equation (PARSE_LIST *list)
return "Stack too short" ;
if (!pd->name)
return "No data in stack entry" ;
if (list->length>1)
return "Too much data on stack\n" ;
formula = (char *)g_malloc(strlen(pd->name)+2) ;
if (!formula)
......@@ -323,6 +344,35 @@ void ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, BIFF_QUERY *q,
g_free (ref) ;
}
break ;
case FORMULA_PTG_REF_3D:
{
CellRef *ref ;
char *buffer ;
/* Need to look at EXTERNSHEETS, these need to go into gnum_sheet struct, S59DA9.HTM and then be referenced */
if (sheet->ver == eBiffV8)
{
printf ("FIXME: proper sheet names needed from EXTERNSHEET table\n") ;
ref = getRefV8 (sheet, BIFF_GETWORD(cur+2), BIFF_GETWORD(cur + 4), fn_col, fn_row) ;
ptg_length = 6 ;
}
else
{
printf ("FIXME: Biff V7 3D refs are ugly !\n") ;
error = 1 ;
ref = 0 ;
ptg_length = 16 ;
}
if (ref)
{
buffer = cellref_name (ref, sheet->gnum_sheet, fn_col, fn_row) ;
parse_list_push_raw(stack, buffer, NO_PRECEDENCE) ;
printf ("%s\n", buffer) ;
g_free (ref) ;
}
}
break ;
case FORMULA_PTG_AREA:
{
CellRef *first, *last ;
......@@ -403,14 +453,31 @@ void ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, BIFF_QUERY *q,
ptg_length = 2 ;
}
break ;
case FORMULA_PTG_INT:
{
char buf[8]; /* max. "65535" */
guint16 num = BIFF_GETWORD(cur) ;
sprintf(buf,"%u",num);
parse_list_push_raw (stack, strdup(buf), NO_PRECEDENCE) ;
ptg_length = 2 ;
}
break;
case FORMULA_PTG_BOOL:
{
parse_list_push_raw (stack, strdup(BIFF_GETBYTE(cur) ? "TRUE" : "FALSE" ), NO_PRECEDENCE) ;
ptg_length = 1 ;
}
break ;
case FORMULA_PTG_STR:
{ /* FIXME: Len should only be a byte but seems to be a word ! */
guint32 len = BIFF_GETWORD(cur) ;
char *str = (char *)g_malloc(len+1) ;
char *str = (char *)g_malloc(len+3) ;
guint32 lp ;
for (lp=0;lp<len;lp++)
str[lp] = BIFF_GETBYTE(cur+2+lp) ;
str[lp] = 0 ;
str[lp+1] = BIFF_GETBYTE(cur+2+lp) ;
str[lp] = '"' ;
str[lp+1] = '\0' ;
str[0] = '"' ;
parse_list_push_raw (stack, str, NO_PRECEDENCE) ;
printf ("Found string '%s'\n", str) ;
ptg_length = 2 + len ;
......@@ -425,36 +492,37 @@ void ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, BIFF_QUERY *q,
{
if (ptgbase == formula_op_data[lp].formula_ptg)
{
PARSE_DATA *arg1, *arg2 ;
PARSE_DATA *arg1=0, *arg2 ;
GList *tmp ;
char buffer[2048] ;
FORMULA_OP_DATA *fd = &formula_op_data[lp] ;
int bracket_arg2 ;
int bracket_arg1 ;
buffer[0] = '\0' ; /* Terminate string */
arg2 = parse_list_pop (stack) ;
arg1 = parse_list_pop (stack) ;
bracket_arg2 = arg2->precedence<fd->precedence ;
bracket_arg1 = arg1->precedence<fd->precedence ;
strcpy (buffer, fd->prefix?fd->prefix:"") ;
if (bracket_arg1)
strcat (buffer, "(") ;
strcat (buffer, arg1->name) ;
if (bracket_arg1)
strcat (buffer, ")") ;
if (fd->infix)
{
arg1 = parse_list_pop (stack) ;
bracket_arg1 = arg1->precedence<fd->precedence ;
if (bracket_arg1)
strcat (buffer, "(") ;
strcat (buffer, arg1->name) ;
if (bracket_arg1)
strcat (buffer, ")") ;
}
strcat (buffer, fd->mid?fd->mid:"") ;
if (bracket_arg2)
strcat (buffer, "(") ;
strcat (buffer, arg2->name) ;
if (bracket_arg2)
strcat (buffer, ")") ;
strcat (buffer, fd->suffix?fd->suffix:"") ;
printf ("Op : '%s'\n", buffer) ;
parse_list_push_raw(stack, strdup (buffer), fd->precedence) ;
parse_data_free (arg1) ;
if (fd->infix)
parse_data_free (arg1) ;
parse_data_free (arg2) ;
break ;
}
......
......@@ -7,6 +7,8 @@
#ifndef GNUMERIC_MS_FORMULA_H
#define GNUMERIC_MS_FORMULA_H
#include <glib.h>
#include "ms-excel.h"
#include "ms-biff.h"
......@@ -20,6 +22,8 @@ void ms_excel_fixup_array_formulae (MS_EXCEL_SHEET *sheet) ;
#define FORMULA_PTG_EXP 0x01
#define FORMULA_PTG_PAREN 0x15
#define FORMULA_PTG_STR 0x17
#define FORMULA_PTG_BOOL 0x1d
#define FORMULA_PTG_INT 0x1e
#define FORMULA_PTG_FUNC 0x21
#define FORMULA_PTG_FUNC_VAR 0x22
......@@ -27,6 +31,8 @@ void ms_excel_fixup_array_formulae (MS_EXCEL_SHEET *sheet) ;
#define FORMULA_PTG_AREA 0x25
#define FORMULA_PTG_MEM_AREA 0x26
#define FORMULA_PTG_REF_3D 0x3a
typedef struct _FORMULA_ARRAY_DATA
{
int src_col, src_row, dest_col, dest_row ;
......@@ -35,9 +41,8 @@ typedef struct _FORMULA_ARRAY_DATA
typedef struct _FORMULA_OP_DATA
{
BYTE formula_ptg ;
char *prefix ;
gboolean infix ; /* ie. not unary */
char *mid ;
char *suffix ;
int precedence ;
} FORMULA_OP_DATA ;
......
......@@ -26,10 +26,25 @@
* formula PTG, prefix, middle, suffix, precedence
**/
FORMULA_OP_DATA formula_op_data[] = {
{ 0x03, 0, "+", 0, 8 },
{ 0x04, 0, "-", 0, 8 },
{ 0x05, 0, "*", 0, 32 },
{ 0x06, 0, "/", 0, 16 }
/* Binary operator tokens */
{ 0x03, 1, "+", 30 }, /* ptgAdd : Addition */
{ 0x04, 1, "-", 30 }, /* ptgSub : Subtraction */
{ 0x05, 1, "*", 48 }, /* ptgMul : Multiplication */
{ 0x06, 1, "/", 32 }, /* ptgDiv : Division */
{ 0x07, 1, "^", 60 }, /* ptgPower : Exponentiation */
{ 0x09, 1, "<", 24 }, /* ptgLT : Less Than */
{ 0x0a, 1, "<=", 24 }, /* ptgLTE : Less Than or Equal */
{ 0x0b, 1, "=", 20 }, /* ptgEQ : Equal */
{ 0x0c, 1, ">=", 24 }, /* ptgGTE : Greater Than or Equal */
{ 0x0d, 1, ">" , 24 }, /* ptgGT : Greater Than */
{ 0x0e, 1, "<>", 20 }, /* ptgNE : Not Equal */
{ 0x0f, 1, " " , 62 }, /* ptgIsect : Intersection */
{ 0x10, 1, "," , 62 }, /* ptgUnion : Union */
{ 0x11, 1, ":" , 63 }, /* ptgRange : Range */
/* Unary operator tokens */
{ 0x12, 0, "+", 64 }, /* ptgUplus : Unary Plus */
{ 0x13, 0, "-", 64 }, /* ptgUminux : Unary Minus */
{ 0x14, 0, "%", 64 } /* ptgPercent : Percent Sign */
} ;
#define FORMULA_OP_DATA_LEN (sizeof(formula_op_data)/sizeof(FORMULA_OP_DATA))
......@@ -43,7 +58,11 @@ FORMULA_FUNC_DATA formula_func_data[] =
{ 0x04, "SUM (", 0, ")", 1, 0 },
{ 0x05, "AVERAGE (", 0, ")", 1, 0 },
{ 0x06, "MIN (", 0, ")", 1, 0 },
{ 0x07, "MAX (", 0, ")", 1, 0 }
{ 0x07, "MAX (", 0, ")", 1, 0 },
{ 0x24, "AND (", 0, ")", 1, 0 },
{ 0x25, "OR (", 0, ")", 1, 0 },
{ 0x65, "HLOOKUP (", 0, ")", 1, 0 },
{ 0x66, "VLOOKUP (", 0, ")", 1, 0 }
};
#define FORMULA_FUNC_DATA_LEN (sizeof(formula_func_data)/sizeof(FORMULA_FUNC_DATA))
......@@ -211,6 +230,8 @@ static char *parse_list_to_equation (PARSE_LIST *list)
return "Stack too short" ;
if (!pd->name)
return "No data in stack entry" ;
if (list->length>1)
return "Too much data on stack\n" ;
formula = (char *)g_malloc(strlen(pd->name)+2) ;
if (!formula)
......@@ -323,6 +344,35 @@ void ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, BIFF_QUERY *q,
g_free (ref) ;
}
break ;
case FORMULA_PTG_REF_3D:
{
CellRef *ref ;
char *buffer ;
/* Need to look at EXTERNSHEETS, these need to go into gnum_sheet struct, S59DA9.HTM and then be referenced */
if (sheet->ver == eBiffV8)
{
printf ("FIXME: proper sheet names needed from EXTERNSHEET table\n") ;
ref = getRefV8 (sheet, BIFF_GETWORD(cur+2), BIFF_GETWORD(cur + 4), fn_col, fn_row) ;
ptg_length = 6 ;
}
else
{
printf ("FIXME: Biff V7 3D refs are ugly !\n") ;
error = 1 ;
ref = 0 ;
ptg_length = 16 ;
}
if (ref)
{
buffer = cellref_name (ref, sheet->gnum_sheet, fn_col, fn_row) ;
parse_list_push_raw(stack, buffer, NO_PRECEDENCE) ;
printf ("%s\n", buffer) ;
g_free (ref) ;
}
}
break ;
case FORMULA_PTG_AREA:
{
CellRef *first, *last ;
......@@ -403,14 +453,31 @@ void ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, BIFF_QUERY *q,
ptg_length = 2 ;
}
break ;
case FORMULA_PTG_INT:
{
char buf[8]; /* max. "65535" */
guint16 num = BIFF_GETWORD(cur) ;
sprintf(buf,"%u",num);
parse_list_push_raw (stack, strdup(buf), NO_PRECEDENCE) ;
ptg_length = 2 ;
}
break;
case FORMULA_PTG_BOOL:
{
parse_list_push_raw (stack, strdup(BIFF_GETBYTE(cur) ? "TRUE" : "FALSE" ), NO_PRECEDENCE) ;
ptg_length = 1 ;
}
break ;
case FORMULA_PTG_STR:
{ /* FIXME: Len should only be a byte but seems to be a word ! */
guint32 len = BIFF_GETWORD(cur) ;
char *str = (char *)g_malloc(len+1) ;
char *str = (char *)g_malloc(len+3) ;
guint32 lp ;
for (lp=0;lp<len;lp++)
str[lp] = BIFF_GETBYTE(cur+2+lp) ;
str[lp] = 0 ;
str[lp+1] = BIFF_GETBYTE(cur+2+lp) ;
str[lp] = '"' ;
str[lp+1] = '\0' ;
str[0] = '"' ;
parse_list_push_raw (stack, str, NO_PRECEDENCE) ;
printf ("Found string '%s'\n", str) ;
ptg_length = 2 + len ;
......@@ -425,36 +492,37 @@ void ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, BIFF_QUERY *q,
{
if (ptgbase == formula_op_data[lp].formula_ptg)
{
PARSE_DATA *arg1, *arg2 ;
PARSE_DATA *arg1=0, *arg2 ;
GList *tmp ;
char buffer[2048] ;
FORMULA_OP_DATA *fd = &formula_op_data[lp] ;
int bracket_arg2 ;
int bracket_arg1 ;
buffer[0] = '\0' ; /* Terminate string */
arg2 = parse_list_pop (stack) ;
arg1 = parse_list_pop (stack) ;
bracket_arg2 = arg2->precedence<fd->precedence ;
bracket_arg1 = arg1->precedence<fd->precedence ;
strcpy (buffer, fd->prefix?fd->prefix:"") ;
if (bracket_arg1)
strcat (buffer, "(") ;
strcat (buffer, arg1->name) ;
if (bracket_arg1)
strcat (buffer, ")") ;
if (fd->infix)
{
arg1 = parse_list_pop (stack) ;
bracket_arg1 = arg1->precedence<fd->precedence ;
if (bracket_arg1)
strcat (buffer, "(") ;
strcat (buffer, arg1->name) ;
if (bracket_arg1)
strcat (buffer, ")") ;
}
strcat (buffer, fd->mid?fd->mid:"") ;
if (bracket_arg2)
strcat (buffer, "(") ;
strcat (buffer, arg2->name) ;
if (bracket_arg2)
strcat (buffer, ")") ;
strcat (buffer, fd->suffix?fd->suffix:"") ;
printf ("Op : '%s'\n", buffer) ;
parse_list_push_raw(stack, strdup (buffer), fd->precedence) ;
parse_data_free (arg1) ;
if (fd->infix)
parse_data_free (arg1) ;
parse_data_free (arg2) ;
break ;
}
......
......@@ -7,6 +7,8 @@
#ifndef GNUMERIC_MS_FORMULA_H
#define GNUMERIC_MS_FORMULA_H
#include <glib.h>
#include "ms-excel.h"
#include "ms-biff.h"
......@@ -20,6 +22,8 @@ void ms_excel_fixup_array_formulae (MS_EXCEL_SHEET *sheet) ;
#define FORMULA_PTG_EXP 0x01
#define FORMULA_PTG_PAREN 0x15
#define FORMULA_PTG_STR 0x17
#define FORMULA_PTG_BOOL 0x1d
#define FORMULA_PTG_INT 0x1e
#define FORMULA_PTG_FUNC 0x21
#define FORMULA_PTG_FUNC_VAR 0x22
......@@ -27,6 +31,8 @@ void ms_excel_fixup_array_formulae (MS_EXCEL_SHEET *sheet) ;
#define FORMULA_PTG_AREA 0x25
#define FORMULA_PTG_MEM_AREA 0x26
#define FORMULA_PTG_REF_3D 0x3a
typedef struct _FORMULA_ARRAY_DATA
{
int src_col, src_row, dest_col, dest_row ;
......@@ -35,9 +41,8 @@ typedef struct _FORMULA_ARRAY_DATA
typedef struct _FORMULA_OP_DATA
{
BYTE formula_ptg ;
char *prefix ;
gboolean infix ; /* ie. not unary */
char *mid ;
char *suffix ;
int precedence ;
} FORMULA_OP_DATA ;
......
......@@ -356,7 +356,7 @@ ms_ole_create (const char *name)
guint32 sbd_startblock = 0, zero = 0;
char title[] ="Root Entry";
if ((file = open (name, O_RDWR|O_CREAT|O_TRUNC|O_NONBLOCK,
if ((file = open (name, O_RDONLY|O_CREAT|O_TRUNC|O_NONBLOCK,
S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)) == -1)
{
printf ("Can't create file '%s'\n", name);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment