[gnumeric] sax: fix array formula problem.



commit 1d8994453ec964b1cf7df74e375b4e29aaf46aec
Author: Morten Welinder <terra gnome org>
Date:   Wed Aug 4 22:13:32 2010 -0400

    sax: fix array formula problem.

 ChangeLog          |    5 +++++
 src/cell.c         |   41 ++++++++++++++++++++++++++++++++++++++++-
 src/cell.h         |    3 +++
 src/xml-sax-read.c |   28 ++++++++++++++++++----------
 4 files changed, 66 insertions(+), 11 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index cb9495f..923e945 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2010-08-04  Morten Welinder  <terra gnome org>
 
+	* src/xml-sax-read.c (xml_cell_set_array_expr): Use
+	gnm_cell_set_array.  Fixes #626034's original problem.
+
+	* src/cell.c (gnm_cell_set_array): New, somewhat saner variant.
+
 	* src/expr.c (gnm_expr_eval): Catch when the alleged array corner
 	isn't a corner.  See bug 626034.
 
diff --git a/src/cell.c b/src/cell.c
index 1590f04..35b5201 100644
--- a/src/cell.c
+++ b/src/cell.c
@@ -266,7 +266,7 @@ gnm_cell_set_expr (GnmCell *cell, GnmExprTop const *texpr)
  * @row_a:   The top row in the destination region.
  * @col_b:   The right column in the destination region.
  * @row_b:   The bottom row in the destination region.
- * @expr:    an expression (the inner expression, not a corner or element)
+ * @texpr:   an expression (the inner expression, not a corner or element)
  *
  * Uses cell_set_expr_internal to store the expr as an
  * 'array-formula'.  The supplied expression is wrapped in an array
@@ -350,6 +350,45 @@ gnm_cell_set_array_formula_undo (GnmSheetRange *sr, GnmExprTop const  *texpr)
 				   (GFreeFunc) gnm_expr_top_unref);
 }
 
+/**
+ * gnm_cell_set_array: set an array expression for a range.
+ * @sheet:   The sheet to set the expr in.
+ * @r:       The range to set.
+ * @texpr:   an expression (the inner expression, not a corner or element)
+ *
+ * Uses cell_set_expr_internal to store the expr as an
+ * 'array-formula'.  The supplied expression is wrapped in an array
+ * operator for each cell in the range and scheduled for recalc.
+ *
+ * Returns: TRUE if the operation succeded.
+ *
+ * NOTE : This adds a reference to the expression.
+ *
+ * Does not regenerate spans, dimensions or autosize cols/rows.
+ *
+ * DOES CHECK for array partitioning.
+ */
+
+gboolean
+gnm_cell_set_array (Sheet *sheet,
+		    const GnmRange *r,
+		    GnmExprTop const *texpr)
+{
+	g_return_val_if_fail (sheet != NULL, FALSE);
+	g_return_val_if_fail (range_is_sane (r), FALSE);
+	g_return_val_if_fail (texpr != NULL, FALSE);
+
+	if (sheet_range_splits_array (sheet, r, NULL, NULL, NULL))
+		return FALSE;
+
+	gnm_expr_top_ref (texpr);
+	gnm_cell_set_array_formula (sheet,
+				    r->start.col, r->start.row,
+				    r->end.col, r->end.row,
+				    texpr);
+	return TRUE;
+}
+
 /***************************************************************************/
 
 /**
diff --git a/src/cell.h b/src/cell.h
index 426ea99..86e8e49 100644
--- a/src/cell.h
+++ b/src/cell.h
@@ -73,6 +73,9 @@ void gnm_cell_set_array_formula	(Sheet *sheet,
 				 GnmExprTop const *texpr);
 GOUndo *gnm_cell_set_array_formula_undo (GnmSheetRange *sr, 
 					 GnmExprTop const  *texpr);
+gboolean gnm_cell_set_array     (Sheet *sheet,
+				 const GnmRange *r,
+				 GnmExprTop const *texpr);
 void gnm_cell_cleanout		(GnmCell *cell);
 void gnm_cell_convert_expr_to_value	(GnmCell *cell);
 
diff --git a/src/xml-sax-read.c b/src/xml-sax-read.c
index 97cc071..f206f21 100644
--- a/src/xml-sax-read.c
+++ b/src/xml-sax-read.c
@@ -87,16 +87,17 @@ xml_sax_barf (const char *locus, const char *reason)
 		   locus, reason);
 }
 
-#define XML_CHECK2(_cond_,_code_)			\
+#define XML_CHECK3(_cond_,_code_,_reason_)		\
   do {							\
 	  if (G_UNLIKELY(!(_cond_))) {			\
-		  xml_sax_barf (G_STRFUNC, #_cond_);	\
+		  xml_sax_barf (G_STRFUNC, _reason_);	\
 		  _code_;				\
 		  return;				\
 	  }						\
   } while (0)
 
-#define XML_CHECK(_cond_) XML_CHECK2(_cond_,{})
+#define XML_CHECK(_cond_) XML_CHECK3(_cond_,{},#_cond_)
+#define XML_CHECK2(_cond_,_code_) XML_CHECK3(_cond_,_code_,#_cond_)
 
 
 #define CXML2C(s) ((char const *)(s))
@@ -1837,17 +1838,24 @@ xml_cell_set_array_expr (XMLSaxParseState *state,
 				    GNM_EXPR_PARSE_DEFAULT,
 				    state->convs,
 				    NULL);
+	GnmRange r;
 
 	g_return_if_fail (texpr != NULL);
 
-	if (cell)
-		gnm_cell_set_array_formula (cell->base.sheet,
-					    cell->pos.col, cell->pos.row,
-					    cell->pos.col + cols - 1,
-					    cell->pos.row + rows - 1,
-					    texpr);
-	else
+	if (!cell) {
 		cc->texpr = texpr;
+		return;
+	}
+
+	r.start = r.end = cell->pos;
+	r.end.col += (cols - 1);
+	r.end.row += (rows - 1);
+
+	if (!gnm_cell_set_array (cell->base.sheet, &r, texpr)) {
+		xml_sax_barf (G_STRFUNC, "target area empty");
+	}
+
+	gnm_expr_top_unref (texpr);
 }
 
 /**



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