Commit a348468a authored by Michael Meeks's avatar Michael Meeks

More work on writing excel files,

Biff 7 3D references written,
Lookups / Area use optimised,
Memory leak fixed in area_get_at_x_y.
parent c243154b
1999-05-14 Michael Meeks <michael@imaginator.com>
* src/expr.c (value_area_get_width, value_area_get_height):
Clip to sheet bounds if CELLRANGE: Massive speedup on some
lookups.
* src/expr.h: Added value_zero
* src/func.c (constants_init): Added a 'value_zero' constant
to kill leak in out-of-range / NULL cell cases in value_get_at_x_y
1999-05-14 Jukka-Pekka Iivonen <iivonen@iki.fi>
* src/fn-math.c: Added LCM().
......
1999-05-14 Michael Meeks <michael@imaginator.com>
* src/expr.c (value_area_get_width, value_area_get_height):
Clip to sheet bounds if CELLRANGE: Massive speedup on some
lookups.
* src/expr.h: Added value_zero
* src/func.c (constants_init): Added a 'value_zero' constant
to kill leak in out-of-range / NULL cell cases in value_get_at_x_y
1999-05-14 Jukka-Pekka Iivonen <iivonen@iki.fi>
* src/fn-math.c: Added LCM().
......
1999-05-14 Michael Meeks <michael@imaginator.com>
* src/expr.c (value_area_get_width, value_area_get_height):
Clip to sheet bounds if CELLRANGE: Massive speedup on some
lookups.
* src/expr.h: Added value_zero
* src/func.c (constants_init): Added a 'value_zero' constant
to kill leak in out-of-range / NULL cell cases in value_get_at_x_y
1999-05-14 Jukka-Pekka Iivonen <iivonen@iki.fi>
* src/fn-math.c: Added LCM().
......
1999-05-14 Michael Meeks <michael@imaginator.com>
* src/expr.c (value_area_get_width, value_area_get_height):
Clip to sheet bounds if CELLRANGE: Massive speedup on some
lookups.
* src/expr.h: Added value_zero
* src/func.c (constants_init): Added a 'value_zero' constant
to kill leak in out-of-range / NULL cell cases in value_get_at_x_y
1999-05-14 Jukka-Pekka Iivonen <iivonen@iki.fi>
* src/fn-math.c: Added LCM().
......
1999-05-14 Michael Meeks <michael@imaginator.com>
* ms-formula.c (ms_excel_parse_formula): Implemented V7. 3D refs
and 3D Area references.
(make_inter_sheet_ref_v7): Created to deal with V7 references.
* ole.c (really_put): Changed to ms_ole_get_root.
* ms-excel-biff.h: moved biff_version to 'excel.h'.
* *.c: Re-ordered includes.
* ms-excel-write.c (ms_excel_write_workbook): Fleshed out.
* ms-biff.c (biff_put*): Fleshed out.
* ms-biff.h (BIFF_SET_GUINT*): Added BIFF setting macros.
1999-05-13 Michael Meeks <michael@imaginator.com>
* ms-formula.c (ms_excel_parse_formula): Updated Array support.
......
......@@ -59,3 +59,4 @@
#define BIFF_STRING 0x207
#define BIFF_NAME 0x218
#define BIFF_WINDOW2 0x23e
......@@ -9,7 +9,14 @@
#include "ms-ole.h"
typedef enum _eBiff_version { eBiffV2=2, eBiffV3=3,
eBiffV4=4, eBiffV5=5,
eBiffV7=7,
eBiffV8=8, eBiffVUnknown=0} eBiff_version ;
extern Workbook *ms_excel_read_workbook (MS_OLE *file);
extern void ms_excel_write_workbook (MS_OLE *file, Workbook *wb);
extern int ms_excel_write_workbook (MS_OLE *file, Workbook *wb,
eBiff_version ver);
#endif
1999-05-14 Michael Meeks <michael@imaginator.com>
* ms-ole.h: Updated types to forward references.
Changed ms_ole_directory_get_root to ms_ole_get_root.
1999-05-13 Michael Meeks <michael@imaginator.com>
* ms-ole.c (ms_ole_new, ms_ole_create, ms_ole_deanalyse):
......
......@@ -1340,7 +1340,7 @@ ms_ole_stream_close (MS_OLE_STREAM *s)
}
MS_OLE_DIRECTORY *
ms_ole_directory_get_root (MS_OLE *f)
ms_ole_get_root (MS_OLE *f)
{
MS_OLE_DIRECTORY *d = g_new0 (MS_OLE_DIRECTORY, 1);
d->file = f;
......@@ -1355,7 +1355,7 @@ ms_ole_directory_get_root (MS_OLE *f)
MS_OLE_DIRECTORY *
ms_ole_directory_new (MS_OLE *f)
{
MS_OLE_DIRECTORY *d = ms_ole_directory_get_root (f);
MS_OLE_DIRECTORY *d = ms_ole_get_root (f);
ms_ole_directory_enter (d);
return d;
}
......
......@@ -12,7 +12,14 @@
typedef guint32 BBPtr ;
typedef guint32 SBPtr ;
typedef struct _MS_OLE_HEADER
/* Forward declarations of types */
typedef struct _MS_OLE MS_OLE;
typedef struct _MS_OLE_HEADER MS_OLE_HEADER;
typedef struct _MS_OLE_STREAM MS_OLE_STREAM;
typedef struct _MS_OLE_DIRECTORY MS_OLE_DIRECTORY;
struct _MS_OLE_HEADER
{
/* sbd = Small Block Depot ( made up of BB's BTW ) */
BBPtr sbd_startblock ;
......@@ -23,7 +30,7 @@ typedef struct _MS_OLE_HEADER
BBPtr root_startblock ;
GArray *root_list;
} MS_OLE_HEADER ;
};
typedef guint32 PPS_IDX ;
typedef enum _PPS_TYPE { MS_OLE_PPS_STORAGE = 1,
......@@ -33,7 +40,7 @@ typedef enum _PPS_TYPE { MS_OLE_PPS_STORAGE = 1,
/**
* Structure describing an OLE file
**/
typedef struct _MS_OLE
struct _MS_OLE
{
guint8 *mem ;
guint32 length ;
......@@ -44,15 +51,17 @@ typedef struct _MS_OLE
char mode;
MS_OLE_HEADER header ; /* For speed cut down dereferences */
int file_descriptor ;
} MS_OLE ;
};
/* Create new OLE file */
extern MS_OLE *ms_ole_create (const char *name) ;
extern MS_OLE *ms_ole_create (const char *name) ;
/* Open existing OLE file */
extern MS_OLE *ms_ole_new (const char *name) ;
extern void ms_ole_destroy (MS_OLE *ptr) ;
extern MS_OLE *ms_ole_new (const char *name) ;
/* Get a root directory handle */
extern MS_OLE_DIRECTORY *ms_ole_get_root (MS_OLE *);
extern void ms_ole_destroy (MS_OLE *ptr) ;
typedef struct _MS_OLE_DIRECTORY
struct _MS_OLE_DIRECTORY
{
char *name ;
PPS_TYPE type ;
......@@ -63,20 +72,21 @@ typedef struct _MS_OLE_DIRECTORY
/* Private */
MS_OLE *file ;
} MS_OLE_DIRECTORY ;
};
extern MS_OLE_DIRECTORY *ms_ole_directory_new (MS_OLE *) ;
extern int ms_ole_directory_next (MS_OLE_DIRECTORY *) ;
extern void ms_ole_directory_enter (MS_OLE_DIRECTORY *) ;
/* Pointer to the directory in which to create a new stream / storage object */
extern MS_OLE_DIRECTORY *ms_ole_directory_create (MS_OLE_DIRECTORY *d, char *name, PPS_TYPE type) ;
extern MS_OLE_DIRECTORY *ms_ole_directory_get_root (MS_OLE *);
extern MS_OLE_DIRECTORY *ms_ole_directory_create (MS_OLE_DIRECTORY *d,
char *name,
PPS_TYPE type) ;
extern void ms_ole_directory_unlink (MS_OLE_DIRECTORY *) ;
extern void ms_ole_directory_destroy (MS_OLE_DIRECTORY *) ;
typedef enum { MS_OLE_SEEK_SET, MS_OLE_SEEK_CUR } ms_ole_seek_t;
typedef struct _MS_OLE_STREAM
struct _MS_OLE_STREAM
{
GArray *blocks; /* A list of the blocks in the file if NULL: no file */
#ifdef G_HAVE_GINT64
......@@ -114,7 +124,7 @@ typedef struct _MS_OLE_STREAM
**/
MS_OLE *file ;
PPS_IDX pps ;
} MS_OLE_STREAM ;
};
/* Mode = 'r' or 'w' */
extern MS_OLE_STREAM *ms_ole_stream_open (MS_OLE_DIRECTORY *d, char mode) ;
......
......@@ -15,6 +15,7 @@
#include <assert.h>
#include <ctype.h>
#include <glib.h>
#include "ms-ole.h"
#include "ms-biff.h"
#include "biff-types.h"
......@@ -327,14 +328,32 @@ ms_biff_put_len_next (BIFF_PUT *bp, guint16 opcode, guint32 len)
bp->padding = 0;
bp->num_merges = 0;
bp->streamPos = bp->pos->position;
return 0;
bp->data = g_new (guint8, len);
return bp->data;
}
void
ms_biff_put_len_commit (BIFF_PUT *bp)
{
guint8 tmp[4];
g_return_if_fail (bp);
g_return_if_fail (bp->pos);
g_return_if_fail (bp->len_fixed);
g_return_if_fail (bp->data);
g_return_if_fail (bp->length < MAX_LIKED_BIFF_LEN);
/* if (!bp->data_malloced) Unimplemented optimisation
bp->pos->lseek (bp->pos, bp->length, MS_OLE_SEEK_CUR);
else */
BIFF_SET_GUINT16 (tmp, (bp->ms_op<<8) + bp->ls_op);
BIFF_SET_GUINT16 (tmp, bp->length);
bp->pos->write (bp->pos, tmp, 4);
bp->pos->write (bp->pos, bp->data, bp->length);
g_free (bp->data);
bp->data = 0 ;
}
void
......@@ -349,7 +368,10 @@ ms_biff_put_var_next (BIFF_PUT *bp, guint16 opcode)
bp->padding = ms_bug_get_padding (opcode);
bp->num_merges = 0;
bp->length = 0;
bp->data = 0;
bp->streamPos = bp->pos->position;
bp->pos->lseek (bp->pos, 4, MS_OLE_SEEK_CUR); /* Leave for header */
}
void
ms_biff_put_var_write (BIFF_PUT *bp, guint8 *data, guint32 len)
......@@ -358,11 +380,26 @@ ms_biff_put_var_write (BIFF_PUT *bp, guint8 *data, guint32 len)
g_return_if_fail (data);
g_return_if_fail (bp->pos);
g_return_if_fail (!bp->len_fixed);
/* Temporary */
g_return_if_fail (bp->length+len < 0xf000);
bp->pos->write (bp->pos, data, len);
bp->length+= len;
}
void
ms_biff_put_var_commit (BIFF_PUT *bp)
{
guint8 tmp[4];
g_return_if_fail (bp);
g_return_if_fail (bp->pos);
g_return_if_fail (!bp->len_fixed);
g_return_if_fail (!bp->data);
bp->pos->lseek (bp->pos, -4-bp->length, MS_OLE_SEEK_CUR);
BIFF_SET_GUINT16 (tmp, (bp->ms_op<<8) + bp->ls_op);
BIFF_SET_GUINT16 (tmp, bp->length);
bp->pos->write (bp->pos, tmp, 4);
}
......@@ -21,6 +21,14 @@ typedef guint64 DLONG;
(*((const BYTE *)(p)+3)<<24))
#define BIFF_GETDLONG(p) (BIFF_GETLONG(p) | (((DLONG)BIFF_GETLONG((const BYTE *)(p)+4))<<32))
#define BIFF_SET_GUINT8(p,n) (*((guint8 *)(p)+0)=n)
#define BIFF_SET_GUINT16(p,n) ((*((guint8 *)(p)+0)=((n)&0xff)), \
(*((guint8 *)(p)+1)=((n)>>8)&0xff))
#define BIFF_SET_GUINT32(p,n) ((*((guint8 *)(p)+0)=((n))&0xff), \
(*((guint8 *)(p)+1)=((n)>>8)&0xff), \
(*((guint8 *)(p)+2)=((n)>>16)&0xff), \
(*((guint8 *)(p)+3)=((n)>>24)&0xff))
double biff_getdouble(guint8 *p);
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
......@@ -78,6 +86,7 @@ typedef struct _BIFF_PUT
guint32 streamPos;
guint16 num_merges;
gint16 padding;
int data_malloced;
int len_fixed;
MS_OLE_STREAM *pos;
} BIFF_PUT;
......
......@@ -28,6 +28,7 @@
#include "sheet-object.h"
#include "style.h"
#include "excel.h"
#include "ms-ole.h"
#include "ms-biff.h"
#include "ms-formula.h"
......
......@@ -14,12 +14,7 @@
#define EX_GETXF(p) (BIFF_GETWORD(p->data + 4))
#define EX_GETSTRLEN(p) (BIFF_GETWORD(p->data + 6))
/* Version info types as found in various Biff records */
typedef enum _eBiff_version { eBiffV2=2, eBiffV3=3,
eBiffV4=4, eBiffV5=5,
eBiffV7=7,
eBiffV8=8, eBiffVUnknown=0} eBiff_version ;
typedef enum _eBiff_filetype { eBiffTWorkbook=0, eBiffTVBModule=1, eBiffTWorksheet=2,
eBiffTChart=3, eBiffTMacrosheet=4, eBiffTWorkspace=5,
eBiffTUnknown=6 } eBiff_filetype ;
......@@ -53,8 +48,8 @@ typedef struct _BIFF_BOF_DATA
eBiff_filetype type ;
} BIFF_BOF_DATA ;
extern BIFF_BOF_DATA *new_ms_biff_bof_data (BIFF_QUERY *pos) ;
extern void free_ms_biff_bof_data (BIFF_BOF_DATA *data) ;
extern BIFF_BOF_DATA *new_ms_biff_bof_data (BIFF_QUERY *pos) ;
extern void free_ms_biff_bof_data (BIFF_BOF_DATA *data) ;
#include "biff-types.h"
......
......@@ -25,10 +25,10 @@
#include "style.h"
#include "main.h"
#include "excel.h"
#include "ms-ole.h"
#include "ms-biff.h"
#include "ms-formula.h"
#include "excel.h"
#include "ms-excel.h"
#include "ms-obj.h"
#include "ms-escher.h"
......
......@@ -31,8 +31,37 @@
#include "excel.h"
#include "ms-excel-write.h"
void
ms_excel_write_workbook (MS_OLE *file, Workbook *wb)
int
ms_excel_write_workbook (MS_OLE *file, Workbook *wb,
eBiff_version ver)
{
MS_OLE_DIRECTORY *dir;
MS_OLE_STREAM *str;
BIFF_PUT *bp;
g_return_val_if_fail (ver>=eBiffV7, 0);
if (!file || !wb) {
printf ("Can't write Null pointers\n");
return 0;
}
dir = ms_ole_directory_create (ms_ole_get_root (file),
"Workbook",
MS_OLE_PPS_STREAM);
if (!dir) {
printf ("Can't create stream\n");
return 0;
}
str = ms_ole_stream_open (dir, 'w');
if (!str) {
printf ("Can't open stream for writing\n");
return 0;
}
bp = ms_biff_put_new (str);
ms_biff_put_destroy (bp);
return 1;
}
......@@ -25,10 +25,10 @@
#include "style.h"
#include "main.h"
#include "excel.h"
#include "ms-ole.h"
#include "ms-biff.h"
#include "ms-formula.h"
#include "excel.h"
#include "ms-excel.h"
#include "ms-obj.h"
#include "ms-escher.h"
......
......@@ -14,8 +14,9 @@
#include "utils.h"
#include "excel.h"
#include "ms-biff.h"
#include "ms-excel.h"
#include "ms-excel-biff.h"
#include "ms-formula.h"
#define FORMULA_DEBUG 0
......@@ -602,11 +603,43 @@ parse_list_free (PARSE_LIST **list)
static void
make_inter_sheet_ref (MS_EXCEL_WORKBOOK *wb, guint16 extn_idx, CellRef *a, CellRef *b)
{
g_return_if_fail (wb);
g_return_if_fail (a);
a->sheet = biff_get_externsheet_name (wb, extn_idx, 1) ;
if (b)
b->sheet = biff_get_externsheet_name (wb, extn_idx, 0) ;
}
static void
make_inter_sheet_ref_v7 (MS_EXCEL_WORKBOOK *wb, guint16 extn_idx,
guint16 first, guint16 second, CellRef *a, CellRef *b)
{
MS_EXCEL_SHEET *sheet;
g_return_if_fail (wb);
g_return_if_fail (a);
if ((gint16)extn_idx>0) {
printf ("FIXME: BIFF 7 ExternSheet 3D ref\n");
return;
}
g_return_if_fail (wb->excel_sheets);
g_return_if_fail (first<wb->excel_sheets->len);
sheet = g_ptr_array_index (wb->excel_sheets, first);
g_return_if_fail (sheet);
a->sheet = sheet->gnum_sheet;
if (b) {
g_return_if_fail (second < wb->excel_sheets->len);
sheet = g_ptr_array_index (wb->excel_sheets, second);
g_return_if_fail (sheet);
b->sheet = sheet->gnum_sheet;
}
}
static gboolean
make_function (PARSE_LIST **stack, int fn_idx, int numargs)
{
......@@ -753,17 +786,21 @@ ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, guint8 *mem,
make_inter_sheet_ref (sheet->wb, extn_idx, ref, 0) ;
parse_list_push (&stack, expr_tree_cellref (ref));
ptg_length = 6 ;
}
else
{
printf ("FIXME: Biff V7 3D refs are ugly !\n") ;
error = 1 ;
ref = 0 ;
ptg_length = 16 ;
} else {
guint16 extn_idx, first_idx, second_idx;
ref = getRefV7 (sheet, BIFF_GETBYTE(cur+16), BIFF_GETWORD(cur+14),
fn_col, fn_row, 0) ;
extn_idx = BIFF_GETWORD(cur);
first_idx = BIFF_GETWORD(cur + 10);
second_idx = BIFF_GETWORD(cur + 12);
make_inter_sheet_ref_v7 (sheet->wb, extn_idx, first_idx, second_idx, ref, 0) ;
parse_list_push (&stack, expr_tree_cellref (ref));
ptg_length = 17 ;
}
if (ref) g_free (ref) ;
break ;
}
break ;
case FORMULA_PTG_AREA_3D: /* see S59E2B.HTM */
{
CellRef *first=0, *last=0 ;
......@@ -780,11 +817,19 @@ ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, guint8 *mem,
make_inter_sheet_ref (sheet->wb, extn_idx, first, last) ;
parse_list_push_raw (&stack, value_new_cellrange (first, last));
ptg_length = 10 ;
}
else
{
printf ("FIXME: Biff V7 3D refs are ugly !\n") ;
error = 1 ;
} else {
guint16 extn_idx, first_idx, second_idx;
first = getRefV7 (sheet, BIFF_GETBYTE(cur+18), BIFF_GETWORD(cur+14),
fn_col, fn_row, 0) ;
last = getRefV7 (sheet, BIFF_GETBYTE(cur+19), BIFF_GETWORD(cur+16),
fn_col, fn_row, 0) ;
extn_idx = BIFF_GETWORD(cur);
first_idx = BIFF_GETWORD(cur + 10);
second_idx = BIFF_GETWORD(cur + 12);
make_inter_sheet_ref_v7 (sheet->wb, extn_idx, first_idx,
second_idx, first, last) ;
parse_list_push_raw (&stack, value_new_cellrange (first, last));
ptg_length = 20 ;
}
if (first) g_free (first) ;
......
......@@ -14,8 +14,9 @@
#include "utils.h"
#include "excel.h"
#include "ms-biff.h"
#include "ms-excel.h"
#include "ms-excel-biff.h"
#include "ms-formula.h"
#define FORMULA_DEBUG 0
......@@ -602,11 +603,43 @@ parse_list_free (PARSE_LIST **list)
static void
make_inter_sheet_ref (MS_EXCEL_WORKBOOK *wb, guint16 extn_idx, CellRef *a, CellRef *b)
{
g_return_if_fail (wb);
g_return_if_fail (a);
a->sheet = biff_get_externsheet_name (wb, extn_idx, 1) ;
if (b)
b->sheet = biff_get_externsheet_name (wb, extn_idx, 0) ;
}
static void
make_inter_sheet_ref_v7 (MS_EXCEL_WORKBOOK *wb, guint16 extn_idx,
guint16 first, guint16 second, CellRef *a, CellRef *b)
{
MS_EXCEL_SHEET *sheet;
g_return_if_fail (wb);
g_return_if_fail (a);
if ((gint16)extn_idx>0) {
printf ("FIXME: BIFF 7 ExternSheet 3D ref\n");
return;
}
g_return_if_fail (wb->excel_sheets);
g_return_if_fail (first<wb->excel_sheets->len);
sheet = g_ptr_array_index (wb->excel_sheets, first);
g_return_if_fail (sheet);
a->sheet = sheet->gnum_sheet;
if (b) {
g_return_if_fail (second < wb->excel_sheets->len);
sheet = g_ptr_array_index (wb->excel_sheets, second);
g_return_if_fail (sheet);
b->sheet = sheet->gnum_sheet;
}
}
static gboolean
make_function (PARSE_LIST **stack, int fn_idx, int numargs)
{
......@@ -753,17 +786,21 @@ ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, guint8 *mem,
make_inter_sheet_ref (sheet->wb, extn_idx, ref, 0) ;
parse_list_push (&stack, expr_tree_cellref (ref));
ptg_length = 6 ;
}
else
{
printf ("FIXME: Biff V7 3D refs are ugly !\n") ;
error = 1 ;
ref = 0 ;
ptg_length = 16 ;
} else {
guint16 extn_idx, first_idx, second_idx;
ref = getRefV7 (sheet, BIFF_GETBYTE(cur+16), BIFF_GETWORD(cur+14),
fn_col, fn_row, 0) ;
extn_idx = BIFF_GETWORD(cur);
first_idx = BIFF_GETWORD(cur + 10);
second_idx = BIFF_GETWORD(cur + 12);
make_inter_sheet_ref_v7 (sheet->wb, extn_idx, first_idx, second_idx, ref, 0) ;
parse_list_push (&stack, expr_tree_cellref (ref));
ptg_length = 17 ;
}
if (ref) g_free (ref) ;
break ;
}
break ;
case FORMULA_PTG_AREA_3D: /* see S59E2B.HTM */
{
CellRef *first=0, *last=0 ;
......@@ -780,11 +817,19 @@ ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, guint8 *mem,
make_inter_sheet_ref (sheet->wb, extn_idx, first, last) ;
parse_list_push_raw (&stack, value_new_cellrange (first, last));
ptg_length = 10 ;
}
else
{
printf ("FIXME: Biff V7 3D refs are ugly !\n") ;
error = 1 ;
} else {
guint16 extn_idx, first_idx, second_idx;
first = getRefV7 (sheet, BIFF_GETBYTE(cur+18), BIFF_GETWORD(cur+14),
fn_col, fn_row, 0) ;
last = getRefV7 (sheet, BIFF_GETBYTE(cur+19), BIFF_GETWORD(cur+16),
fn_col, fn_row, 0) ;
extn_idx = BIFF_GETWORD(cur);
first_idx = BIFF_GETWORD(cur + 10);
second_idx = BIFF_GETWORD(cur + 12);
make_inter_sheet_ref_v7 (sheet->wb, extn_idx, first_idx,
second_idx, first, last) ;
parse_list_push_raw (&stack, value_new_cellrange (first, last));
ptg_length = 20 ;
}
if (first) g_free (first) ;
......
......@@ -25,7 +25,7 @@
#include "sheet-object.h"
#include "style.h"
#include "ms-ole.h"
#include "excel.h"
#include "ms-biff.h"
#include "ms-excel.h"
#include "ms-excel-biff.h"
......
......@@ -442,7 +442,7 @@ really_put (MS_OLE *ole, char *from, char *to)
}
if (!(dir = get_file_handle (ole, to)))
dir = ms_ole_directory_create (ms_ole_directory_get_root(ole),
dir = ms_ole_directory_create (ms_ole_get_root(ole),
to, MS_OLE_PPS_STREAM);
if (dir)
......
......@@ -15,6 +15,8 @@
#include "func.h"
#include "utils.h"
Value *value_zero = NULL;
ExprTree *
expr_parse_string (const char *expr, Sheet *sheet, int col, int row,
const char **desired_format, char **error_msg)
......@@ -492,9 +494,14 @@ value_area_get_width (Value *v)
if (v->type == VALUE_ARRAY)
return v->v.array.x;
else
return v->v.cell_range.cell_b.col -
v->v.cell_range.cell_a.col + 1;
else {
guint ans = v->v.cell_range.cell_b.col -
v->v.cell_range.cell_a.col + 1;
if (v->v.cell_range.cell_a.sheet &&
v->v.cell_range.cell_a.sheet->max_col_used < ans)
ans = v->v.cell_range.cell_a.sheet->max_col_used+1;
return ans;
}
}
guint
......@@ -506,9 +513,14 @@ value_area_get_height (Value *v)
if (v->type == VALUE_ARRAY)
return v->v.array.y;
else
return v->v.cell_range.cell_b.row -
v->v.cell_range.cell_a.row + 1;
else {
guint ans = v->v.cell_range.cell_b.row -
v->v.cell_range.cell_a.row + 1;
if (v->v.cell_range.cell_a.sheet &&
v->v.cell_range.cell_a.sheet->max_row_used < ans)
ans = v->v.cell_range.cell_a.sheet->max_row_used+1;
return ans;
}
}
const Value *
......@@ -530,18 +542,17 @@ value_area_get_at_x_y (Value *v, guint x, guint y)
a = &v->v.cell_range.cell_a;
b = &v->v.cell_range.cell_b;
g_return_val_if_fail (!a->col_relative,
value_new_int (0));
g_return_val_if_fail (!b->col_relative,
value_new_int (0));
g_return_val_if_fail (!a->row_relative,
value_new_int (0));
g_return_val_if_fail (!b->row_relative,
value_new_int (0));
g_return_val_if_fail (a->col<=b->col,
value_new_int (0));
g_return_val_if_fail (a->row<=b->row,
value_new_int (0));
g_return_val_if_fail (!a->col_relative, value_zero);
g_return_val_if_fail (!b->col_relative, value_zero);
g_return_val_if_fail (!a->row_relative, value_zero);
g_return_val_if_fail (!b->row_relative, value_zero);
g_return_val_if_fail (a->col<=b->col, value_zero);
g_return_val_if_fail (a->row<=b->row, value_zero);
/* Speedup */
if (a->sheet->max_col_used < a->col+x ||
a->sheet->max_row_used < a->row+y)
return value_zero;
cell = sheet_cell_get (a->sheet, a->col+x, a->row+y);
......@@ -549,8 +560,7 @@ value_area_get_at_x_y (Value *v, guint x, guint y)
return cell