[gnumeric] Eval: fix problem with single cell names and 'r' arguments.



commit f387d30c8bf6f5dbf3c1cd144f54bc94865a9d32
Author: Morten Welinder <terra gnome org>
Date:   Wed Feb 16 09:21:49 2011 -0500

    Eval: fix problem with single cell names and 'r' arguments.

 ChangeLog      |   17 ++++++++++++++---
 NEWS           |    1 +
 src/expr.c     |   26 ++++++++++++++++----------
 src/func.c     |   41 ++++++++++++++++++-----------------------
 src/gnumeric.h |    3 ++-
 5 files changed, 51 insertions(+), 37 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 8588933..190fd3d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,14 +1,25 @@
+2011-02-16  Morten Welinder  <terra gnome org>
+
+	* src/gnumeric.h (GnmExprEvalFlags): Add new want-ref flag.
+
+	* src/expr.c (gnm_expr_eval): clear the want-ref flag for
+	arguments to operands.  If the flag is set, return a ref for the
+	cellref case.
+
+	* src/func.c (function_call_with_exprs): Evaluate 'r' arguments
+	with want-ref flag.  Fixes #613273.
+
 2011-02-15  Andreas J. Guelzow <aguelzow pyrshep ca>
 
 	* src/validation-combo.h (IS_GNM_VALIDATION_COMBO): new
-	
+
 2011-02-07  Andreas J. Guelzow <aguelzow pyrshep ca>
 
