Commit a9475d31 authored by Michael Meeks's avatar Michael Meeks

Major, major re-organisation of OLE code with a view towards getting it into

a library. Very little real code change there, mostly shuffling.
Similar cosmetic cleanups to ms-excel.c, and a few little features fixed.
parent d07ed146
1998-11-12 Michael Meeks <michael@imaginator.com>
* plugins/excel/ms-ole.c, plugins/excel/ms-ole.h: Massive changes
renamed many functions to conform to a sensible naming convention.
Cleaned the interface, and structure names.
* plugins/excel/ms-excel-biff.h: Split from ms-biff.h removing all
the excel specifics so that the biff & ole stuff can be turned into
a library sometime.
* src/workbook.c(workbook_read): Updated to new structure names.
* plugins/excel/ms-excel.c: Added list of array formulae, as yet
unused, possibly unneccesary.
* plugins/excel/ms-formula.c: Added support for slightly different
array formula BIFF layout.
1998-11-11 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/gnumeric-util.c (font_get_italic_name): Missing function.
......
1998-11-12 Michael Meeks <michael@imaginator.com>
* plugins/excel/ms-ole.c, plugins/excel/ms-ole.h: Massive changes
renamed many functions to conform to a sensible naming convention.
Cleaned the interface, and structure names.
* plugins/excel/ms-excel-biff.h: Split from ms-biff.h removing all
the excel specifics so that the biff & ole stuff can be turned into
a library sometime.
* src/workbook.c(workbook_read): Updated to new structure names.
* plugins/excel/ms-excel.c: Added list of array formulae, as yet
unused, possibly unneccesary.
* plugins/excel/ms-formula.c: Added support for slightly different
array formula BIFF layout.
1998-11-11 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/gnumeric-util.c (font_get_italic_name): Missing function.
......
1998-11-12 Michael Meeks <michael@imaginator.com>
* plugins/excel/ms-ole.c, plugins/excel/ms-ole.h: Massive changes
renamed many functions to conform to a sensible naming convention.
Cleaned the interface, and structure names.
* plugins/excel/ms-excel-biff.h: Split from ms-biff.h removing all
the excel specifics so that the biff & ole stuff can be turned into
a library sometime.
* src/workbook.c(workbook_read): Updated to new structure names.
* plugins/excel/ms-excel.c: Added list of array formulae, as yet
unused, possibly unneccesary.
* plugins/excel/ms-formula.c: Added support for slightly different
array formula BIFF layout.
1998-11-11 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/gnumeric-util.c (font_get_italic_name): Missing function.
......
1998-11-12 Michael Meeks <michael@imaginator.com>
* plugins/excel/ms-ole.c, plugins/excel/ms-ole.h: Massive changes
renamed many functions to conform to a sensible naming convention.
Cleaned the interface, and structure names.
* plugins/excel/ms-excel-biff.h: Split from ms-biff.h removing all
the excel specifics so that the biff & ole stuff can be turned into
a library sometime.
* src/workbook.c(workbook_read): Updated to new structure names.
* plugins/excel/ms-excel.c: Added list of array formulae, as yet
unused, possibly unneccesary.
* plugins/excel/ms-formula.c: Added support for slightly different
array formula BIFF layout.
1998-11-11 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/gnumeric-util.c (font_get_italic_name): Missing function.
......
......@@ -8,7 +8,7 @@ INCLUDES = \
noinst_LIBRARIES = libexcel.a
libexcel_a_SOURCES = \
ms-biff.c \
ms-excel-biff.h \
ms-biff.h \
ms-excel.c \
ms-excel.h \
......
/*
* ms-biff.c: MS Excel BIFF support for Gnumeric
*
* Author:
* Michael Meeks (michael@imaginator.com)
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <malloc.h>
#include <assert.h>
#include <ctype.h>
#include "ms-ole.h"
#include "ms-biff.h"
BIFF_BOF_DATA *new_ms_biff_bof_data (BIFF_QUERY *q)
{
BIFF_BOF_DATA *ans = (BIFF_BOF_DATA *)malloc(sizeof(BIFF_BOF_DATA)) ;
if ((q->opcode&0xff) == BIFF_BOF)
{
assert (q->length>=4) ;
// Determine type from boff
switch (q->opcode>>8)
{
case 0:
ans->version = eBiffV2 ;
break ;
case 2:
ans->version = eBiffV3 ;
break ;
case 4:
ans->version = eBiffV4 ;
break ;
case 8: // MOre complicated
{
switch (GETWORD(q->data))
{
case 0x0600:
ans->version = eBiffV8 ;
break ;
case 0x500:
ans->version = eBiffV5 ; // OR ebiff7 : FIXME ? !
break ;
default:
printf ("Unknown BIFF sub-number in BOF %x\n", q->opcode) ;
ans->version = eBiffVUnknown ;
}
}
break;
default:
printf ("Unknown BIFF number in BOF %x\n", q->opcode) ;
ans->version = eBiffVUnknown ;
}
switch (GETWORD(q->data+2))
{
case 0x0005:
ans->type = eBiffTWorkbook ;
break ;
case 0x0006:
ans->type = eBiffTVBModule ;
break ;
case 0x0010:
ans->type = eBiffTWorksheet ;
break ;
case 0x0020:
ans->type = eBiffTChart ;
break ;
case 0x0040:
ans->type = eBiffTMacrosheet ;
break ;
case 0x0100:
ans->type = eBiffTWorkspace ;
break ;
default:
ans->type = eBiffTUnknown ;
printf ("Unknown BIFF type in BOF %x\n", GETWORD(q->data+2)) ;
break ;
}
// Now store in the directory array:
printf ("BOF %x, %d == %d, %d\n", q->opcode, q->length,
ans->version, ans->type) ;
}
else
{
printf ("Not a BOF !\n") ;
ans->version = eBiffVUnknown ;
ans->type = eBiffTUnknown ;
}
return ans ;
}
void free_ms_biff_bof_data (BIFF_BOF_DATA *data)
{
free (data) ;
}
......@@ -8,6 +8,10 @@
#define GNUMERIC_BIFF_H
#include "ms-ole.h"
typedef guint8 BYTE ;
typedef guint16 WORD ;
typedef guint32 LONG ;
// EXTREMELY IMPORTANT TO PASS A BYTE PTR !
#define BIFF_GETBYTE(p) (*(p+0))
#define BIFF_GETWORD(p) (*(p+0)+(*(p+1)<<8))
......@@ -20,11 +24,6 @@
// Oh dear, silly really, brutal endianness hack: FIXME
// #define GETDOUBLE(p) ((double)GETDLONG(p))
#define BIFF_GETDOUBLE(p) (*((double *)(p)))
// Pass this a BIFF_QUERY *
#define BIFF_GETROW(p) (GETWORD(p->data + 0))
#define BIFF_GETCOL(p) (GETWORD(p->data + 2))
#define BIFF_GETXF(p) (GETWORD(p->data + 4))
#define BIFF_GETSTRLEN(p) (GETWORD(p->data + 6))
typedef struct _BIFF_QUERY
{
......@@ -46,13 +45,12 @@ typedef struct _BIFF_QUERY
// to split the stream into files first, before using ms_next_biff
// Opens OLE file 'workbook' or 'book' depending.
extern BIFF_QUERY *new_ms_biff_query_file (MS_OLE_FILE *) ;
extern BIFF_QUERY *new_ms_biff_query_here (MS_OLE_STREAM_POS *p) ;
extern BIFF_QUERY *copy_ms_biff_query (const BIFF_QUERY *p) ;
extern BIFF_QUERY *ms_biff_query_new (MS_OLE *) ;
extern BIFF_QUERY *ms_biff_query_copy (const BIFF_QUERY *p) ;
// Updates the BIFF_QUERY Structure
extern int ms_next_biff (BIFF_QUERY *) ;
extern int ms_biff_query_next (BIFF_QUERY *) ;
// Free it then.
extern void free_ms_biff_query (BIFF_QUERY *) ;
extern void ms_biff_query_destroy (BIFF_QUERY *) ;
//------------------------------------------------------------------------
......@@ -64,78 +62,9 @@ typedef enum _eBiff_version { eBiffV2=2, eBiffV3=3, eBiffV4=4, eBiffV5=5, eBiffV
typedef enum _eBiff_filetype { eBiffTWorkbook=0, eBiffTVBModule=1, eBiffTWorksheet=2,
eBiffTChart=3, eBiffTMacrosheet=4, eBiffTWorkspace=5,
eBiffTUnknown=6 } eBiff_filetype ;
// Cell / XF types
typedef enum _eBiff_hidden { eBiffHVisible=0, eBiffHHidden=1,
eBiffHVeryHidden=2 } eBiff_hidden ;
typedef enum _eBiff_locked { eBiffLLocked=1, eBiffLUnlocked=0 } eBiff_locked ;
typedef enum _eBiff_xftype { eBiffXStyle=0, eBiffXCell=1 } eBiff_xftype ;
typedef enum _eBiff_format { eBiffFMS=0, eBiffFLotus=1 } eBiff_format ;
typedef enum _eBiff_wrap { eBiffWWrap=0, eBiffWNoWrap=1 } eBiff_wrap ;
typedef enum _eBiff_eastern { eBiffEContext=0, eBiffEleftToRight=1,
eBiffErightToLeft=2 } eBiff_eastern ;
typedef enum _eBiff_direction { eBiffDirTop=0, eBiffDirBottom=1,
eBiffDirLeft=2, eBiffDirRight=3 } eBiff_direction ;
typedef enum _eBiff_border_orientation { eBiffBONone=0,
eBiffBODiagDown=1,
eBiffBODiagUp=2,
eBiffBODiagBoth=3 } eBiff_border_orientation ;
typedef enum _eBiff_border_linestyle // Magic numbers !
{
eBiffBorderNone=0, eBiffBorderThin=1, eBiffBorderMedium=2,
eBiffBorderDashed=3, eBiffBorderDotted=4, eBiffBorderThick=5,
eBiffBorderDouble=6, eBiffBorderHair=7, eBiffBorderMediumDash=8,
eBiffBorderDashDot=9, eBiffBorderMediumDashDot=10,
eBiffBorderDashDotDot=11, eBiffBorderMediumDashDotDot=12,
eBiffBorderSlantedDashDot=13
} eBiff_border_linestyle ;
typedef enum _eBiffFontUnderline
{
eBiffFUNone=1, eBiffFUSingle=2, eBiffFUDouble=3,
eBiffFUSingleAcc=4, eBiffFUDoubleAcc=5
} eBiffFontUnderline ;
typedef enum _eBiffFontScript { eBiffFSNone, eBiffFSSub, eBiffFSSuper } eBiffFontScript ;
typedef struct _BIFF_BOF_DATA
{
eBiff_version version ;
eBiff_filetype type ;
} BIFF_BOF_DATA ;
// Privatish BIFF_FILE functions
extern BIFF_BOF_DATA *new_ms_biff_bof_data (BIFF_QUERY *pos) ;
extern void free_ms_biff_bof_data (BIFF_BOF_DATA *data) ;
//------------------------------------------------------------------------
#define BIFF_BLANK 0x01
#define BIFF_NUMBER 0x03
#define BIFF_LABEL 0x04
#define BIFF_FORMULA 0x06
#define BIFF_ROW 0x08
#define BIFF_BOF 0x09
#define BIFF_EOF 0x0a
#define BIFF_PRECISION 0x0e
#define BIFF_FONT 0x31
#define BIFF_XF_OLD 0x43
#define BIFF_RK 0x7e
#define BIFF_BOUNDSHEET 0x85
#define BIFF_PALETTE 0x92
#define BIFF_MULBLANK 0xbe
#define BIFF_RSTRING 0xd6
#define BIFF_XF 0xe0
#endif
/* Odd balls */
#define BIFF_DV 0x1be
//------------------------------------------------------------------------
#endif
......
/*
* ms-excel-biff.h: MS Excel BIFF header for Gnumeric
* contains data about the Excel BIFF records
*
* Author:
* Michael Meeks (michael@imaginator.com)
*/
#ifndef GNUMERIC_EXCEL_BIFF_H
#define GNUMERIC_EXCEL_BIFF_H
/* Pass this a BIFF_QUERY * */
#define EX_GETROW(p) (BIFF_GETWORD(p->data + 0))
#define EX_GETCOL(p) (BIFF_GETWORD(p->data + 2))
#define EX_GETXF(p) (BIFF_GETWORD(p->data + 4))
#define EX_GETSTRLEN(p) (BIFF_GETWORD(p->data + 6))
// Cell / XF types
typedef enum _eBiff_hidden { eBiffHVisible=0, eBiffHHidden=1,
eBiffHVeryHidden=2 } eBiff_hidden ;
typedef enum _eBiff_locked { eBiffLLocked=1, eBiffLUnlocked=0 } eBiff_locked ;
typedef enum _eBiff_xftype { eBiffXStyle=0, eBiffXCell=1 } eBiff_xftype ;
typedef enum _eBiff_format { eBiffFMS=0, eBiffFLotus=1 } eBiff_format ;
typedef enum _eBiff_wrap { eBiffWWrap=0, eBiffWNoWrap=1 } eBiff_wrap ;
typedef enum _eBiff_eastern { eBiffEContext=0, eBiffEleftToRight=1,
eBiffErightToLeft=2 } eBiff_eastern ;
typedef enum _eBiff_direction { eBiffDirTop=0, eBiffDirBottom=1,
eBiffDirLeft=2, eBiffDirRight=3 } eBiff_direction ;
typedef enum _eBiff_border_orientation { eBiffBONone=0,
eBiffBODiagDown=1,
eBiffBODiagUp=2,
eBiffBODiagBoth=3 } eBiff_border_orientation ;
typedef enum _eBiff_border_linestyle // Magic numbers !
{
eBiffBorderNone=0, eBiffBorderThin=1, eBiffBorderMedium=2,
eBiffBorderDashed=3, eBiffBorderDotted=4, eBiffBorderThick=5,
eBiffBorderDouble=6, eBiffBorderHair=7, eBiffBorderMediumDash=8,
eBiffBorderDashDot=9, eBiffBorderMediumDashDot=10,
eBiffBorderDashDotDot=11, eBiffBorderMediumDashDotDot=12,
eBiffBorderSlantedDashDot=13
} eBiff_border_linestyle ;
typedef enum _eBiffFontUnderline
{
eBiffFUNone=1, eBiffFUSingle=2, eBiffFUDouble=3,
eBiffFUSingleAcc=4, eBiffFUDoubleAcc=5
} eBiffFontUnderline ;
typedef enum _eBiffFontScript { eBiffFSNone, eBiffFSSub, eBiffFSSuper } eBiffFontScript ;
typedef struct _BIFF_BOF_DATA
{
eBiff_version version ;
eBiff_filetype type ;
} BIFF_BOF_DATA ;
// Privatish BIFF_FILE functions
extern BIFF_BOF_DATA *new_ms_biff_bof_data (BIFF_QUERY *pos) ;
extern void free_ms_biff_bof_data (BIFF_BOF_DATA *data) ;
//------------------------------------------------------------------------
/* See S59B52.HTM */
#define BIFF_BLANK 0x01
#define BIFF_NUMBER 0x03
#define BIFF_LABEL 0x04
#define BIFF_FORMULA 0x06
#define BIFF_ROW 0x08
#define BIFF_BOF 0x09
#define BIFF_EOF 0x0a
#define BIFF_PRECISION 0x0e
#define BIFF_ARRAY 0x21
#define BIFF_FONT 0x31
#define BIFF_XF_OLD 0x43
#define BIFF_RK 0x7e
#define BIFF_BOUNDSHEET 0x85
#define BIFF_PALETTE 0x92
#define BIFF_MULBLANK 0xbe
#define BIFF_RSTRING 0xd6
#define BIFF_XF 0xe0
/* Odd balls */
#define BIFF_DV 0x1be
//------------------------------------------------------------------------
#endif
This diff is collapsed.
......@@ -9,8 +9,9 @@
#include "ms-ole.h"
#include "ms-biff.h"
#include "ms-excel-biff.h"
extern Workbook *ms_excelReadWorkbook(MS_OLE_FILE *file) ;
extern Workbook *ms_excelReadWorkbook(MS_OLE *file) ;
typedef struct _BIFF_BOUNDSHEET_DATA
{
......@@ -25,6 +26,7 @@ typedef struct _MS_EXCEL_SHEET
Sheet *gnum_sheet ;
struct _MS_EXCEL_WORKBOOK *wb ;
eBiff_version ver ;
GList *array_formulae ;
} MS_EXCEL_SHEET ;
extern void ms_excel_sheet_insert (MS_EXCEL_SHEET *sheet, int xfidx, int col, int row, char *text) ;
......
This diff is collapsed.
......@@ -9,8 +9,9 @@
#include "ms-ole.h"
#include "ms-biff.h"
#include "ms-excel-biff.h"
extern Workbook *ms_excelReadWorkbook(MS_OLE_FILE *file) ;
extern Workbook *ms_excelReadWorkbook(MS_OLE *file) ;
typedef struct _BIFF_BOUNDSHEET_DATA
{
......@@ -25,6 +26,7 @@ typedef struct _MS_EXCEL_SHEET
Sheet *gnum_sheet ;
struct _MS_EXCEL_WORKBOOK *wb ;
eBiff_version ver ;
GList *array_formulae ;
} MS_EXCEL_SHEET ;
extern void ms_excel_sheet_insert (MS_EXCEL_SHEET *sheet, int xfidx, int col, int row, char *text) ;
......
......@@ -13,6 +13,9 @@
#include "gnumeric.h"
#include "utils.h"
#include "ms-excel.h"
#include "ms-excel-biff.h"
#include "ms-formula.h"
#define NO_PRECEDENCE 256
......@@ -219,31 +222,75 @@ static char *parse_list_to_equation (PARSE_LIST *list)
return "Nothing on stack" ;
}
/**
* Should be in cell.c ?
**/
static Cell *
duplicate_formula (Sheet *sheet, int src_col, int src_row, int dest_col, int dest_row)
{
Cell *ref_cell, *new_cell;
ref_cell = sheet_cell_get (sheet, src_col, src_row);
if (!ref_cell || !ref_cell->parsed_node)
return 0;
new_cell = sheet_cell_new (sheet, dest_col, dest_row);
cell_set_formula_tree_simple (new_cell, ref_cell->parsed_node);
return new_cell ;
}
/**
* 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)
void ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, BIFF_QUERY *q,
int fn_col, int fn_row)
{
Cell *cell ;
BYTE *cur ;
int length, fn_row, fn_col ;
int length ;
PARSE_LIST *stack ;
int error = 0 ;
char *ans ;
int array_col_first, array_col_last ;
int array_row_first, array_row_last ;
int fn_xf ;
g_assert (q->ls_op == BIFF_FORMULA) ;
fn_col = BIFF_GETCOL(q) ;
fn_row = BIFF_GETROW(q) ;
printf ("Formula at [%d, %d] XF %d :\n", fn_col, fn_row, 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) ;
/* NB. the effective '-1' here is so that the offsets and lengths
are identical to those in the documentation */
cur = q->data + 23 ;
stack = parse_list_new() ;
if (q->ls_op == BIFF_FORMULA)
{
fn_xf = EX_GETXF(q) ;
printf ("Formula at [%d, %d] XF %d :\n", fn_col, fn_row, fn_xf) ;
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) ;
/* NB. the effective '+1' here is so that the offsets and lengths
are identical to those in the documentation */
cur = q->data + 22 + 1 ;
array_col_first = fn_col ;
array_col_last = fn_col ;
array_row_first = fn_row ;
array_row_last = fn_row ;
}
else
{
g_assert (q->ls_op == BIFF_ARRAY) ;
fn_xf = 0 ;
printf ("Array at [%d, %d] XF %d :\n", fn_col, fn_row, fn_xf) ;
printf ("Array 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 + 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 ;
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) ;
}
stack = parse_list_new() ;
while (length>0 && !error)
{
int ptg_length = 0 ;
......@@ -332,11 +379,11 @@ void ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, BIFF_QUERY *q)
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), error=1 ;
ptg_length = 4 ;
cell = sheet_cell_fetch (sheet->gnum_sheet, fn_col, fn_row) ;
if (!cell->text) /* FIXME: work around cell.c bug, we can't have formatting with no text in a cell ! */
cell_set_text_simple(cell, "") ;
ms_excel_set_cell_xf (sheet, cell, fn_xf) ;
return ;
}
break ;
case FORMULA_PTG_PAREN:
......@@ -402,22 +449,45 @@ void ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, BIFF_QUERY *q)
}
if (error)
{
ms_excel_sheet_insert (sheet, BIFF_GETXF(q), BIFF_GETCOL(q), BIFF_GETROW(q), "Unknown formula") ;
int xlp, ylp ;
for (xlp=array_col_first;xlp<=array_col_last;xlp++)
for (ylp=array_row_first;ylp<=array_row_last;ylp++)
ms_excel_sheet_insert (sheet, fn_xf, xlp, ylp, "Unknown formula") ;
return ;
}
printf ("--------- Found valid formula !---------\n") ;
ans = parse_list_to_equation(stack) ;
if (ans)
{
cell = sheet_cell_fetch (sheet->gnum_sheet, BIFF_GETCOL(q), BIFF_GETROW(q)) ;
/* FIXME: this _should_ be a set_formula with the formula, and a
set_text_simple with the current value */
cell_set_text (cell, ans) ;
ms_excel_set_cell_xf (sheet, cell, BIFF_GETXF(q)) ;
int xlp, ylp ;
for (xlp=array_col_first;xlp<=array_col_last;xlp++)
for (ylp=array_row_first;ylp<=array_row_last;ylp++)
{
cell = sheet_cell_fetch (sheet->gnum_sheet, EX_GETCOL(q), EX_GETROW(q)) ;
/* FIXME: this _should_ be a set_formula with the formula, and a
set_text_simple with the current value */
cell_set_text (cell, ans) ;
ms_excel_set_cell_xf (sheet, cell, EX_GETXF(q)) ;
}
}
parse_list_free (stack) ;
}
void ms_excel_fixup_array_formulae (MS_EXCEL_SHEET *sheet)
{
GList *tmp = sheet->array_formulae ;
while (tmp)
{
FORMULA_ARRAY_DATA *dat = tmp->data ;
printf ("Copying formula from %d,%d to %d,%d\n",
dat->src_col, dat->src_row,
dat->dest_col, dat->dest_row) ;
duplicate_formula (sheet->gnum_sheet,
dat->src_col, dat->src_row,
dat->dest_col, dat->dest_row) ;
tmp = tmp->next ;
}