Commit a447415c authored by Jody Goldberg's avatar Jody Goldberg Committed by Jody Goldberg

Fix some updates. Be more paranoid when printing. Big speedup for implicit

Fix some updates.
Be more paranoid when printing.
Big speedup for implicit intersection.

2000-04-05  Jody Goldberg <jgoldberg@home.com>

	* src/functions/fn-logical.c (gnumeric_if) : Use eval_expr_nonempty
	  and permit non-scalars.
	* src/functions/fn-lookup.c (gnumeric_choose) : Ditto.
	* src/functions/fn-math.c (gnumeric_sumproduct) : Ditto.

	* src/functions/fn-information.c (get_value_class) : Use
	  eval_expr_empty, and permit non-scalars.

	* src/func.c (function_iterate_argument_values) : Permit non-scalar
	  values.
	(function_marshal_arg) : Be more specific about what types of argument
	  must be scalar.

2000-04-04  Jody Goldberg <jgoldberg@home.com>

	* src/functions/fn-math.c (gnumeric_sumproduct) : eval_expr_nonempty
	  and permit non-scalars.
	* src/functions/fn-lookup.c (gnumeric_choose) : Ditto.

	* src/expr-name.c (eval_expr_name) : Accept 'as_scalar' as an
	  argument use eval_expr_empty.

	* src/expr.c (eval_expr_real) : Push the common cases for implicit
	  intersection further down for a big speed improvement.
	(eval_expr_nonempty) : New routine.
	(eval_expr_empty) : Accept as_scalar.

2000-04-04  Jody Goldberg <jgoldberg@home.com>

	* src/item-grid.c (item_grid_button_1) : sheet_update after button
	  press that changes selection.

2000-04-04  Jody Goldberg <jgoldberg@home.com>

	* src/print.c (print_hf) : Add precautions in an attempt to address
	  http://bugs.gnome.org/db/82/8200.html
	  I can not replicate it, but it can't hurt to be more careful just in
	  case.
