[gnumeric] INDEX: partial cleanup.



commit 448ab65eed41e790e83907fd901f60f7274002e9
Author: Morten Welinder <terra gnome org>
Date:   Fri Apr 16 11:32:48 2010 -0400

    INDEX: partial cleanup.

 NEWS                          |    1 +
 plugins/fn-lookup/ChangeLog   |    5 +++++
 plugins/fn-lookup/functions.c |   41 ++++++++++++++++++++++++++++-------------
 3 files changed, 34 insertions(+), 13 deletions(-)
---
diff --git a/NEWS b/NEWS
index a00455e..391fbd6 100644
--- a/NEWS
+++ b/NEWS
@@ -32,6 +32,7 @@ Morten:
 	* Patch gtk+ so GtkEntry widgets on win32 draw right.  [#603667]
 	* Fix xls export of cell comments.  [#615845]
 	* Fix error propagation problem.  [#615772]
+	* Partially clean up INDEX implementation.
 
 --------------------------------------------------------------------------
 Gnumeric 1.10.1
diff --git a/plugins/fn-lookup/ChangeLog b/plugins/fn-lookup/ChangeLog
index 4bb1f00..635effe 100644
--- a/plugins/fn-lookup/ChangeLog
+++ b/plugins/fn-lookup/ChangeLog
@@ -1,3 +1,8 @@
+2010-04-16  Morten Welinder  <terra gnome org>
+
+	* functions.c (gnumeric_index): Clean this up somewhat.  Why is
+	this a vararg function?
+
 2010-03-08  Morten Welinder <terra gnome org>
 
 	* Release 1.10.1
diff --git a/plugins/fn-lookup/functions.c b/plugins/fn-lookup/functions.c
index 6044137..1d07629 100644
--- a/plugins/fn-lookup/functions.c
+++ b/plugins/fn-lookup/functions.c
@@ -1258,30 +1258,45 @@ gnumeric_index (GnmFuncEvalInfo *ei, int argc, GnmExprConstPtr const *argv)
 	gboolean valid;
 	GnmValue *v, *res;
 
-	if (argc == 0)
+	if (argc == 0 || argc > 4)
 		return value_new_error_VALUE (ei->pos);
 	source = argv[0];
 
+	/* This is crazy.  */
+	while (GNM_EXPR_GET_OPER (source) == GNM_EXPR_OP_PAREN)
+		source = source->unary.value;
+
+	v = gnm_expr_eval (source, ei->pos, GNM_EXPR_EVAL_PERMIT_NON_SCALAR);
+	if (VALUE_IS_ERROR (v))
+		return v;
+
 	for (i = 0; i + 1 < argc && i < (int)G_N_ELEMENTS (elem); i++) {
-		v = value_coerce_to_number (
+		GnmValue *vi = value_coerce_to_number (
 			gnm_expr_eval (argv[i + 1], ei->pos, GNM_EXPR_EVAL_SCALAR_NON_EMPTY),
 			&valid, ei->pos);
-		if (!valid)
-			return v;
-		elem[i] = value_get_as_int (v) - 1;
-		value_release (v);
+		if (!valid) {
+			value_release (v);
+			return vi;
+		}
+		elem[i] = value_get_as_int (vi) - 1;
+		value_release (vi);
 	}
 
 	if (GNM_EXPR_GET_OPER (source) == GNM_EXPR_OP_SET) {
-		source = (elem[2] >= 0 && elem[2] < source->set.argc)
-			? source->set.argv[elem[2]]
-			: NULL;
-		if (source == NULL)
+		int w = value_area_get_height (v, ei->pos);
+		int i = elem[2];
+		GnmValue *vi;
+		if (i < 0 || i >= w) {
+			value_release (v);
 			return value_new_error_REF (ei->pos);
-	} else if (elem[2] != 0)
+		}
+		vi = value_dup (value_area_fetch_x_y (v, 0, i, ei->pos));
+		value_release (v);
+		v = vi;
+	} else if (elem[2] != 0) {
+		value_release (v);
 		return value_new_error_REF (ei->pos);
-
-	v = gnm_expr_eval (source, ei->pos, GNM_EXPR_EVAL_PERMIT_NON_SCALAR);
+	}
 
 	if (elem[1] < 0 ||
 	    elem[1] >= value_area_get_width (v, ei->pos) ||



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