-	* schemas/gnumeric-dialogs.schemas.in 
+	* schemas/gnumeric-dialogs.schemas.in
 	(/apps/gnumeric/stf/export/terminator): use escape
 	* src/stf-export.c (gnm_stf_get_stfe): do not leave the terminator
 	as "" (this could happen due to gconf bug #641807)
-	
+
 2011-02-07  Jean Brefort  <jean brefort normalesup org>
 
 	* src/item-edit.c (item_edit_button_pressed), (item_edit_motion): fix
diff --git a/NEWS b/NEWS
index d7099b8..d758598 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,7 @@ Jean:
 
 Morten:
 	* Import wide sc files.  [#641581]
+	* Fix problem with single-cell names and 'r'-type arguments.  [#613273]
 
 --------------------------------------------------------------------------
 Gnumeric 1.10.13
diff --git a/src/expr.c b/src/expr.c
index 07ae4a4..93b8a1f 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -1208,6 +1208,7 @@ gnm_expr_eval (GnmExpr const *expr, GnmEvalPos const *pos,
 	case GNM_EXPR_OP_LT:
 	case GNM_EXPR_OP_LTE:
 		flags |= GNM_EXPR_EVAL_PERMIT_EMPTY;
+		flags &= ~GNM_EXPR_EVAL_WANT_REF;
 
 		a = gnm_expr_eval (expr->binary.value_a, pos, flags);
 		if (a != NULL) {
@@ -1253,6 +1254,7 @@ gnm_expr_eval (GnmExpr const *expr, GnmEvalPos const *pos,
 
 		/* Guarantees value != NULL */
 		flags &= ~GNM_EXPR_EVAL_PERMIT_EMPTY;
+		flags &= ~GNM_EXPR_EVAL_WANT_REF;
 
 		/* 1) Error from A */
 		a = gnm_expr_eval (expr->binary.value_a, pos, flags);
@@ -1327,6 +1329,7 @@ gnm_expr_eval (GnmExpr const *expr, GnmEvalPos const *pos,
 	case GNM_EXPR_OP_UNARY_PLUS:
 		/* Guarantees value != NULL */
 		flags &= ~GNM_EXPR_EVAL_PERMIT_EMPTY;
+		flags &= ~GNM_EXPR_EVAL_WANT_REF;
 
 		a = gnm_expr_eval (expr->unary.value, pos, flags);
 		if (VALUE_IS_ERROR (a))
@@ -1367,6 +1370,7 @@ gnm_expr_eval (GnmExpr const *expr, GnmEvalPos const *pos,
 
 	case GNM_EXPR_OP_CAT:
 		flags |= GNM_EXPR_EVAL_PERMIT_EMPTY;
+		flags &= ~GNM_EXPR_EVAL_WANT_REF;
 		a = gnm_expr_eval (expr->binary.value_a, pos, flags);
 		if (a != NULL) {
 			if (VALUE_IS_ERROR (a))
@@ -1441,19 +1445,21 @@ gnm_expr_eval (GnmExpr const *expr, GnmEvalPos const *pos,
 
 	case GNM_EXPR_OP_CELLREF: {
 		GnmCell *cell;
-		GnmCellPos dest;
+		GnmCellRef r;
 
-		gnm_cellpos_init_cellref (&dest, &expr->cellref.ref,
-					  &pos->eval, pos->sheet);
+		gnm_cellref_make_abs (&r, &expr->cellref.ref, pos);
 
-		cell = sheet_cell_get (eval_sheet (expr->cellref.ref.sheet, pos->sheet),
-			dest.col, dest.row);
-		if (cell == NULL)
-			return handle_empty (NULL, flags);
-
-		gnm_cell_eval (cell);
+		cell = sheet_cell_get (eval_sheet (r.sheet, pos->sheet),
+				       r.col, r.row);
+		if (cell)
+			gnm_cell_eval (cell);
 
-		return handle_empty (value_dup (cell->value), flags);
+		if (flags & GNM_EXPR_EVAL_WANT_REF) {
+			return value_new_cellrange_unsafe (&r, &r);
+		} else {
+			GnmValue *v = cell ? value_dup (cell->value) : NULL;
+			return handle_empty (v, flags);
+		}
 	}
 
 	case GNM_EXPR_OP_CONSTANT:
diff --git a/src/func.c b/src/func.c
index 6405433..a071049 100644
--- a/src/func.c
+++ b/src/func.c
@@ -1507,31 +1507,26 @@ function_call_with_exprs (GnmFuncEvalInfo *ei, GnmExprEvalFlags flags)
 		GnmExpr const *expr = argv[i];
 
 		if (arg_type == 'A' || arg_type == 'r') {
-			if (GNM_EXPR_GET_OPER (expr) == GNM_EXPR_OP_CELLREF) {
-				GnmCellRef r;
-				gnm_cellref_make_abs (&r, &expr->cellref.ref, ei->pos);
-				args[i] = value_new_cellrange_unsafe (&r, &r);
-			} else {
-				tmp = args[i] = gnm_expr_eval (expr, ei->pos,
-					GNM_EXPR_EVAL_PERMIT_NON_SCALAR);
-				if (VALUE_IS_ERROR (tmp)) {
-					free_values (args, i);
-					return tmp;
-				}
-
-				if (tmp->type == VALUE_CELLRANGE) {
-					gnm_cellref_make_abs (&tmp->v_range.cell.a,
-						&tmp->v_range.cell.a,
-						ei->pos);
-					gnm_cellref_make_abs (&tmp->v_range.cell.b,
-						&tmp->v_range.cell.b,
-						ei->pos);
+			tmp = args[i] = gnm_expr_eval
+				(expr, ei->pos,
+				 GNM_EXPR_EVAL_PERMIT_NON_SCALAR |
+				 GNM_EXPR_EVAL_WANT_REF);
+			if (VALUE_IS_ERROR (tmp)) {
+				free_values (args, i);
+				return tmp;
+			}
 
+			if (tmp->type == VALUE_CELLRANGE) {
+				gnm_cellref_make_abs (&tmp->v_range.cell.a,
+						      &tmp->v_range.cell.a,
+						      ei->pos);
+				gnm_cellref_make_abs (&tmp->v_range.cell.b,
+						      &tmp->v_range.cell.b,
+						      ei->pos);
 				/* Array args accept scalars */
-				} else if (arg_type != 'A' && tmp->type != VALUE_ARRAY) {
-					free_values (args, i + 1);
-					return value_new_error_VALUE (ei->pos);
-				}
+			} else if (arg_type != 'A' && tmp->type != VALUE_ARRAY) {
+				free_values (args, i + 1);
+				return value_new_error_VALUE (ei->pos);
 			}
 			continue;
 		}
diff --git a/src/gnumeric.h b/src/gnumeric.h
index 9713e55..c060097 100644
--- a/src/gnumeric.h
+++ b/src/gnumeric.h
@@ -172,7 +172,8 @@ typedef enum {
 typedef enum {
 	GNM_EXPR_EVAL_SCALAR_NON_EMPTY	= 0,
 	GNM_EXPR_EVAL_PERMIT_NON_SCALAR	= 0x1,
-	GNM_EXPR_EVAL_PERMIT_EMPTY	= 0x2
+	GNM_EXPR_EVAL_PERMIT_EMPTY	= 0x2,
+	GNM_EXPR_EVAL_WANT_REF		= 0x4
 } GnmExprEvalFlags;
 
 typedef struct _XmlParseContext		XmlParseContext;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]