parent ddebc71f
2000-04-05 Jody Goldberg <jgoldberg@home.com>
* src/functions/fn-logical.c (gnumeric_if) : Use eval_expr_nonempty
and permit non-scalars.
* src/functions/fn-lookup.c (gnumeric_choose) : Ditto.
* src/functions/fn-math.c (gnumeric_sumproduct) : Ditto.
* src/functions/fn-information.c (get_value_class) : Use
eval_expr_empty, and permit non-scalars.
* src/func.c (function_iterate_argument_values) : Permit non-scalar
values.
(function_marshal_arg) : Be more specific about what types of argument
must be scalar.
2000-04-04 Jody Goldberg <jgoldberg@home.com>
* src/functions/fn-math.c (gnumeric_sumproduct) : eval_expr_nonempty
and permit non-scalars.
* src/functions/fn-lookup.c (gnumeric_choose) : Ditto.
* src/expr-name.c (eval_expr_name) : Accept 'as_scalar' as an
argument use eval_expr_empty.
* src/expr.c (eval_expr_real) : Push the common cases for implicit
intersection further down for a big speed improvement.
(eval_expr_nonempty) : New routine.
(eval_expr_empty) : Accept as_scalar.
2000-04-04 Jody Goldberg <jgoldberg@home.com>
* src/item-grid.c (item_grid_button_1) : sheet_update after button
press that changes selection.
2000-04-04 Jody Goldberg <jgoldberg@home.com>
* src/print.c (print_hf) : Add precautions in an attempt to address
http://bugs.gnome.org/db/82/8200.html
I can not replicate it, but it can't hurt to be more careful just in
case.
2000-04-04 Miguel de Icaza <miguel@gnu.org>
* src/item-cursor.c (item_cursor_autofill_event): Flush the canvas updates
......
2000-04-05 Jody Goldberg <jgoldberg@home.com>
* src/functions/fn-logical.c (gnumeric_if) : Use eval_expr_nonempty
and permit non-scalars.
* src/functions/fn-lookup.c (gnumeric_choose) : Ditto.
* src/functions/fn-math.c (gnumeric_sumproduct) : Ditto.
* src/functions/fn-information.c (get_value_class) : Use
eval_expr_empty, and permit non-scalars.
* src/func.c (function_iterate_argument_values) : Permit non-scalar
values.
(function_marshal_arg) : Be more specific about what types of argument
must be scalar.
2000-04-04 Jody Goldberg <jgoldberg@home.com>
* src/functions/fn-math.c (gnumeric_sumproduct) : eval_expr_nonempty
and permit non-scalars.
* src/functions/fn-lookup.c (gnumeric_choose) : Ditto.
* src/expr-name.c (eval_expr_name) : Accept 'as_scalar' as an
argument use eval_expr_empty.
* src/expr.c (eval_expr_real) : Push the common cases for implicit
intersection further down for a big speed improvement.
(eval_expr_nonempty) : New routine.
(eval_expr_empty) : Accept as_scalar.
2000-04-04 Jody Goldberg <jgoldberg@home.com>
* src/item-grid.c (item_grid_button_1) : sheet_update after button
press that changes selection.
2000-04-04 Jody Goldberg <jgoldberg@home.com>
* src/print.c (print_hf) : Add precautions in an attempt to address
http://bugs.gnome.org/db/82/8200.html
I can not replicate it, but it can't hurt to be more careful just in
case.
2000-04-04 Miguel de Icaza <miguel@gnu.org>
* src/item-cursor.c (item_cursor_autofill_event): Flush the canvas updates
......
2000-04-05 Jody Goldberg <jgoldberg@home.com>
* src/functions/fn-logical.c (gnumeric_if) : Use eval_expr_nonempty
and permit non-scalars.
* src/functions/fn-lookup.c (gnumeric_choose) : Ditto.
* src/functions/fn-math.c (gnumeric_sumproduct) : Ditto.
* src/functions/fn-information.c (get_value_class) : Use
eval_expr_empty, and permit non-scalars.
* src/func.c (function_iterate_argument_values) : Permit non-scalar
values.
(function_marshal_arg) : Be more specific about what types of argument
must be scalar.
2000-04-04 Jody Goldberg <jgoldberg@home.com>
* src/functions/fn-math.c (gnumeric_sumproduct) : eval_expr_nonempty
and permit non-scalars.
* src/functions/fn-lookup.c (gnumeric_choose) : Ditto.
* src/expr-name.c (eval_expr_name) : Accept 'as_scalar' as an
argument use eval_expr_empty.
* src/expr.c (eval_expr_real) : Push the common cases for implicit
intersection further down for a big speed improvement.
(eval_expr_nonempty) : New routine.
(eval_expr_empty) : Accept as_scalar.
2000-04-04 Jody Goldberg <jgoldberg@home.com>
* src/item-grid.c (item_grid_button_1) : sheet_update after button
press that changes selection.
2000-04-04 Jody Goldberg <jgoldberg@home.com>
* src/print.c (print_hf) : Add precautions in an attempt to address
http://bugs.gnome.org/db/82/8200.html
I can not replicate it, but it can't hurt to be more careful just in
case.
2000-04-04 Miguel de Icaza <miguel@gnu.org>
* src/item-cursor.c (item_cursor_autofill_event): Flush the canvas updates
......
2000-04-05 Jody Goldberg <jgoldberg@home.com>
* src/functions/fn-logical.c (gnumeric_if) : Use eval_expr_nonempty
and permit non-scalars.
* src/functions/fn-lookup.c (gnumeric_choose) : Ditto.
* src/functions/fn-math.c (gnumeric_sumproduct) : Ditto.
* src/functions/fn-information.c (get_value_class) : Use
eval_expr_empty, and permit non-scalars.
* src/func.c (function_iterate_argument_values) : Permit non-scalar
values.
(function_marshal_arg) : Be more specific about what types of argument
must be scalar.
2000-04-04 Jody Goldberg <jgoldberg@home.com>
* src/functions/fn-math.c (gnumeric_sumproduct) : eval_expr_nonempty
and permit non-scalars.
* src/functions/fn-lookup.c (gnumeric_choose) : Ditto.
* src/expr-name.c (eval_expr_name) : Accept 'as_scalar' as an
argument use eval_expr_empty.
* src/expr.c (eval_expr_real) : Push the common cases for implicit
intersection further down for a big speed improvement.
(eval_expr_nonempty) : New routine.
(eval_expr_empty) : Accept as_scalar.
2000-04-04 Jody Goldberg <jgoldberg@home.com>
* src/item-grid.c (item_grid_button_1) : sheet_update after button
press that changes selection.
2000-04-04 Jody Goldberg <jgoldberg@home.com>
* src/print.c (print_hf) : Add precautions in an attempt to address
http://bugs.gnome.org/db/82/8200.html
I can not replicate it, but it can't hurt to be more careful just in
case.
2000-04-04 Miguel de Icaza <miguel@gnu.org>
* src/item-cursor.c (item_cursor_autofill_event): Flush the canvas updates
......
2000-04-05 Jody Goldberg <jgoldberg@home.com>
* src/functions/fn-logical.c (gnumeric_if) : Use eval_expr_nonempty
and permit non-scalars.
* src/functions/fn-lookup.c (gnumeric_choose) : Ditto.
* src/functions/fn-math.c (gnumeric_sumproduct) : Ditto.
* src/functions/fn-information.c (get_value_class) : Use
eval_expr_empty, and permit non-scalars.
* src/func.c (function_iterate_argument_values) : Permit non-scalar
values.
(function_marshal_arg) : Be more specific about what types of argument
must be scalar.
2000-04-04 Jody Goldberg <jgoldberg@home.com>
* src/functions/fn-math.c (gnumeric_sumproduct) : eval_expr_nonempty
and permit non-scalars.
* src/functions/fn-lookup.c (gnumeric_choose) : Ditto.
* src/expr-name.c (eval_expr_name) : Accept 'as_scalar' as an
argument use eval_expr_empty.
* src/expr.c (eval_expr_real) : Push the common cases for implicit
intersection further down for a big speed improvement.
(eval_expr_nonempty) : New routine.
(eval_expr_empty) : Accept as_scalar.
2000-04-04 Jody Goldberg <jgoldberg@home.com>
* src/item-grid.c (item_grid_button_1) : sheet_update after button
press that changes selection.
2000-04-04 Jody Goldberg <jgoldberg@home.com>
* src/print.c (print_hf) : Add precautions in an attempt to address
http://bugs.gnome.org/db/82/8200.html
I can not replicate it, but it can't hurt to be more careful just in
case.
2000-04-04 Miguel de Icaza <miguel@gnu.org>
* src/item-cursor.c (item_cursor_autofill_event): Flush the canvas updates
......
2000-04-05 Jody Goldberg <jgoldberg@home.com>
* src/functions/fn-logical.c (gnumeric_if) : Use eval_expr_nonempty
and permit non-scalars.
* src/functions/fn-lookup.c (gnumeric_choose) : Ditto.
* src/functions/fn-math.c (gnumeric_sumproduct) : Ditto.
* src/functions/fn-information.c (get_value_class) : Use
eval_expr_empty, and permit non-scalars.
* src/func.c (function_iterate_argument_values) : Permit non-scalar
values.
(function_marshal_arg) : Be more specific about what types of argument
must be scalar.
2000-04-04 Jody Goldberg <jgoldberg@home.com>
* src/functions/fn-math.c (gnumeric_sumproduct) : eval_expr_nonempty
and permit non-scalars.
* src/functions/fn-lookup.c (gnumeric_choose) : Ditto.
* src/expr-name.c (eval_expr_name) : Accept 'as_scalar' as an
argument use eval_expr_empty.
* src/expr.c (eval_expr_real) : Push the common cases for implicit
intersection further down for a big speed improvement.
(eval_expr_nonempty) : New routine.
(eval_expr_empty) : Accept as_scalar.
2000-04-04 Jody Goldberg <jgoldberg@home.com>
* src/item-grid.c (item_grid_button_1) : sheet_update after button
press that changes selection.
2000-04-04 Jody Goldberg <jgoldberg@home.com>
* src/print.c (print_hf) : Add precautions in an attempt to address
http://bugs.gnome.org/db/82/8200.html
I can not replicate it, but it can't hurt to be more careful just in
case.
2000-04-04 Miguel de Icaza <miguel@gnu.org>
* src/item-cursor.c (item_cursor_autofill_event): Flush the canvas updates
......
2000-04-05 Jody Goldberg <jgoldberg@home.com>
* src/functions/fn-logical.c (gnumeric_if) : Use eval_expr_nonempty
and permit non-scalars.
* src/functions/fn-lookup.c (gnumeric_choose) : Ditto.
* src/functions/fn-math.c (gnumeric_sumproduct) : Ditto.
* src/functions/fn-information.c (get_value_class) : Use
eval_expr_empty, and permit non-scalars.
* src/func.c (function_iterate_argument_values) : Permit non-scalar
values.
(function_marshal_arg) : Be more specific about what types of argument
must be scalar.
2000-04-04 Jody Goldberg <jgoldberg@home.com>
* src/functions/fn-math.c (gnumeric_sumproduct) : eval_expr_nonempty
and permit non-scalars.
* src/functions/fn-lookup.c (gnumeric_choose) : Ditto.
* src/expr-name.c (eval_expr_name) : Accept 'as_scalar' as an
argument use eval_expr_empty.
* src/expr.c (eval_expr_real) : Push the common cases for implicit
intersection further down for a big speed improvement.
(eval_expr_nonempty) : New routine.
(eval_expr_empty) : Accept as_scalar.
2000-04-04 Jody Goldberg <jgoldberg@home.com>
* src/item-grid.c (item_grid_button_1) : sheet_update after button
press that changes selection.
2000-04-04 Jody Goldberg <jgoldberg@home.com>
* src/print.c (print_hf) : Add precautions in an attempt to address
http://bugs.gnome.org/db/82/8200.html
I can not replicate it, but it can't hurt to be more careful just in
case.
2000-04-04 Miguel de Icaza <miguel@gnu.org>
* src/item-cursor.c (item_cursor_autofill_event): Flush the canvas updates
......
......@@ -32,7 +32,7 @@ get_value_class (FunctionEvalInfo *ei, ExprTree *expr)
Value *value;
enum Value_Class res;
value = eval_expr (ei->pos, expr);
value = eval_expr_empty (ei->pos, expr, FALSE);
if (value) {
switch (value->type) {
case VALUE_INTEGER:
......
......@@ -218,8 +218,8 @@ gnumeric_if (FunctionEvalInfo *ei, GList *expr_node_list)
return value_new_bool (FALSE);
}
/* Return the result */
return eval_expr (ei->pos, expr);
/* Return the result (not necessarily a scalar) */
return eval_expr_nonempty (ei->pos, expr, FALSE);
}
/***************************************************************************/
......
......@@ -176,7 +176,8 @@ gnumeric_choose (FunctionEvalInfo *ei, GList *l)
while (l){
index--;
if (!index)
return eval_expr (ei->pos, l->data);
/* The result need not be a scalar */
return eval_expr_nonempty (ei->pos, l->data, FALSE);
l = g_list_next (l);
}
return value_new_error (ei->pos, gnumeric_err_VALUE);
......
......@@ -3348,7 +3348,8 @@ gnumeric_sumproduct (FunctionEvalInfo *ei, GList *expr_node_list)
ExprTree *tree = (ExprTree *) expr_node_list->data;
Value *val;
val = eval_expr (ei->pos, tree);
/* The result need not be a scalar */
val = eval_expr_nonempty (ei->pos, tree, FALSE);
if (val) {
p.current = p.components;
......
2000-04-05 Jody Goldberg <jgoldberg@home.com>
* plugin.c (generic_marshaller) : Use eval_expr_nonempty, but do not
force scalar.
2000-03-22 Chema Celorio <chema@celorio.com>
* .cvsignore: Created .cvsignore in /plugins/gb,
......@@ -24,4 +29,4 @@
* plugin.c (value_to_gb): implemented.
(gb_to_value): implement.
* plugin.c: created.
\ No newline at end of file
* plugin.c: created.
......@@ -183,7 +183,11 @@ generic_marshaller (FunctionEvalInfo *ei, GList *nodes)
g_return_val_if_fail (fd != NULL, NULL);
for (l = nodes; l; l = l->next) {
Value *v = eval_expr (ei->pos, l->data);
/* TODO : When the translation mechanism is more complete
* this can be relaxed. We do not need to require
* non emptiness, or scalarness.
*/
Value *v = eval_expr_nonempty (ei->pos, l->data, TRUE);
args = g_slist_prepend (args, value_to_gb (ei, v));
......
2000-04-05 Jody Goldberg <jgoldberg@home.com>
* plugin.c (func_scm_apply) : Use eval_expr_empty, and
eval_expr_nonempty..
2000-03-29 Jody Goldberg <jgoldberg@home.com>
* plugin.c (init_plugin) : Add check to ensure that gnumeric was
......
......@@ -284,12 +284,14 @@ func_scm_apply (FunctionEvalInfo *ei, GList *expr_node_list)
if (g_list_length(expr_node_list) < 1)
return value_new_error (ei->pos, _("Invalid number of arguments"));
value = eval_expr(ei->pos, (ExprTree*)expr_node_list->data);
/* Retrieve the function name, This can be empty, but not a non scalar */
value = eval_expr_empty(ei->pos, (ExprTree*)expr_node_list->data, TRUE);
if (value == NULL)
return value_new_error (ei->pos, _("First argument to SCM must be a Guile expression"));
symbol = value_get_as_string (value);
if (symbol == NULL)
/* FIXME : This looks like a leak (JEG 4/4/00) */
return value_new_error (ei->pos, _("First argument to SCM must be a Guile expression"));
function = scm_eval_0str(symbol);
......@@ -308,7 +310,8 @@ func_scm_apply (FunctionEvalInfo *ei, GList *expr_node_list)
eval_cell.row_relative = 0;
eval_cell.sheet = NULL;
value = eval_expr (ei->pos, (ExprTree*)g_list_nth(expr_node_list, i)->data);
/* Evaluate each argument, non scalar is ok, but empty is not */
value = eval_expr_nonempty (ei->pos, (ExprTree*)g_list_nth(expr_node_list, i)->data, FALSE);
if (value == NULL)
return value_new_error (ei->pos, _("Could not evaluate argument"));
......
2000-04-05 Jody Goldberg <jgoldberg@home.com>
* python.c (marshal_func_nodes) : Use eval_expr_nonempty, but permit
non-scalars.
2000-03-24 Jon K Hellan <hellan@acm.org>
* python.c (apply): Fix leak.
......
......@@ -691,7 +691,7 @@ marshal_func_nodes (FunctionEvalInfo *ei, GList *nodes)
/* Now, the actual arguments */
for (i = 0, l = nodes; i < argc && l; i++, l = l->next) {
ev = eval_expr (ei->pos, l->data);
ev = eval_expr_nonempty (ei->pos, l->data, FALSE);
/* ref is stolen from us */
PyTuple_SetItem (args, i + 1, value_to_python (ev));
value_release (ev);
......
......@@ -350,7 +350,8 @@ expr_name_value (const ExprName *expr_name)
Value *
eval_expr_name (EvalPosition const * const pos, const ExprName *expr_name)
eval_expr_name (EvalPosition const * const pos, const ExprName *expr_name,
gboolean const as_scalar)
{
g_return_val_if_fail (pos, NULL);
......@@ -364,7 +365,7 @@ eval_expr_name (EvalPosition const * const pos, const ExprName *expr_name)
no descriptors for builtins */
return expr_name->t.expr_func (&ei, NULL);
} else
return eval_expr (pos, expr_name->t.expr_tree);
return eval_expr_empty (pos, expr_name->t.expr_tree, as_scalar);
}
/* ------------------------------------------------------------- */
......
......@@ -35,7 +35,8 @@ void expr_name_clean_sheet (Sheet *sheet);
GList *expr_name_list (Workbook *wb, Sheet *sheet, gboolean builtins_too);
/* Evaluate the name's expression */
Value *eval_expr_name (EvalPosition const * const pos, const ExprName *exprn);
Value *eval_expr_name (EvalPosition const * const pos, const ExprName *exprn,
gboolean const as_scalar);
char *expr_name_value (const ExprName *expr_name);
......
......@@ -618,7 +618,8 @@ eval_range (EvalPosition const * const pos, Value *v)
}
static Value *
eval_expr_real (EvalPosition const * const pos, ExprTree const * const tree)
eval_expr_real (EvalPosition const * const pos, ExprTree const * const tree,
gboolean const as_scalar)
{
Value *res = NULL, *a = NULL, *b = NULL;
......@@ -634,7 +635,7 @@ eval_expr_real (EvalPosition const * const pos, ExprTree const * const tree)
case OPER_LTE: {
int comp;
a = eval_expr_real (pos, tree->u.binary.value_a);
a = eval_expr_real (pos, tree->u.binary.value_a, as_scalar);
if (a != NULL) {
if (a->type == VALUE_CELLRANGE) {
a = expr_implicit_intersection (pos, a);
......@@ -644,7 +645,7 @@ eval_expr_real (EvalPosition const * const pos, ExprTree const * const tree)
return a;
}
b = eval_expr_real (pos, tree->u.binary.value_b);
b = eval_expr_real (pos, tree->u.binary.value_b, as_scalar);
if (b != NULL) {
Value *res = NULL;
if (b->type == VALUE_CELLRANGE) {
......@@ -729,7 +730,7 @@ eval_expr_real (EvalPosition const * const pos, ExprTree const * const tree)
*/
/* Garantees that a != NULL */
a = eval_expr (pos, tree->u.binary.value_a);
a = eval_expr_nonempty (pos, tree->u.binary.value_a, as_scalar);
/* Handle implicit intersection */
if (a->type == VALUE_CELLRANGE) {
......@@ -749,7 +750,7 @@ eval_expr_real (EvalPosition const * const pos, ExprTree const * const tree)
}
/* Garantees that b != NULL */
b = eval_expr (pos, tree->u.binary.value_b);
b = eval_expr_nonempty (pos, tree->u.binary.value_b, as_scalar);
/* Handle implicit intersection */
if (b->type == VALUE_CELLRANGE) {
......@@ -868,7 +869,7 @@ eval_expr_real (EvalPosition const * const pos, ExprTree const * const tree)
case OPER_UNARY_NEG:
case OPER_UNARY_PLUS:
/* Garantees that a != NULL */
a = eval_expr (pos, tree->u.value);
a = eval_expr_nonempty (pos, tree->u.value, as_scalar);
/* Handle implicit intersection */
if (a->type == VALUE_CELLRANGE) {
......@@ -902,10 +903,10 @@ eval_expr_real (EvalPosition const * const pos, ExprTree const * const tree)
case OPER_CONCAT: {
char *sa, *sb, *tmp;
a = eval_expr_real (pos, tree->u.binary.value_a);
a = eval_expr_real (pos, tree->u.binary.value_a, as_scalar);
if (a != NULL && a->type == VALUE_ERROR)
return a;
b = eval_expr_real (pos, tree->u.binary.value_b);
b = eval_expr_real (pos, tree->u.binary.value_b, as_scalar);
if (b != NULL && b->type == VALUE_ERROR) {
if (a != NULL)
value_release (a);
......@@ -932,7 +933,7 @@ eval_expr_real (EvalPosition const * const pos, ExprTree const * const tree)
return eval_funcall (pos, tree);
case OPER_NAME:
return eval_expr_name (pos, tree->u.name);
return eval_expr_name (pos, tree->u.name, as_scalar);
case OPER_VAR: {
Sheet *cell_sheet;
......@@ -961,9 +962,54 @@ eval_expr_real (EvalPosition const * const pos, ExprTree const * const tree)
case OPER_CONSTANT:
res = tree->u.constant;
if (res->type == VALUE_CELLRANGE)
if (res->type != VALUE_CELLRANGE)
return value_duplicate (res);
if (!as_scalar) {
eval_range (pos, res);
return value_duplicate (res);
return value_duplicate (res);
} else {
/*
* 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.
*/
CellRef const * const a = & res->v.cell_range.cell_a;
CellRef const * const b = & res->v.cell_range.cell_b;
gboolean found = FALSE;
if (a->sheet == b->sheet) {
int a_col, a_row, b_col, b_row;
int c = pos->eval.col;
int r = pos->eval.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) {
if (a_col <= c && c <= b_col) {
r = a_row;
found = TRUE;
}
} else if (a_col == b_col) {
if (a_row <= r && r <= b_row) {
c = a_col;
found = TRUE;
}
}
if (found) {
Cell * cell = sheet_cell_get (pos->sheet, c, r);
if (cell == NULL)
return NULL;
if (cell->generation != pos->sheet->workbook->generation)
cell_eval (cell);
return value_duplicate (cell->value);
}
}
return value_new_error (pos, gnumeric_err_VALUE);
}
case OPER_ARRAY:
{
......@@ -992,7 +1038,7 @@ eval_expr_real (EvalPosition const * const pos, ExprTree const * const tree)
* is an array return the result, else build an array and
* iterate over the elements, but that theory needs validation.
*/
a = eval_expr_real (pos, tree->u.array.corner.func.expr);
a = eval_expr_real (pos, tree->u.array.corner.func.expr, FALSE);
*((Value **)&(tree->u.array.corner.func.value)) = a;
} else {
ExprTree const * const array =
......@@ -1034,9 +1080,10 @@ eval_expr_real (EvalPosition const * const pos, ExprTree const * const tree)
}
Value *
eval_expr (EvalPosition const * const pos, ExprTree const *tree)
eval_expr_nonempty (EvalPosition const * const pos, ExprTree const *tree,
gboolean const as_scalar)
{
Value * res = eval_expr_real (pos, tree);
Value * res = eval_expr_real (pos, tree, as_scalar);
if (res == NULL)
return value_new_int (0);
......@@ -1048,9 +1095,16 @@ eval_expr (EvalPosition const * const pos, ExprTree const *tree)
}
Value *
eval_expr_empty (EvalPosition const * const pos, ExprTree const * const tree)
eval_expr (EvalPosition const * const pos, ExprTree const *tree)
{
return eval_expr_nonempty (pos, tree, TRUE);
}
Value *
eval_expr_empty (EvalPosition const * const pos, ExprTree const * const tree,
gboolean const as_scalar)
{
Value * res = eval_expr_real (pos, tree);
Value * res = eval_expr_real (pos, tree, as_scalar);
if (res && res->type == VALUE_EMPTY) {
value_release (res);
......
......@@ -190,9 +190,15 @@ void expr_dump_tree (const ExprTree *tree);
Value *eval_expr (EvalPosition const * const pos,
ExprTree const * const tree);
/* Identical to eval_expr but permits being called as an array */
Value *eval_expr_nonempty (EvalPosition const * const pos,
ExprTree const *tree,
gboolean const as_scalar);
/* Same as eval_expr, except that this return NULL for empty values. */
Value *eval_expr_empty (EvalPosition const * const pos,
ExprTree const * const tree);
ExprTree const * const tree,
gboolean const as_scalar);
Value *expr_implicit_intersection (EvalPosition const * const pos,
Value * const v);
......
......@@ -141,7 +141,9 @@ function_iterate_argument_values (const EvalPosition *ep,
ExprTree const * tree = (ExprTree const *) expr_node_list->data;
Value *val;
val = eval_expr_empty (ep, tree);
/* Permit empties and non scalars. We don't know what form the
* function wants its arguments */
val = eval_expr_empty (ep, tree, FALSE);
if (val == NULL)
continue;
......@@ -343,7 +345,12 @@ function_marshal_arg (FunctionEvalInfo *ei,
arg_type == 'r'))
v = value_new_cellrange (&t->u.ref, &t->u.ref);
else
v = eval_expr (ei->pos, t);
/* force scalars whenever we are certain */
v = eval_expr_nonempty (ei->pos, t,
(arg_type != 'r' &&
arg_type != 'a' &&
arg_type != 'A' &&
arg_type != '?'));
switch (arg_type) {
......
......@@ -32,7 +32,7 @@ get_value_class (FunctionEvalInfo *ei, ExprTree *expr)
Value *value;
enum Value_Class res;
value = eval_expr (ei->pos, expr);
value = eval_expr_empty (ei->pos, expr, FALSE);
if (value) {
switch (value->type) {
case VALUE_INTEGER:
......
......@@ -218,8 +218,8 @@ gnumeric_if (FunctionEv