[gnumeric] Handle [#REF!] and friends on ODF import. [#650640]



commit cd4a5fc562c187f9bfa8ead5876735b5b59638a6
Author: Andreas J Guelzow <aguelzow pyrshep ca>
Date:   Fri May 20 11:49:25 2011 -0600

    Handle [#REF!] and friends on ODF import. [#650640]
    
    2011-05-20  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* openoffice-read.c (oo_cellref_parse): return invalid_sheet when
    	encountering #REF!, check for this return value in all callers
    	(oo_rangeref_parse): check for invalid_sheet, check for this return
    	value in all callers
    	(oo_expr_rangeref_parse): check for [#REF!]
    
    2011-05-20  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* src/sheet.h (invalid_sheet): new
    	* src/sheet.c (invalid_sheet): initialize
    	* src/parser.y (yylex): convs->input.range_ref might return
    	invalid_sheet

 ChangeLog                            |    7 +++++
 NEWS                                 |    1 +
 plugins/openoffice/ChangeLog         |   10 ++++++-
 plugins/openoffice/openoffice-read.c |   46 +++++++++++++++++++++++----------
 src/parser.y                         |    6 ++++
 src/sheet.c                          |    3 ++
 src/sheet.h                          |    3 ++
 7 files changed, 61 insertions(+), 15 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index f483a4a..efe0eca 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2011-05-20  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* src/sheet.h (invalid_sheet): new
+	* src/sheet.c (invalid_sheet): initialize
+	* src/parser.y (yylex): convs->input.range_ref might return
+	invalid_sheet
+
 2011-05-20  Morten Welinder  <terra gnome org>
 
 	* src/expr-name.c (expr_name_is_active): New function.
diff --git a/NEWS b/NEWS
index 299a962..f3636a5 100644
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,7 @@ Andreas:
 	* Export all validations to ODF.
 	* Fix printing of background colours. [#650261]
 	* From ODF also import named expressions with illegal name. [#650125]
+	* Handle [#REF!] and friends on ODF import. [#650640]
 
 Jean:
 	* Fixed critical. [#649901]
diff --git a/plugins/openoffice/ChangeLog b/plugins/openoffice/ChangeLog
index 111373b..fc7cd12 100644
--- a/plugins/openoffice/ChangeLog
+++ b/plugins/openoffice/ChangeLog
@@ -1,3 +1,11 @@
+2011-05-20  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* openoffice-read.c (oo_cellref_parse): return invalid_sheet when
+	encountering #REF!, check for this return value in all callers
+	(oo_rangeref_parse): check for invalid_sheet, check for this return 
+	value in all callers
+	(oo_expr_rangeref_parse): check for [#REF!]
+
 2011-05-19  Andreas J. Guelzow <aguelzow pyrshep ca>
 
 	* openoffice-read.c (odf_fix_expr_names): implement
@@ -7,7 +15,7 @@
 	(odf_fix_en_validate): new
 	(odf_fix_en_collect): new
 	(odf_fix_en_apply): new
-	
+
 2011-05-19  Andreas J. Guelzow <aguelzow pyrshep ca>
 
 	* openoffice-write.c (odf_write_sheet): use sheet_get_cells_extent
diff --git a/plugins/openoffice/openoffice-read.c b/plugins/openoffice/openoffice-read.c
index 20a4156..ced9c74 100644
--- a/plugins/openoffice/openoffice-read.c
+++ b/plugins/openoffice/openoffice-read.c
@@ -1109,8 +1109,7 @@ two_quotes :
 		ref->sheet = workbook_sheet_by_name (pp->wb, name);
 		if (ref->sheet == NULL) {
 			if (strcmp (name, "#REF!") == 0) {
-				g_warning ("Ignoring reference to sheet %s", name);
-				ref->sheet = NULL;
+				ref->sheet = invalid_sheet;
 			} else {
 				Sheet *old_sheet = workbook_sheet_by_index (pp->wb, 0);
 				ref->sheet = sheet_new (pp->wb, name,
@@ -1131,6 +1130,9 @@ two_quotes :
 	if (!tmp2)
 		return start;
 
+	if (ref->sheet == invalid_sheet)
+		return tmp2;
+
 	sheet = eval_sheet (ref->sheet, pp->sheet);
 	ss = gnm_sheet_get_size (sheet);
 
@@ -1164,6 +1166,8 @@ oo_rangeref_parse (GnmRangeRef *ref, char const *start, GnmParsePos const *pp)
 		ptr = oo_cellref_parse (&ref->b, ptr+1, pp);
 	else
 		ref->b = ref->a;
+	if (ref->b.sheet == invalid_sheet)
+		ref->a.sheet = invalid_sheet;
 	return ptr;
 }
 
@@ -1173,6 +1177,10 @@ oo_expr_rangeref_parse (GnmRangeRef *ref, char const *start, GnmParsePos const *
 {
 	char const *ptr;
 	if (*start == '[') {
+		if (strncmp (start, "[#REF!]", 7) == 0) {
+			ref->a.sheet = invalid_sheet;
+			return start + 7;
+		}
 		ptr = oo_rangeref_parse (ref, start+1, pp);
 		if (*ptr == ']')
 			return ptr + 1;
@@ -5186,10 +5194,14 @@ oo_db_range_start (GsfXMLIn *xin, xmlChar const **attrs)
 	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
 		if (gsf_xml_in_namecmp (xin, CXML2C (attrs[0]), OO_NS_TABLE, "target-range-address")) {
 			char const *ptr = oo_cellref_parse (&ref.a, CXML2C (attrs[1]), &state->pos);
-			if (':' == *ptr &&
-			    '\0' == *oo_cellref_parse (&ref.b, ptr+1, &state->pos)) {
-				state->filter = gnm_filter_new (ref.a.sheet, range_init_rangeref (&r, &ref));
-				expr = gnm_expr_new_constant (value_new_cellrange_r (ref.a.sheet, &r));
+			if (ref.a.sheet != invalid_sheet &&
+			    ':' == *ptr &&
+			    '\0' == *oo_cellref_parse (&ref.b, ptr+1, &state->pos) &&
+			    ref.b.sheet != invalid_sheet) {
+				state->filter = gnm_filter_new 
+					(ref.a.sheet, range_init_rangeref (&r, &ref));
+				expr = gnm_expr_new_constant 
+					(value_new_cellrange_r (ref.a.sheet, &r));
 			} else
 				oo_warning (xin, _("Invalid DB range '%s'"), attrs[1]);
 		} else if (oo_attr_bool (xin, attrs, OO_NS_TABLE, "display-filter-buttons", &buttons))
@@ -5504,7 +5516,8 @@ od_draw_control_start (GsfXMLIn *xin, xmlChar const **attrs)
 				char const *ptr = oo_rangeref_parse
 					(&ref, oc->linked_cell,
 					 parse_pos_init_sheet (&pp, state->pos.sheet));
-				if (ptr != oc->linked_cell) {
+				if (ptr != oc->linked_cell 
+				    && ref.a.sheet != invalid_sheet) {
 					GnmValue *v = value_new_cellrange
 						(&ref.a, &ref.a, 0, 0);
 					GnmExprTop const *texpr
@@ -5541,7 +5554,8 @@ od_draw_control_start (GsfXMLIn *xin, xmlChar const **attrs)
 					char const *ptr = oo_rangeref_parse
 						(&ref, oc->source_cell_range,
 						 parse_pos_init_sheet (&pp, state->pos.sheet));
-					if (ptr != oc->source_cell_range) {
+					if (ptr != oc->source_cell_range && 
+					    ref.a.sheet != invalid_sheet) {
 						GnmValue *v = value_new_cellrange
 							(&ref.a, &ref.b, 0, 0);
 						GnmExprTop const *texpr
@@ -6011,7 +6025,7 @@ oo_plot_assign_dim (GsfXMLIn *xin, xmlChar const *range, int dim_type, char cons
 		GnmRangeRef ref;
 		char const *ptr = oo_rangeref_parse (&ref, CXML2C (range),
 			parse_pos_init_sheet (&pp, state->pos.sheet));
-		if (ptr == CXML2C (range))
+		if (ptr == CXML2C (range) || ref.a.sheet == invalid_sheet)
 			return;
 		v = value_new_cellrange (&ref.a, &ref.b, 0, 0);
 		if (state->debug)
@@ -6148,7 +6162,8 @@ oo_plot_area (GsfXMLIn *xin, xmlChar const **attrs)
 		Sheet	   *dummy;
 		char const *ptr = oo_rangeref_parse (&ref, CXML2C (source_range_str),
 			parse_pos_init_sheet (&pp, state->pos.sheet));
-		if (ptr != CXML2C (source_range_str)) {
+		if (ptr != CXML2C (source_range_str) 
+		    && ref.a.sheet != invalid_sheet) {
 			gnm_rangeref_normalize (&ref,
 				eval_pos_init_sheet (&ep, state->pos.sheet),
 				&state->chart.src_sheet, &dummy,
@@ -6352,7 +6367,8 @@ oo_plot_series (GsfXMLIn *xin, xmlChar const **attrs)
 					GnmParsePos pp;
 					char const *ptr = oo_rangeref_parse (&ref, CXML2C (attrs[1]),
 									     parse_pos_init_sheet (&pp, state->pos.sheet));
-					if (ptr == CXML2C (attrs[1]))
+					if (ptr == CXML2C (attrs[1]) || 
+					    ref.a.sheet == invalid_sheet)
 						return;
 					v = value_new_cellrange (&ref.a, &ref.b, 0, 0);
 					texpr = gnm_expr_top_new_constant (v);
@@ -6398,7 +6414,8 @@ oo_plot_series (GsfXMLIn *xin, xmlChar const **attrs)
 			char const *ptr = oo_rangeref_parse
 				(&ref, CXML2C (label),
 				 parse_pos_init_sheet (&pp, state->pos.sheet));
-			if (ptr == CXML2C (label))
+			if (ptr == CXML2C (label) 
+			    || ref.a.sheet == invalid_sheet)
 				texpr = oo_expr_parse_str (xin, label,
 							   &state->pos,
 							   GNM_EXPR_PARSE_DEFAULT,
@@ -6587,7 +6604,7 @@ odf_store_data (OOParseState *state, gchar const *str, GogObject *obj, int dim)
 		char const *ptr = oo_rangeref_parse
 			(&ref, CXML2C (str),
 			 parse_pos_init (&pp, state->pos.wb, NULL, 0, 0));
-		if (ptr != CXML2C (str)) {
+		if (ptr != CXML2C (str) && ref.a.sheet != invalid_sheet) {
 			GnmValue *v = value_new_cellrange (&ref.a, &ref.b, 0, 0);
 			GnmExprTop const *texpr = gnm_expr_top_new_constant (v);
 			if (NULL != texpr) {
@@ -7053,7 +7070,8 @@ odf_line (GsfXMLIn *xin, xmlChar const **attrs)
 			char const *ptr = oo_rangeref_parse
 				(&ref, CXML2C (attrs[1]),
 				 parse_pos_init_sheet (&pp, state->pos.sheet));
-			if (ptr != CXML2C (attrs[1])) {
+			if (ptr != CXML2C (attrs[1]) 
+			    && ref.a.sheet != invalid_sheet) {
 				cell_base.end.col = ref.a.col;
 				cell_base.end.row = ref.a.row;
 			}
diff --git a/src/parser.y b/src/parser.y
index 15f5f9b..395c5b2 100644
--- a/src/parser.y
+++ b/src/parser.y
@@ -1185,6 +1185,12 @@ yylex (void)
 	 */
 	if (start != end && !open_paren (end)) {
 		state->ptr = end;
+		if (invalid_sheet == ref.a.sheet) {
+		        yylval.expr = register_expr_allocation
+		                (gnm_expr_new_constant 
+				 (value_new_error_REF (NULL)));
+			return CONSTANT;
+		}
 		if (state->flags & GNM_EXPR_PARSE_FORCE_ABSOLUTE_REFERENCES) {
 			if (ref.a.col_relative) {
 				ref.a.col += state->pos->eval.col;
diff --git a/src/sheet.c b/src/sheet.c
index 76bacac..5bc8848 100644
--- a/src/sheet.c
+++ b/src/sheet.c
@@ -806,6 +806,9 @@ gnm_sheet_init (Sheet *sheet)
 	sheet->index_in_wb = -1;
 }
 
+static const Sheet the_invalid_sheet;
+const Sheet *invalid_sheet = &the_invalid_sheet;
+
 static void
 gnm_sheet_class_init (GObjectClass *gobject_class)
 {
diff --git a/src/sheet.h b/src/sheet.h
index 008693d..17afa4d 100644
--- a/src/sheet.h
+++ b/src/sheet.h
@@ -7,9 +7,12 @@
 #include "position.h"
 #include <pango/pango.h>
 #include <goffice/goffice.h>
+#include "libgnumeric.h"
 
 G_BEGIN_DECLS
 
+GNM_VAR_DECL const Sheet *invalid_sheet;
+
 struct _GnmSheetSize {
 	int max_cols, max_rows;
 };



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