[gnumeric] Handle [#REF!] and friends on ODF import. [#650639][#650640] Handle some invalid expressions in ODF
- From: Andreas J. Guelzow <guelzow src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] Handle [#REF!] and friends on ODF import. [#650639][#650640] Handle some invalid expressions in ODF
- Date: Fri, 20 May 2011 21:07:29 +0000 (UTC)
commit 3800a0bc1586e5694533bb5fa17c6fd0ad3b5c38
Author: Andreas J Guelzow <aguelzow pyrshep ca>
Date: Fri May 20 15:06:21 2011 -0600
Handle [#REF!] and friends on ODF import. [#650639][#650640]
Handle some invalid expressions in ODF import. [#650625]
2011-05-20 Andreas J. Guelzow <aguelzow pyrshep ca>
* openoffice-read.c (oo_cellref_check_for_err): look for #REF!
(oo_cellref_parse): use oo_cellref_check_for_err, don't create
new sheets until we know that we likely have a valid reference
(oo_expr_parse_str_try): new
(oo_expr_parse_str): use oo_expr_parse_str_try, handle references
that are missing []
2011-05-20 Andreas J. Guelzow <aguelzow pyrshep ca>
* src/sheet.h (invalid_sheet): make non-const to avoid casts
* src/sheet.c (invalid_sheet): ditto
ChangeLog | 5 ++
NEWS | 3 +-
plugins/openoffice/ChangeLog | 9 +++
plugins/openoffice/openoffice-read.c | 116 ++++++++++++++++++++++++----------
src/sheet.c | 4 +-
src/sheet.h | 2 +-
6 files changed, 102 insertions(+), 37 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 75a78fd..66a6489 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,11 @@
2011-05-20 Andreas J. Guelzow <aguelzow pyrshep ca>
+ * src/sheet.h (invalid_sheet): make non-const to avoid casts
+ * src/sheet.c (invalid_sheet): ditto
+
+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
diff --git a/NEWS b/NEWS
index c1a0ea8..850f097 100644
--- a/NEWS
+++ b/NEWS
@@ -20,7 +20,8 @@ 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]
+ * Handle [#REF!] and friends on ODF import. [#650639][#650640]
+ * Handle some invalid expressions in ODF import. [#650625]
Jean:
* Fixed critical. [#649901]
diff --git a/plugins/openoffice/ChangeLog b/plugins/openoffice/ChangeLog
index e923d32..d424838 100644
--- a/plugins/openoffice/ChangeLog
+++ b/plugins/openoffice/ChangeLog
@@ -1,5 +1,14 @@
2011-05-20 Andreas J. Guelzow <aguelzow pyrshep ca>
+ * openoffice-read.c (oo_cellref_check_for_err): look for #REF!
+ (oo_cellref_parse): use oo_cellref_check_for_err, don't create
+ new sheets until we know that we likely have a valid reference
+ (oo_expr_parse_str_try): new
+ (oo_expr_parse_str): use oo_expr_parse_str_try, handle references
+ that are missing []
+
+2011-05-20 Andreas J. Guelzow <aguelzow pyrshep ca>
+
* openoffice-write.c (odf_write_named_expression): only write
active names
diff --git a/plugins/openoffice/openoffice-read.c b/plugins/openoffice/openoffice-read.c
index ced9c74..5acc371 100644
--- a/plugins/openoffice/openoffice-read.c
+++ b/plugins/openoffice/openoffice-read.c
@@ -1051,13 +1051,30 @@ oo_attr_enum (GsfXMLIn *xin, xmlChar const * const *attrs,
name, attrs[1]);
}
+static gboolean
+oo_cellref_check_for_err (GnmCellRef *ref, char const **start)
+{
+ if (g_str_has_prefix (*start, "$#REF!")) {
+ ref->sheet = invalid_sheet;
+ *start += 6;
+ return TRUE;
+ }
+ if (g_str_has_prefix (*start, "#REF!")) {
+ ref->sheet = invalid_sheet;
+ *start += 5;
+ return TRUE;
+ }
+ return FALSE;
+}
+
static char const *
oo_cellref_parse (GnmCellRef *ref, char const *start, GnmParsePos const *pp)
{
- char const *tmp1, *tmp2, *ptr = start;
+ char const *tmp, *ptr = start;
GnmSheetSize const *ss;
GnmSheetSize ss_max = { GNM_MAX_COLS, GNM_MAX_ROWS};
Sheet *sheet;
+ char *new_sheet_name = NULL;
if (*ptr != '.') {
char *name, *accum;
@@ -1069,35 +1086,35 @@ oo_cellref_parse (GnmCellRef *ref, char const *start, GnmParsePos const *pp)
/* From the spec :
* SheetName ::= [^\. ']+ | "'" ([^'] | "''")+ "'" */
if ('\'' == *ptr) {
- tmp1 = ++ptr;
+ tmp = ++ptr;
two_quotes :
/* missing close paren */
- if (NULL == (tmp1 = strchr (tmp1, '\'')))
+ if (NULL == (tmp = strchr (tmp, '\'')))
return start;
/* two in a row is the escape for a single */
- if (tmp1[1] == '\'') {
- tmp1 += 2;
+ if (tmp[1] == '\'') {
+ tmp += 2;
goto two_quotes;
}
/* If a name is quoted the entire named must be quoted */
- if (tmp1[1] != '.')
+ if (tmp[1] != '.')
return start;
- accum = name = g_alloca (tmp1-ptr+1);
- while (ptr != tmp1)
+ accum = name = g_alloca (tmp-ptr+1);
+ while (ptr != tmp)
if ('\'' == (*accum++ = *ptr++))
ptr++;
*accum = '\0';
ptr += 2;
} else {
- if (NULL == (tmp1 = strchr (ptr, '.')))
+ if (NULL == (tmp = strchr (ptr, '.')))
return start;
- name = g_alloca (tmp1-ptr+1);
- strncpy (name, ptr, tmp1-ptr);
- name[tmp1-ptr] = '\0';
- ptr = tmp1 + 1;
+ name = g_alloca (tmp-ptr+1);
+ strncpy (name, ptr, tmp-ptr);
+ name[tmp-ptr] = '\0';
+ ptr = tmp + 1;
}
if (name[0] == 0)
@@ -1111,11 +1128,10 @@ two_quotes :
if (strcmp (name, "#REF!") == 0) {
ref->sheet = invalid_sheet;
} else {
- Sheet *old_sheet = workbook_sheet_by_index (pp->wb, 0);
- ref->sheet = sheet_new (pp->wb, name,
- gnm_sheet_get_max_cols (old_sheet),
- gnm_sheet_get_max_rows (old_sheet));
- workbook_sheet_attach (pp->wb, ref->sheet);
+ /* We can't add it yet since this whole ref */
+ /* may be invalid */
+ new_sheet_name = g_strdup (name);
+ ref->sheet = NULL;
}
}
} else {
@@ -1123,15 +1139,30 @@ two_quotes :
ref->sheet = NULL;
}
- tmp1 = col_parse (ptr, &ss_max, &ref->col, &ref->col_relative);
- if (!tmp1)
+ tmp = col_parse (ptr, &ss_max, &ref->col, &ref->col_relative);
+ if (!tmp && !oo_cellref_check_for_err (ref, &ptr))
return start;
- tmp2 = row_parse (tmp1, &ss_max, &ref->row, &ref->row_relative);
- if (!tmp2)
+ if (tmp)
+ ptr = tmp;
+ tmp = row_parse (ptr, &ss_max, &ref->row, &ref->row_relative);
+ if (!tmp && !oo_cellref_check_for_err (ref, &ptr))
return start;
+ if (tmp)
+ ptr = tmp;
- if (ref->sheet == invalid_sheet)
- return tmp2;
+ if (ref->sheet == invalid_sheet) {
+ g_free (new_sheet_name);
+ return ptr;
+ }
+
+ if (new_sheet_name != NULL) {
+ Sheet *old_sheet = workbook_sheet_by_index (pp->wb, 0);
+ ref->sheet = sheet_new (pp->wb, new_sheet_name,
+ gnm_sheet_get_max_cols (old_sheet),
+ gnm_sheet_get_max_rows (old_sheet));
+ workbook_sheet_attach (pp->wb, ref->sheet);
+ g_free (new_sheet_name);
+ }
sheet = eval_sheet (ref->sheet, pp->sheet);
ss = gnm_sheet_get_size (sheet);
@@ -1155,7 +1186,7 @@ two_quotes :
if (ref->row_relative)
ref->row -= pp->eval.row;
- return tmp2;
+ return ptr;
}
static char const *
@@ -1426,24 +1457,43 @@ oo_load_convention (OOParseState *state, OOFormula type)
}
static GnmExprTop const *
+oo_expr_parse_str_try (GsfXMLIn *xin, char const *str,
+ GnmParsePos const *pp, GnmExprParseFlags flags,
+ OOFormula type, GnmParseError *perr)
+{
+ OOParseState *state = (OOParseState *)xin->user_state;
+
+ if (state->convs[type] == NULL)
+ oo_load_convention (state, type);
+ return gnm_expr_parse_str (str, pp, flags,
+ state->convs[type], perr);
+}
+
+static GnmExprTop const *
oo_expr_parse_str (GsfXMLIn *xin, char const *str,
GnmParsePos const *pp, GnmExprParseFlags flags,
OOFormula type)
{
- OOParseState *state = (OOParseState *)xin->user_state;
GnmExprTop const *texpr;
GnmParseError perr;
- if (state->convs[type] == NULL)
- oo_load_convention (state, type);
parse_error_init (&perr);
- texpr = gnm_expr_parse_str (str, pp, flags,
- state->convs[type], &perr);
+
+ texpr = oo_expr_parse_str_try (xin, str, pp, flags, type, &perr);
if (texpr == NULL) {
- oo_warning (xin, _("Unable to parse '%s' ('%s')"),
- str, perr.err->message);
- parse_error_free (&perr);
+ if (*str != '[') {
+ /* There are faulty expressions in the wild that */
+ /* are references w/o [] */
+ char *test = g_strdup_printf ("[%s]", str);
+ texpr = oo_expr_parse_str_try (xin, test, pp,
+ flags, type, NULL);
+ g_free (test);
+ }
+ if (texpr == NULL)
+ oo_warning (xin, _("Unable to parse '%s' ('%s')"),
+ str, perr.err->message);
}
+ parse_error_free (&perr);
return texpr;
}
diff --git a/src/sheet.c b/src/sheet.c
index 5bc8848..795c962 100644
--- a/src/sheet.c
+++ b/src/sheet.c
@@ -806,8 +806,8 @@ gnm_sheet_init (Sheet *sheet)
sheet->index_in_wb = -1;
}
-static const Sheet the_invalid_sheet;
-const Sheet *invalid_sheet = &the_invalid_sheet;
+static Sheet the_invalid_sheet;
+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 17afa4d..99e3b76 100644
--- a/src/sheet.h
+++ b/src/sheet.h
@@ -11,7 +11,7 @@
G_BEGIN_DECLS
-GNM_VAR_DECL const Sheet *invalid_sheet;
+GNM_VAR_DECL Sheet *invalid_sheet;
struct _GnmSheetSize {
int max_cols, max_rows;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]