Commit 7e7b6e01 authored by Jody Goldberg's avatar Jody Goldberg Committed by Jody Goldberg

Implicit intersection is done.

Now all we need is implicit iteration for array formulas.
I've added a comment on a possible heuristic to use to evaluate the
which for of iteration to use.

1999-12-21  Jody Goldberg <jgoldberg@home.com>

	* src/expr.c (expr_implicit_intersection) : New routine split from
	  function_call_with_list.
	(compare) : Handle intersection.
	(eval_expr_real) : Ditto.  Add verbose comment on a possible heuristic
	  for the final piece of this ugly evaluation mechanism, array
	  interation.
	(cell_ref_get_abs_col_row) : Adjust to take a CellPos.

	* src/func.c (function_iterate_do_value) : Split the implicit
	  intersection out into a new function.  Use intersection for
	  strings as well as float & bool args.  Correct memory leak
	  when intersetion was used.
	(function_call_with_list) : Ditto.

	* *.c : Adjust to change in EvalPosition to use CellPos.

	* gnumeric.spec.in : Update the libglade dependancy.

	* src/workbook.c (wb_edit_key_pressed) : Do not select the current
	  cell address and do not move the cursor to the start of the cell
	  address when F4 is hit.
parent 2bc98e1e
1999-12-21 Jody Goldberg <jgoldberg@home.com>
* src/expr.c (expr_implicit_intersection) : New routine split from
function_call_with_list.
(compare) : Handle intersection.
(eval_expr_real) : Ditto. Add verbose comment on a possible heuristic
for the final piece of this ugly evaluation mechanism, array
interation.
(cell_ref_get_abs_col_row) : Adjust to take a CellPos.
* src/func.c (function_iterate_do_value) : Split the implicit
intersection out into a new function. Use intersection for
strings as well as float & bool args. Correct memory leak
when intersetion was used.
(function_call_with_list) : Ditto.
* *.c : Adjust to change in EvalPosition to use CellPos.
* gnumeric.spec.in : Update the libglade dependancy.
* src/workbook.c (wb_edit_key_pressed) : Do not select the current
cell address and do not move the cursor to the start of the cell
address when F4 is hit.
1999-12-20 Jody Goldberg <jgoldberg@home.com>
* src/parser.y : Clean up for byacc.
......
1999-12-21 Jody Goldberg <jgoldberg@home.com>
* src/expr.c (expr_implicit_intersection) : New routine split from
function_call_with_list.
(compare) : Handle intersection.
(eval_expr_real) : Ditto. Add verbose comment on a possible heuristic
for the final piece of this ugly evaluation mechanism, array
interation.
(cell_ref_get_abs_col_row) : Adjust to take a CellPos.
* src/func.c (function_iterate_do_value) : Split the implicit
intersection out into a new function. Use intersection for
strings as well as float & bool args. Correct memory leak
when intersetion was used.
(function_call_with_list) : Ditto.
* *.c : Adjust to change in EvalPosition to use CellPos.
* gnumeric.spec.in : Update the libglade dependancy.
* src/workbook.c (wb_edit_key_pressed) : Do not select the current
cell address and do not move the cursor to the start of the cell
address when F4 is hit.
1999-12-20 Jody Goldberg <jgoldberg@home.com>
* src/parser.y : Clean up for byacc.
......
......@@ -15,9 +15,8 @@ BuildRoot: /var/tmp/gnumeric-%{PACKAGE_VERSION}-root
Docdir: %{prefix}/doc
Requires: gnome-libs >= 1.0.0
Requires: guile >= 1.3
Requires: gnome-print >= 0.8
Requires: libglade >= 0.5
Requires: libglade >= 0.11
%description
GNOME (GNU Network Object Model Environment) is a user-friendly set of
......@@ -53,6 +52,10 @@ make prefix=$RPM_BUILD_ROOT%{prefix} sysconfdir=$RPM_BUILD_ROOT/etc install
rm -rf $RPM_BUILD_ROOT
%changelog
* Mon Dec 20 1999 Jody Goldberg <jgolbderg@home.com>
- Updated the libglade dependancy.
- Remove req for guile. We can build without it.
* Thu Sep 02 1999 Gregory McLean <gregm@comstar.net>
- Added small fix so glade generated dialogs appear.
......
......@@ -588,8 +588,7 @@ gnumeric_isblank (FunctionEvalInfo *ei, GList *expr_node_list)
CellRef const *ref = &expr->u.ref;
Sheet const *sheet = eval_sheet (ref->sheet, ei->pos.sheet);
int row, col;
cell_get_abs_col_row(ref, ei->pos.eval_col, ei->pos.eval_row,
&col, &row);
cell_get_abs_col_row(ref, &ei->pos.eval, &col, &row);
result = cell_is_blank(sheet_cell_get(sheet, col, row));
}
return value_new_bool (result);
......
......@@ -674,22 +674,21 @@ gnumeric_indirect (FunctionEvalInfo *ei, Value **args)
}
if (a1_style)
error = !cellref_a1_get (&ref, text, ei->pos.eval_col,
ei->pos.eval_row);
error = !cellref_a1_get (&ref, text, ei->pos.eval.col,
ei->pos.eval.row);
else
error = !cellref_r1c1_get (&ref, text, ei->pos.eval_col,
ei->pos.eval_row);
error = !cellref_r1c1_get (&ref, text, ei->pos.eval.col,
ei->pos.eval.row);
g_free (text);
if (error)
return value_new_error (&ei->pos, gnumeric_err_REF);
cell_get_abs_col_row (&ref, ei->pos.eval_col, ei->pos.eval_row,
&col, &row);
cell_get_abs_col_row (&ref, &ei->pos.eval, &col, &row);
dest_cell = sheet_cell_get (ei->pos.sheet, col, row);
calling_cell = sheet_cell_get (ei->pos.sheet,
ei->pos.eval_col, ei->pos.eval_row);
ei->pos.eval.col, ei->pos.eval.row);
/* A dependency on the indirection cell if we do not already depend on it */
cell_add_explicit_dependency (calling_cell, &ref);
......@@ -778,7 +777,7 @@ gnumeric_column (FunctionEvalInfo *ei, GList *nodes)
ExprTree *expr;
if (!nodes || !nodes->data)
return value_new_int (ei->pos.eval_col+1);
return value_new_int (ei->pos.eval.col+1);
expr = (ExprTree *)nodes->data;
......@@ -919,7 +918,7 @@ gnumeric_row (FunctionEvalInfo *ei, GList *nodes)
ExprTree *expr;
if (!nodes || !nodes->data)
return value_new_int (ei->pos.eval_row+1);
return value_new_int (ei->pos.eval.row+1);
expr = (ExprTree *)nodes->data;
......
......@@ -2512,7 +2512,7 @@ gnumeric_prob (FunctionEvalInfo *ei, Value **argv)
err = function_iterate_argument_values
(eval_pos_init(&ep, eval_sheet(ei->pos.sheet, ei->pos.sheet),
ei->pos.eval_col, ei->pos.eval_row),
ei->pos.eval.col, ei->pos.eval.row),
callback_function_make_list, &x_cl, expr_node_list,
TRUE);
......@@ -2530,7 +2530,7 @@ gnumeric_prob (FunctionEvalInfo *ei, Value **argv)
err = function_iterate_argument_values
(eval_pos_init(&ep, eval_sheet(ei->pos.sheet,
ei->pos.sheet),
ei->pos.eval_col, ei->pos.eval_row),
ei->pos.eval.col, ei->pos.eval.row),
callback_function_make_list, &prob_cl, expr_node_list,
TRUE);
......@@ -3713,7 +3713,7 @@ gnumeric_frequency (FunctionEvalInfo *ei, Value *argv[])
err = function_iterate_argument_values
(eval_pos_init(&ep, eval_sheet(ei->pos.sheet, ei->pos.sheet),
ei->pos.eval_col, ei->pos.eval_row),
ei->pos.eval.col, ei->pos.eval.row),
callback_function_make_list, &data_cl, expr_node_list,
TRUE);
......@@ -3730,7 +3730,7 @@ gnumeric_frequency (FunctionEvalInfo *ei, Value *argv[])
err = function_iterate_argument_values
(eval_pos_init(&ep, eval_sheet(ei->pos.sheet, ei->pos.sheet),
ei->pos.eval_col, ei->pos.eval_row),
ei->pos.eval.col, ei->pos.eval.row),
callback_function_make_list, &bin_cl, expr_node_list,
TRUE);
......
......@@ -299,8 +299,8 @@ func_scm_apply (FunctionEvalInfo *ei, GList *expr_node_list)
{
CellRef eval_cell;
eval_cell.col = ei->pos.eval_col;
eval_cell.row = ei->pos.eval_row;
eval_cell.col = ei->pos.eval.col;
eval_cell.row = ei->pos.eval.row;
eval_cell.col_relative = 0;
eval_cell.row_relative = 0;
eval_cell.sheet = NULL;
......
......@@ -166,12 +166,13 @@ static inline void
dependency_range_ctor (DependencyRange * const range, Cell const * const cell,
CellRef const * const a, CellRef const * const b)
{
int col = cell->col->pos;
int row = cell->row->pos;
CellPos pos;
pos.col = cell->col->pos;
pos.row = cell->row->pos;
/* Convert to absolute cordinates */
cell_get_abs_col_row (a, col, row, &range->range.start.col, &range->range.start.row);
cell_get_abs_col_row (b, col, row, &range->range.end.col, &range->range.end.row);
cell_get_abs_col_row (a, &pos, &range->range.start.col, &range->range.start.row);
cell_get_abs_col_row (b, &pos, &range->range.end.col, &range->range.end.row);
range->ref_count = 0;
if (b->sheet && a->sheet != b->sheet)
......
......@@ -166,12 +166,13 @@ static inline void
dependency_range_ctor (DependencyRange * const range, Cell const * const cell,
CellRef const * const a, CellRef const * const b)
{
int col = cell->col->pos;
int row = cell->row->pos;
CellPos pos;
pos.col = cell->col->pos;
pos.row = cell->row->pos;
/* Convert to absolute cordinates */
cell_get_abs_col_row (a, col, row, &range->range.start.col, &range->range.start.row);
cell_get_abs_col_row (b, col, row, &range->range.end.col, &range->range.end.row);
cell_get_abs_col_row (a, &pos, &range->range.start.col, &range->range.start.row);
cell_get_abs_col_row (b, &pos, &range->range.end.col, &range->range.end.row);
range->ref_count = 0;
if (b->sheet && a->sheet != b->sheet)
......
......@@ -17,8 +17,6 @@
#include "utils.h"
#include "ranges.h"
static Value *eval_expr_real (FunctionEvalInfo *s, ExprTree const *tree);
EvalPosition *
eval_pos_init (EvalPosition *eval_pos, Sheet *sheet, int col, int row)
{
......@@ -27,8 +25,8 @@ eval_pos_init (EvalPosition *eval_pos, Sheet *sheet, int col, int row)
g_return_val_if_fail (IS_SHEET (sheet), NULL);
eval_pos->sheet = sheet;
eval_pos->eval_col = col;
eval_pos->eval_row = row;
eval_pos->eval.col = col;
eval_pos->eval.row = row;
return eval_pos;
}
......@@ -108,8 +106,8 @@ func_eval_info_pos (FunctionEvalInfo *eval_info, const EvalPosition *eval_pos)
return func_eval_info_init (
eval_info,
eval_pos->sheet,
eval_pos->eval_col,
eval_pos->eval_row);
eval_pos->eval.col,
eval_pos->eval.row);
}
ExprTree *
......@@ -328,8 +326,8 @@ expr_tree_array_formula_corner (ExprTree const *expr, EvalPosition const *pos)
g_return_val_if_fail (pos->sheet != NULL, NULL);
corner = sheet_cell_get (pos->sheet,
pos->eval_col - expr->u.array.x,
pos->eval_row - expr->u.array.y);
pos->eval.col - expr->u.array.x,
pos->eval.row - expr->u.array.y);
((ExprTree *)expr)->u.array.corner.cell = corner;
}
......@@ -445,6 +443,55 @@ eval_funcall (FunctionEvalInfo *ei, ExprTree const *tree)
return function_call_with_list (ei, args);
}
/**
* expr_implicit_intersection :
* @ei: EvalInfo containing valid fd!
* @v: a VALUE_CELLRANGE
*
* Attempt to find the intersection between the calling cell and
* some element of the 1 one unit wide or tall range.
*
* Always release the value passed in.
*
* Return value:
* If the intersection succeeded return a duplicate of the value
* at the intersection point. This value needs to be freed.
**/
Value *
expr_implicit_intersection (EvalPosition const * const pos,
Value * const v)
{
/*
* Handle the implicit union of a single row or
* column with the eval position.
* NOTE : We do not need to know if this is expression is
* being evaluated as an array or not because we can differentiate
* based on the required type for the argument.
*/
Value *res = NULL;
CellRef const * const a = & v->v.cell_range.cell_a;
CellRef const * const b = & v->v.cell_range.cell_b;
if (a->sheet == b->sheet) {
int a_col, a_row, b_col, b_row;
cell_get_abs_col_row (a, &pos->eval, &a_col, &a_row);
cell_get_abs_col_row (b, &pos->eval, &b_col, &b_row);
if (a_row == b_row) {
int const c = pos->eval.col;
if (a_col <= c && c <= b_col)
res = value_duplicate (value_area_get_x_y (pos, v, c - a_col, 0));
}
if (a_col == b_col) {
int const r = pos->eval.row;
if (a_row <= r && r <= b_row)
res = value_duplicate (value_area_get_x_y (pos, v, 0, r - a_row));
}
}
value_release (v);
return res;
}
typedef enum {
IS_EQUAL,
IS_LESS,
......@@ -491,9 +538,12 @@ compare_float_float (Value const * const va, Value const * const vb)
/*
* Compares two (Value *) and returns one of compare_t
*
* if pos is non null it will perform implict intersection for
* cellranges.
*/
static compare_t
compare (const Value *a, const Value *b)
compare (Value const * const a, Value const * const b)
{
ValueType ta, tb;
......@@ -527,10 +577,6 @@ compare (const Value *a, const Value *b)
return IS_LESS;
}
default :
/*
* TODO : Add implicit intersection here if not in
* array mode
* */
return TYPE_MISMATCH;
}
} else if (tb == VALUE_STRING) {
......@@ -544,10 +590,6 @@ compare (const Value *a, const Value *b)
return IS_GREATER;
default :
/*
* TODO : Add implicit intersection here if not in
* array mode
* */
return TYPE_MISMATCH;
}
}
......@@ -590,12 +632,8 @@ eval_range (FunctionEvalInfo *s, Value *v)
int r, c;
int const gen = s->pos.sheet->workbook->generation;
cell_get_abs_col_row (a,
s->pos.eval_col, s->pos.eval_row,
&start_col, &start_row);
cell_get_abs_col_row (b,
s->pos.eval_col, s->pos.eval_row,
&end_col, &end_row);
cell_get_abs_col_row (a, &s->pos.eval, &start_col, &start_row);
cell_get_abs_col_row (b, &s->pos.eval, &end_col, &end_row);
if (a->sheet != b->sheet) {
g_warning ("3D references not-fully supported.\n"
......@@ -613,18 +651,13 @@ eval_range (FunctionEvalInfo *s, Value *v)
}
static Value *
eval_expr_real (FunctionEvalInfo *s, ExprTree const *tree)
eval_expr_real (FunctionEvalInfo * const s, ExprTree const * const tree)
{
Value *res = NULL, *a = NULL, *b = NULL;
g_return_val_if_fail (tree != NULL, NULL);
g_return_val_if_fail (s != NULL, NULL);
/* FIXME FIXME : We need to rework support for
* ranges and builtin operators to support the
* implicit intersection rule AND figure out
* how to turn it off when evaluating as an array
*/
switch (tree->oper){
case OPER_EQUAL:
case OPER_NOT_EQUAL:
......@@ -635,14 +668,30 @@ eval_expr_real (FunctionEvalInfo *s, ExprTree const *tree)
int comp;
a = eval_expr_real (s, tree->u.binary.value_a);
if (a != NULL && a->type == VALUE_ERROR)
return a;
if (a != NULL) {
if (a->type == VALUE_CELLRANGE) {
a = expr_implicit_intersection (&s->pos, a);
if (a == NULL)
return value_new_error (&s->pos, gnumeric_err_VALUE);
} else if (a->type == VALUE_ERROR)
return a;
}
b = eval_expr_real (s, tree->u.binary.value_b);
if (b != NULL && b->type == VALUE_ERROR) {
if (a != NULL)
value_release (a);
return b;
if (b != NULL) {
Value *res = NULL;
if (b->type == VALUE_CELLRANGE) {
b = expr_implicit_intersection (&s->pos, b);
if (b == NULL)
res = value_new_error (&s->pos, gnumeric_err_VALUE);
} else if (b->type == VALUE_ERROR)
res = b;
if (res != NULL) {
if (a != NULL)
value_release (a);
return res;
}
}
comp = compare (a, b);
......@@ -703,9 +752,6 @@ eval_expr_real (FunctionEvalInfo *s, ExprTree const *tree)
case OPER_MULT:
case OPER_DIV:
case OPER_EXP:
/* Garantees that a != NULL */
a = eval_expr (s, tree->u.binary.value_a);
/*
* Priority
* 1) Error from A
......@@ -715,6 +761,16 @@ eval_expr_real (FunctionEvalInfo *s, ExprTree const *tree)
* 5) result of operation, or error specific to the operation
*/
/* Garantees that a != NULL */
a = eval_expr (s, tree->u.binary.value_a);
/* Handle implicit intersection */
if (a->type == VALUE_CELLRANGE) {
a = expr_implicit_intersection (&s->pos, a);
if (a == NULL)
return value_new_error (&s->pos, gnumeric_err_VALUE);
}
/* 1) Error from A */
if (a->type == VALUE_ERROR)
return a;
......@@ -728,6 +784,13 @@ eval_expr_real (FunctionEvalInfo *s, ExprTree const *tree)
/* Garantees that b != NULL */
b = eval_expr (s, tree->u.binary.value_b);
/* Handle implicit intersection */
if (b->type == VALUE_CELLRANGE) {
b = expr_implicit_intersection (&s->pos, a);
if (b == NULL)
return value_new_error (&s->pos, gnumeric_err_VALUE);
}
/* 3) Error from B */
if (b->type == VALUE_ERROR) {
value_release (a);
......@@ -837,8 +900,17 @@ eval_expr_real (FunctionEvalInfo *s, ExprTree const *tree)
case OPER_NEG:
/* Garantees that a != NULL */
a = eval_expr (s, tree->u.value);
/* Handle implicit intersection */
if (a->type == VALUE_CELLRANGE) {
a = expr_implicit_intersection (&s->pos, a);
if (a == NULL)
return value_new_error (&s->pos, gnumeric_err_VALUE);
}
if (a->type == VALUE_ERROR)
return a;
if (!VALUE_IS_NUMBER (a)){
value_release (a);
return value_new_error (&s->pos, gnumeric_err_VALUE);
......@@ -902,7 +974,7 @@ eval_expr_real (FunctionEvalInfo *s, ExprTree const *tree)
}
ref = &tree->u.ref;
cell_get_abs_col_row (ref, s->pos.eval_col, s->pos.eval_row, &col, &row);
cell_get_abs_col_row (ref, &s->pos.eval, &col, &row);
cell_sheet = eval_sheet (ref->sheet, s->pos.sheet);
cell = sheet_cell_get (cell_sheet, col, row);
......@@ -933,6 +1005,21 @@ eval_expr_real (FunctionEvalInfo *s, ExprTree const *tree)
value_release (a);
/* Store real result (cast away const)*/
/* FIXME : Call a wrapper routine that will iterate over the
* the array and evaluate the expression for all elements
*
* Figure out when to iterate and when to do array operations.
* ie
* A1:A3 = '=B1:B3^2' Will iterate over all the elements and
* re-evaluate.
* whereas
* A1:A3 = '=bob(B1:B3)' Will call bob once if it returns an
* array.
*
* This may be as simple as evaluating the corner. If that is
* is an array return the result, else build an array and
* iterate over the elements, but that theory needs validation.
*/
a = eval_expr_real (s, tree->u.array.corner.func.expr);
*((Value **)&(tree->u.array.corner.func.value)) = a;
} else {
......@@ -951,8 +1038,8 @@ eval_expr_real (FunctionEvalInfo *s, ExprTree const *tree)
/* Evaluate relative to the upper left corner */
EvalPosition tmp_ep = s->pos;
tmp_ep.eval_col -= x;
tmp_ep.eval_row -= y;
tmp_ep.eval.col -= x;
tmp_ep.eval.row -= y;
/* If the src array is 1 element wide or tall we wrap */
if (x >= 1 && num_x == 1)
......@@ -989,41 +1076,43 @@ eval_expr (FunctionEvalInfo *s, ExprTree const *tree)
}
int
cell_ref_get_abs_col (CellRef const *ref, EvalPosition const *pos)
cell_ref_get_abs_col (CellRef const * const ref, EvalPosition const * const pos)
{
g_return_val_if_fail (ref != NULL, 0);
g_return_val_if_fail (pos != NULL, 0);
if (ref->col_relative)
return pos->eval_col + ref->col;
return pos->eval.col + ref->col;
return ref->col;
}
int
cell_ref_get_abs_row (CellRef const *ref, EvalPosition const *pos)
cell_ref_get_abs_row (CellRef const * const ref, EvalPosition const * const pos)
{
g_return_val_if_fail (ref != NULL, 0);
g_return_val_if_fail (pos != NULL, 0);
if (ref->row_relative)
return pos->eval_row + ref->row;
return pos->eval.row + ref->row;
return ref->row;
}
void
cell_get_abs_col_row (const CellRef *cell_ref, int eval_col, int eval_row, int *col, int *row)
cell_get_abs_col_row (CellRef const * const cell_ref,
CellPos const * const pos,
int * const col, int * const row)
{
g_return_if_fail (cell_ref != NULL);
if (cell_ref->col_relative)
*col = eval_col + cell_ref->col;
*col = pos->col + cell_ref->col;
else
*col = cell_ref->col;
if (cell_ref->row_relative)
*row = eval_row + cell_ref->row;
*row = pos->row + cell_ref->row;
else
*row = cell_ref->row;
}
......@@ -1317,7 +1406,7 @@ cellref_relocate (CellRef * const ref,
range_contains (&rinfo->origin, col, row);
gboolean const from_inside =
(rinfo->origin_sheet == pos->sheet) &&
range_contains (&rinfo->origin, pos->eval_col, pos->eval_row);
range_contains (&rinfo->origin, pos->eval.col, pos->eval.row);
/* Case (a) */
if (!from_inside && !to_inside)
......@@ -1358,9 +1447,9 @@ cellref_relocate (CellRef * const ref,
return CELLREF_RELOCATE_ERR;
if (ref->col_relative)
col -= pos->eval_col;
col -= pos->eval.col;
if (ref->row_relative)
row -= pos->eval_row;
row -= pos->eval.row;
if (ref->sheet != ref_sheet || ref->col != col || ref->row != row) {
ref->sheet = ref_sheet;
......
......@@ -140,14 +140,13 @@ struct _ExprName {
} t;
};
int cell_ref_get_abs_col (CellRef const *cell_ref,
EvalPosition const *src_fp);
int cell_ref_get_abs_row (CellRef const *cell_ref,
EvalPosition const *src_fp);
void cell_get_abs_col_row (const CellRef *cell_ref,
int eval_col, int eval_row,
int *col, int *row);
int cell_ref_get_abs_col (CellRef const * const cell_ref,
EvalPosition const * const src_fp);
int cell_ref_get_abs_row (CellRef const * const cell_ref,
EvalPosition const * const src_fp);
void cell_get_abs_col_row (CellRef const * const cell_ref,
CellPos const * const pos,
int * const col, int * const row);
ExprTree *expr_parse_string (const char *expr, const ParsePosition *pp,
const char **desired_format, char **error_msg);
......@@ -195,7 +194,11 @@ void expr_dump_tree (const ExprTree *tree);
* Returns int(0) if the expression uses a non-existant cell for anything
* other than an equality test.
*/
Value *eval_expr (FunctionEvalInfo *s, ExprTree const *tree);
Value *eval_expr (FunctionEvalInfo * const s,
ExprTree const * const tree);
Value *expr_implicit_intersection (EvalPosition const * const pos,
Value * const v);
/* Setup of the symbol table */
void functions_init (void);
......
......@@ -58,14 +58,12 @@ iterate_cellrange_callback (Sheet *sheet, int col, int row,
* Helper routine for function_iterate_argument_values.
*/
Value *
function_iterate_do_value (const EvalPosition *ep,
function_iterate_do_value (EvalPosition const *ep,
FunctionIterateCallback callback,
void *closure,
Value *value,
gboolean strict)
{
int eval_col = ep->eval_col;
int eval_row = ep->eval_row;
Value *res = NULL;
switch (value->type){
......@@ -109,12 +107,10 @@ function_iterate_do_value (const EvalPosition *ep,
data.closure = closure;
data.strict = strict;
cell_get_abs_col_row (&value->v.cell_range.cell_a,
eval_col, eval_row,
cell_get_abs_col_row (&value->v.cell_range.cell_a, &ep->eval,
&start_col, &start_row);
cell_get_abs_col_row (&value->v.cell_range.cell_b,
eval_col, eval_row,
cell_get_abs_col_row (&value->v.cell_range.cell_b, &ep->eval,
&end_col, &end_row);
sheet = eval_sheet (value->v.cell_range.cell_a.sheet, ep->sheet);
......@@ -317,10 +313,10 @@ cell_ref_make_absolute (CellRef *cell_ref,
g_return_if_fail (cell_ref != NULL);
if (cell_ref->col_relative)
cell_ref->col = ep->eval_col + cell_ref->col;
cell_ref->col = ep->eval.col + cell_ref->col;
if (cell_ref->row_relative)
cell_ref->row = ep->eval_row + cell_ref->row;
cell_ref->row = ep->eval.row + cell_ref->row;
cell_ref->row_relative = 0;
cell_ref->col_relative = 0;
......@@ -348,9 +344,9 @@ function_call_with_list (FunctionEvalInfo *ei,
g_return_val_if_fail (ei != NULL, NULL);
g_return_val_if_fail (ei->func_def != NULL, NULL);
/* Functions that deal with ExprNodes */
fd = ei->func_def;
if (fd->fn_type == FUNCTION_NODES)
/* Functions that deal with ExprNodes */
return fd->fn.fn_nodes (ei, l);
/* Functions that take pre-computed Values */
......@@ -364,7 +360,7 @@ function_call_with_list (FunctionEvalInfo *ei,
values = g_new (Value *, fn_argc_max);
for (arg = 0; l; l = l->next, arg++) {
for (arg = 0; l; l = l->next, ++arg) {
char arg_type;
ExprTree *t = (ExprTree *) l->data;
gboolean type_mismatch = FALSE;
......@@ -380,48 +376,35 @@ function_call_with_list (FunctionEvalInfo *ei,
goto free_list;*/
} else {
g_assert (t->oper == OPER_VAR);
v = value_new_cellrange (&t->u.ref,
&t->u.ref);
v = value_new_cellrange (&t->u.ref, &t->u.ref);
}
switch (arg_type) {
case 'f':
case 'b':
/*
* Handle the implicit union of a single row or
* column with the eval position
*/
if (v->type == VALUE_CELLRANGE) {
CellRef a = v->v.cell_range.cell_a;
CellRef b = v->v.cell_range.cell_b;
cell_ref_make_absolute (&a, &ei->pos);
cell_ref_make_absolute (&b, &ei->pos);
if (a.sheet != b.sheet)
type_mismatch = TRUE;
else if (a.row == b.row) {
int const c = ei->pos.eval_col;
if (a.col <= c && c <= b.col)
v = value_duplicate (value_area_get_x_y (&ei->pos, v, c - a.col, 0));
else
type_mismatch = TRUE;
} else if (a.col == b.col) {
int const r = ei->pos.eval_row;
if (a.row <= r && r <= b.row)
v = value_duplicate (value_area_get_x_y (&ei->pos, v, 0, r - a.row));
else
type_mismatch = TRUE;
} else
type_mismatch = TRUE;
} else if (v->type != VALUE_INTEGER &&
v->type != VALUE_FLOAT &&
v->type != VALUE_BOOLEAN)
v = expr_implicit_intersection (&ei->pos, v);
if (v == NULL)
break;