Commit 83447b57 authored by Michael Meeks's avatar Michael Meeks

Array support from Excel -> Strings,

Re-engineered Value array support -> Value *s.
parent a348468a
1999-05-15 Michael Meeks <michael@imaginator.com>
* src/parser.c (value_dump): Updated Arrays, to use Value *
* src/func.c (function_iterate_do_value): same.
* src/fn-sheet.c (gnumeric_selection): same.
* src/eval.c (add_value_deps): same.
* src/expr.c (value_get_as_string): Major re-work of ARRAY
conversion.
(value_array_set): Fix rather embarassing bug in assertions.
(eval_cell_value): Return top left corner of array, seems to be
what excel does.
(value_release, value_array_set, value_array_new),
(value_array_copy_to, value_array_resize):
Updated value->v.array to Value *'s saves much hassle !
1999-05-14 Michael Meeks <michael@imaginator.com>
* src/expr.c (value_area_get_width, value_area_get_height):
......
1999-05-15 Michael Meeks <michael@imaginator.com>
* src/parser.c (value_dump): Updated Arrays, to use Value *
* src/func.c (function_iterate_do_value): same.
* src/fn-sheet.c (gnumeric_selection): same.
* src/eval.c (add_value_deps): same.
* src/expr.c (value_get_as_string): Major re-work of ARRAY
conversion.
(value_array_set): Fix rather embarassing bug in assertions.
(eval_cell_value): Return top left corner of array, seems to be
what excel does.
(value_release, value_array_set, value_array_new),
(value_array_copy_to, value_array_resize):
Updated value->v.array to Value *'s saves much hassle !
1999-05-14 Michael Meeks <michael@imaginator.com>
* src/expr.c (value_area_get_width, value_area_get_height):
......
1999-05-15 Michael Meeks <michael@imaginator.com>
* src/parser.c (value_dump): Updated Arrays, to use Value *
* src/func.c (function_iterate_do_value): same.
* src/fn-sheet.c (gnumeric_selection): same.
* src/eval.c (add_value_deps): same.
* src/expr.c (value_get_as_string): Major re-work of ARRAY
conversion.
(value_array_set): Fix rather embarassing bug in assertions.
(eval_cell_value): Return top left corner of array, seems to be
what excel does.
(value_release, value_array_set, value_array_new),
(value_array_copy_to, value_array_resize):
Updated value->v.array to Value *'s saves much hassle !
1999-05-14 Michael Meeks <michael@imaginator.com>
* src/expr.c (value_area_get_width, value_area_get_height):
......
1999-05-15 Michael Meeks <michael@imaginator.com>
* src/parser.c (value_dump): Updated Arrays, to use Value *
* src/func.c (function_iterate_do_value): same.
* src/fn-sheet.c (gnumeric_selection): same.
* src/eval.c (add_value_deps): same.
* src/expr.c (value_get_as_string): Major re-work of ARRAY
conversion.
(value_array_set): Fix rather embarassing bug in assertions.
(eval_cell_value): Return top left corner of array, seems to be
what excel does.
(value_release, value_array_set, value_array_new),
(value_array_copy_to, value_array_resize):
Updated value->v.array to Value *'s saves much hassle !
1999-05-14 Michael Meeks <michael@imaginator.com>
* src/expr.c (value_area_get_width, value_area_get_height):
......
1999-05-14 Michael Meeks <michael@imaginator.com>
* ms-formula.c (ms_excel_parse_formula): Finaly got the ARRAY
docs sorted, deciphered inconsistancies etc.
1999-05-14 Michael Meeks <michael@imaginator.com>
* ms-formula.c (ms_excel_parse_formula): Implemented V7. 3D refs
......
......@@ -715,6 +715,7 @@ ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, guint8 *mem,
int len_left = length ;
guint8 *cur = mem + 1 ; /* this is so that the offsets and lengths
are identical to those in the documentation */
guint8 *array_data = mem + 3 + length; /* Sad but true */
PARSE_LIST *stack = NULL;
int error = 0 ;
char *ans ;
......@@ -864,41 +865,54 @@ ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, guint8 *mem,
case FORMULA_PTG_ARRAY:
{
Value *v;
guint16 cols=BIFF_GETBYTE(cur+0);
guint16 rows=BIFF_GETWORD(cur+1);
guint32 cols=BIFF_GETBYTE(cur+0)+1; /* NB. the spec. is wrong here, these */
guint32 rows=BIFF_GETWORD(cur+1)+1; /* are zero offset numbers */
guint16 lpx,lpy;
guint8 *data=cur+3;
if (cols==0) cols=256;
v = value_array_new (cols, rows);
ptg_length = 3;
ptg_length = 7;
#if FORMULA_DEBUG > 1
printf ("An Array how interesting: (%d,%d)\n", cols, rows);
dump (mem, length);
#endif
for (lpy=0;lpy<rows;lpy++) {
for (lpx=0;lpx<cols;lpx++) {
guint8 opts=BIFF_GETBYTE(data);
Value *set_val=0;
guint8 opts=BIFF_GETBYTE(array_data);
#if FORMULA_DEBUG > 0
printf ("Opts 0x%x\n", opts);
#endif
if (opts == 1) {
value_array_set (v, lpx, lpy,
value_new_float (BIFF_GETDOUBLE(data+1)));
data+=9;
ptg_length+=9;
set_val = value_new_float (BIFF_GETDOUBLE(array_data+1));
array_data+=9;
} else if (opts == 2) {
guint32 len;
char *str = biff_get_text (data+2,
BIFF_GETBYTE(data+1),
&len);
value_array_set (v, lpx, lpy, value_new_string (str));
g_free (str);
data+=len+2;
ptg_length+=2+len;
char *str;
if (sheet->ver >= eBiffV8) { /* Cunningly not mentioned in spec. ! */
str = biff_get_text (array_data+3,
BIFF_GETWORD(array_data+1),
&len);
array_data+=len+3;
} else {
str = biff_get_text (array_data+2,
BIFF_GETBYTE(array_data+1),
&len);
array_data+=len+2;
}
if (str) {
set_val = value_new_string (str);
printf ("String '%s'\n", str);
g_free (str);
} else
set_val = value_new_string ("");
} else {
printf ("Duff type\n");
printf ("FIXME: Duff array item type\n");
break;
}
value_array_set (v, lpx, lpy, set_val);
}
}
ptg_length+=7;
parse_list_push_raw (&stack, v);
break;
}
......
......@@ -715,6 +715,7 @@ ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, guint8 *mem,
int len_left = length ;
guint8 *cur = mem + 1 ; /* this is so that the offsets and lengths
are identical to those in the documentation */
guint8 *array_data = mem + 3 + length; /* Sad but true */
PARSE_LIST *stack = NULL;
int error = 0 ;
char *ans ;
......@@ -864,41 +865,54 @@ ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, guint8 *mem,
case FORMULA_PTG_ARRAY:
{
Value *v;
guint16 cols=BIFF_GETBYTE(cur+0);
guint16 rows=BIFF_GETWORD(cur+1);
guint32 cols=BIFF_GETBYTE(cur+0)+1; /* NB. the spec. is wrong here, these */
guint32 rows=BIFF_GETWORD(cur+1)+1; /* are zero offset numbers */
guint16 lpx,lpy;
guint8 *data=cur+3;
if (cols==0) cols=256;
v = value_array_new (cols, rows);
ptg_length = 3;
ptg_length = 7;
#if FORMULA_DEBUG > 1
printf ("An Array how interesting: (%d,%d)\n", cols, rows);
dump (mem, length);
#endif
for (lpy=0;lpy<rows;lpy++) {
for (lpx=0;lpx<cols;lpx++) {
guint8 opts=BIFF_GETBYTE(data);
Value *set_val=0;
guint8 opts=BIFF_GETBYTE(array_data);
#if FORMULA_DEBUG > 0
printf ("Opts 0x%x\n", opts);
#endif
if (opts == 1) {
value_array_set (v, lpx, lpy,
value_new_float (BIFF_GETDOUBLE(data+1)));
data+=9;
ptg_length+=9;
set_val = value_new_float (BIFF_GETDOUBLE(array_data+1));
array_data+=9;
} else if (opts == 2) {
guint32 len;
char *str = biff_get_text (data+2,
BIFF_GETBYTE(data+1),
&len);
value_array_set (v, lpx, lpy, value_new_string (str));
g_free (str);
data+=len+2;
ptg_length+=2+len;
char *str;
if (sheet->ver >= eBiffV8) { /* Cunningly not mentioned in spec. ! */
str = biff_get_text (array_data+3,
BIFF_GETWORD(array_data+1),
&len);
array_data+=len+3;
} else {
str = biff_get_text (array_data+2,
BIFF_GETBYTE(array_data+1),
&len);
array_data+=len+2;
}
if (str) {
set_val = value_new_string (str);
printf ("String '%s'\n", str);
g_free (str);
} else
set_val = value_new_string ("");
} else {
printf ("Duff type\n");
printf ("FIXME: Duff array item type\n");
break;
}
value_array_set (v, lpx, lpy, set_val);
}
}
ptg_length+=7;
parse_list_push_raw (&stack, v);
break;
}
......
......@@ -160,7 +160,7 @@ add_value_deps (Cell *cell, const Value *value)
for (x = 0; x < value->v.array.x; x++)
for (y = 0; y < value->v.array.y; y++)
add_value_deps (cell,
&value->v.array.vals [x][y]);
value->v.array.vals [x][y]);
break;
}
case VALUE_CELLRANGE:
......
......@@ -160,7 +160,7 @@ add_value_deps (Cell *cell, const Value *value)
for (x = 0; x < value->v.array.x; x++)
for (y = 0; y < value->v.array.y; y++)
add_value_deps (cell,
&value->v.array.vals [x][y]);
value->v.array.vals [x][y]);
break;
}
case VALUE_CELLRANGE:
......
......@@ -145,8 +145,35 @@ value_get_as_string (const Value *value)
case VALUE_FLOAT:
return g_strdup_printf ("%g", value->v.v_float);
case VALUE_ARRAY:
return g_strdup ("ARRAY");
case VALUE_ARRAY: {
GString *str = g_string_new ("{");
guint lpx, lpy;
char *ans;
for (lpy=0;lpy<value->v.array.y;lpy++) {
for (lpx=0;lpx<value->v.array.x;lpx++) {
const Value *v = value->v.array.vals[lpx][lpy];
g_return_val_if_fail (v->type == VALUE_STRING ||
v->type == VALUE_FLOAT ||
v->type == VALUE_INTEGER,
"Duff Array contents");
if (lpx)
g_string_sprintfa (str, ",");
if (v->type == VALUE_STRING)
g_string_sprintfa (str, "\"%s\"",
v->v.str->str);
else
g_string_sprintfa (str, "%g",
value_get_as_float (v));
}
if (lpy<value->v.array.y-1)
g_string_sprintfa (str, ";");
}
g_string_sprintfa (str, "}");
ans = str->str;
g_string_free (str, FALSE);
return ans;
}
case VALUE_CELLRANGE:
break;
......@@ -177,10 +204,13 @@ value_release (Value *value)
break;
case VALUE_ARRAY:{
guint i;
guint lpx, lpy;
for (i = 0; i < value->v.array.x; i++)
g_free (value->v.array.vals [i]);
for (lpx = 0; lpx < value->v.array.x; lpx++) {
for (lpy = 0; lpy < value->v.array.y; lpy++)
value_release (value->v.array.vals[lpx][lpy]);
g_free (value->v.array.vals [lpx]);
}
g_free (value->v.array.vals);
break;
......@@ -407,15 +437,12 @@ value_array_new (guint width, guint height)
v->type = VALUE_ARRAY;
v->v.array.x = width;
v->v.array.y = height;
v->v.array.vals = g_new (Value *, width);
v->v.array.vals = g_new (Value **, width);
for (x = 0; x < width; x++){
v->v.array.vals [x] = g_new (Value, height);
for (y = 0; y < height; y++){
v->v.array.vals[x][y].type = VALUE_INTEGER;
v->v.array.vals[x][y].v.v_int = 0;
}
v->v.array.vals [x] = g_new (Value *, height);
for (y = 0; y < height; y++)
v->v.array.vals[x][y] = value_new_int (0);
}
return v;
}
......@@ -424,20 +451,23 @@ void
value_array_set (Value *array, guint col, guint row, Value *v)
{
g_return_if_fail (v);
g_return_if_fail (v->type == VALUE_ARRAY);
g_return_if_fail (array->type == VALUE_ARRAY);
g_return_if_fail (col>=0);
g_return_if_fail (row>=0);
g_return_if_fail (v->v.array.y <= row);
g_return_if_fail (v->v.array.x <= col);
g_return_if_fail (array->v.array.y > row);
g_return_if_fail (array->v.array.x > col);
memcpy (&array->v.array.vals[col][row], v, sizeof (Value));
if (array->v.array.vals[col][row])
value_release (array->v.array.vals[col][row]);
array->v.array.vals[col][row] = v;
}
void
value_array_resize (Value *v, guint width, guint height)
{
int x, xcpy, ycpy;
int x, y, xcpy, ycpy;
Value *newval;
Value ***tmp;
g_return_if_fail (v);
g_return_if_fail (v->type == VALUE_ARRAY);
......@@ -454,34 +484,34 @@ value_array_resize (Value *v, guint width, guint height)
else
ycpy = height;
for (x = 0; x < xcpy; x++){
memcpy (newval->v.array.vals [x],
v->v.array.vals [x],
sizeof (Value) * ycpy);
}
for (x = 0; x < xcpy; x++)
for (y = 0; y < ycpy; y++)
value_array_set (newval, x, y, v->v.array.vals[x][y]);
tmp = v->v.array.vals;
v->v.array.vals = newval->v.array.vals;
newval->v.array.vals = tmp ;
value_release (newval);
v->v.array.x = width;
v->v.array.y = height;
value_release (newval);
}
void
value_array_copy_to (Value *v, const Value *src)
{
int x;
int x, y;
g_return_if_fail (src->type == VALUE_ARRAY);
v->type = VALUE_ARRAY;
v->v.array.x = src->v.array.x;
v->v.array.y = src->v.array.y;
v->v.array.vals = g_new (Value *, v->v.array.x);
for (x = 0; x < v->v.array.x; x++){
v->v.array.vals [x] = g_new (Value,v->v.array.y);
v->v.array.vals = g_new (Value **, v->v.array.x);
memcpy (v->v.array.vals [x],
src->v.array.vals [x],
sizeof(Value)*v->v.array.y);
for (x = 0; x < v->v.array.x; x++) {
v->v.array.vals [x] = g_new (Value *, v->v.array.y);
for (y = 0; y < v->v.array.y; y++)
v->v.array.vals [x][y] = value_duplicate (src->v.array.vals [x][y]);
}
}
......@@ -535,7 +565,7 @@ value_area_get_at_x_y (Value *v, guint x, guint y)
g_return_val_if_fail (v->v.array.x < x &&
v->v.array.y < y,
value_new_int (0));
return &v->v.array.vals [x][y];
return v->v.array.vals [x][y];
} else {
CellRef *a, *b;
Cell *cell;
......@@ -615,9 +645,9 @@ eval_cell_value (Sheet *sheet, Value *value)
break;
case VALUE_ARRAY:
g_warning ("VALUE_ARRAY not handled in eval_cell_value\n");
res->type = VALUE_INTEGER;
res->v.v_int = 0;
g_warning ("Check VALUE_ARRAY handling in eval_cell_value vs. Excel\n");
/* Return top left corner... */
res = value_duplicate (value->v.array.vals[0][0]);
break;
case VALUE_CELLRANGE:
......
......@@ -67,7 +67,7 @@ struct _Value {
struct {
int x, y ;
Value **vals; /* Array [x][y] */
Value ***vals; /* Array [x][y] */
} array ;
String *str;
Symbol *sym;
......
......@@ -47,7 +47,7 @@ gnumeric_selection (Sheet *sheet, GList *expr_node_list, int eval_col, int eval_
Value *single_value;
CellRef *cell_ref;
single_value = &value->v.array.vals [lp++][0];
single_value = value->v.array.vals [lp++][0];
single_value->type = VALUE_CELLRANGE;
/* Fill it in */
......
......@@ -89,7 +89,7 @@ function_iterate_do_value (Sheet *sheet,
ret = function_iterate_do_value (
sheet, callback, closure,
eval_col, eval_row,
&value->v.array.vals [x][y], error_string);
value->v.array.vals [x][y], error_string);
if (ret == FALSE)
return FALSE;
}
......
......@@ -47,7 +47,7 @@ gnumeric_selection (Sheet *sheet, GList *expr_node_list, int eval_col, int eval_
Value *single_value;
CellRef *cell_ref;
single_value = &value->v.array.vals [lp++][0];
single_value = value->v.array.vals [lp++][0];
single_value->type = VALUE_CELLRANGE;
/* Fill it in */
......
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