[gnumeric] ods: fix import of references to sheet-local names.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] ods: fix import of references to sheet-local names.
- Date: Fri, 10 Mar 2017 18:25:14 +0000 (UTC)
commit 0bb7de3a7a8e5ece24f43e56d66a501a89323bb6
Author: Morten Welinder <terra gnome org>
Date: Fri Mar 10 13:24:27 2017 -0500
ods: fix import of references to sheet-local names.
plugins/openoffice/ChangeLog | 2 +
plugins/openoffice/openoffice-read.c | 48 ++++++++++++++++++++++++++++++++-
2 files changed, 48 insertions(+), 2 deletions(-)
---
diff --git a/plugins/openoffice/ChangeLog b/plugins/openoffice/ChangeLog
index ac3af52..8df0284 100644
--- a/plugins/openoffice/ChangeLog
+++ b/plugins/openoffice/ChangeLog
@@ -9,6 +9,8 @@
already create it.
(odf_preparse_create_sheet): New function extracted from
odf_preparse_create_sheet.
+ (odf_name_parser): New function to properly handle references to
+ sheet-local names.
* openoffice-write.c (odf_write_link_start): Write internal links
in the format Sheet1.A4 as both Excel and LO do.
diff --git a/plugins/openoffice/openoffice-read.c b/plugins/openoffice/openoffice-read.c
index 5e586e9..dc881e2 100644
--- a/plugins/openoffice/openoffice-read.c
+++ b/plugins/openoffice/openoffice-read.c
@@ -2145,6 +2145,49 @@ odf_expr_name_validate (const char *name)
return TRUE;
}
+/*
+ * This is ugly! And it's ods' fault.
+ *
+ * On one hand we have function names like ORG.GNUMERIC.LOG2, on the
+ * other we have inter-sheet name references Sheet2.localname
+ * The former is a name, the latter is a sheet name, a sheetsep, and
+ * a name.
+ *
+ * To resolve that, we look ahead for a '('.
+ */
+static char const *
+odf_name_parser (char const *str, GnmConventions const *convs)
+{
+ gunichar uc = g_utf8_get_char (str);
+ const char *firstdot = NULL;
+ int dotcount = 0;
+
+ if (!g_unichar_isalpha (uc) && uc != '_' && uc != '\\')
+ return NULL;
+
+ do {
+ str = g_utf8_next_char (str);
+ uc = g_utf8_get_char (str);
+
+ if (uc == '.') {
+ if (dotcount++ == 0)
+ firstdot = str;
+ }
+ } while (g_unichar_isalnum (uc) ||
+ (uc == '_' || uc == '?' || uc == '\\' || uc == '.'));
+
+ if (dotcount == 1 && convs->sheet_name_sep == '.') {
+ const char *p = str;
+
+ while (g_unichar_isspace (g_utf8_get_char (p)))
+ p = g_utf8_next_char (p);
+
+ if (*p != '(')
+ return firstdot;
+ }
+
+ return str;
+}
static GnmExpr const *
oo_func_map_in (GnmConventions const *convs, Workbook *scope,
@@ -2169,7 +2212,8 @@ oo_conventions_new (OOParseState *state, GsfXMLIn *xin)
conv->input.string = odf_strunescape;
conv->input.func = oo_func_map_in;
conv->input.range_ref = oo_expr_rangeref_parse;
- conv->input.name_validate = odf_expr_name_validate;
+ conv->input.name = odf_name_parser;
+ conv->input.name_validate = odf_expr_name_validate;
conv->sheet_name_sep = '.';
oconv->state = state;
oconv->xin = xin;
@@ -2212,7 +2256,7 @@ oo_expr_parse_str_try (GsfXMLIn *xin, char const *str,
if (state->convs[type] == NULL)
oo_load_convention (state, xin, type);
- return gnm_expr_parse_str (str, pp, flags,
+ return gnm_expr_parse_str (str, pp, flags | GNM_EXPR_PARSE_UNKNOWN_NAMES_ARE_INVALID,
state->convs[type], perr);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]