[gnumeric] ODF 1.2 import fix [#649906]



commit 1ee8b8645bce49c7f16ce6fd51d5641140526c14
Author: Andreas J Guelzow <aguelzow pyrshep ca>
Date:   Tue May 10 12:08:39 2011 -0600

    ODF 1.2 import fix [#649906]
    
    2011-05-09  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* openoffice-write.c (odf_string_handler): add comment
    	* openoffice-read.c (odf_strunescape): new
    	(oo_conventions_new): connect odf_strunescape
    
    2011-05-09  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* src/parse-util.h (_GnmConventions): add input.string
    	* src/parse-util.c (std_string_parser): new
    	(gnm_conventions_new_full): connect std_string_parser
    	* src/parser.y (yylex): use state->convs->input.string

 ChangeLog                             |    7 +++++++
 NEWS                                  |    2 +-
 plugins/openoffice/ChangeLog          |    6 ++++++
 plugins/openoffice/openoffice-read.c  |   32 ++++++++++++++++++++++++++++++++
 plugins/openoffice/openoffice-write.c |    5 +++++
 src/parse-util.c                      |    7 +++++++
 src/parse-util.h                      |    5 ++++-
 src/parser.y                          |    2 +-
 8 files changed, 63 insertions(+), 3 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index b8a5248..2ad563f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2011-05-09  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* src/parse-util.h (_GnmConventions): add input.string
+	* src/parse-util.c (std_string_parser): new
+	(gnm_conventions_new_full): connect std_string_parser
+	* src/parser.y (yylex): use state->convs->input.string
+
 2011-05-10  Morten Welinder  <terra gnome org>
 
 	* src/commands.c (cmd_paste_copy): Clarify and fix ownership rules
diff --git a/NEWS b/NEWS
index 4396890..a8a4266 100644
--- a/NEWS
+++ b/NEWS
@@ -13,7 +13,7 @@ Andreas:
 	* Handle MS Works formula import. [#649406]
 	* Restore Gnumeric print range. [#649714]
 	* Set default, save and restore print file name. [#649711][#649713]
-	* Some ODF 1.2 export fixes.
+	* Some ODF 1.2 export fixes including [#649906].
 
 Morten:
 	* Fix problems with localized function docs.
diff --git a/plugins/openoffice/ChangeLog b/plugins/openoffice/ChangeLog
index c6bcf4f..da82279 100644
--- a/plugins/openoffice/ChangeLog
+++ b/plugins/openoffice/ChangeLog
@@ -1,5 +1,11 @@
 2011-05-09  Andreas J. Guelzow <aguelzow pyrshep ca>
 
+	* openoffice-write.c (odf_string_handler): add comment
+	* openoffice-read.c (odf_strunescape): new
+	(oo_conventions_new): connect odf_strunescape
+
+2011-05-09  Andreas J. Guelzow <aguelzow pyrshep ca>
+
 	* openoffice-write.c (odf_string_handler): new
 	(odf_expr_conventions_new): connect odf_string_handler
 
diff --git a/plugins/openoffice/openoffice-read.c b/plugins/openoffice/openoffice-read.c
index 399c3bf..742766f 100644
--- a/plugins/openoffice/openoffice-read.c
+++ b/plugins/openoffice/openoffice-read.c
@@ -1179,6 +1179,37 @@ oo_expr_rangeref_parse (GnmRangeRef *ref, char const *start, GnmParsePos const *
 	return start;
 }
 
+static char const *
+odf_strunescape (char const *string, GString *target,
+		   G_GNUC_UNUSED GnmConventions const *convs)
+{
+	/* Constant strings are surrounded by double-quote characters */
+	/* (QUOTATION MARK, U+0022); a literal double-quote character '"'*/
+	/* (QUOTATION MARK, U+0022) as */
+	/* string content is escaped by duplicating it. */
+
+	char quote = *string++;
+	size_t oldlen = target->len;
+
+	/* This should be UTF-8 safe as long as quote is ASCII.  */
+	do {
+		while (*string != quote) {
+			if (*string == '\0')
+				goto error;
+			g_string_append_c (target, *string);
+			string++;
+		}
+		string++;
+		if (*string == quote)
+			g_string_append_c (target, quote);
+	} while (*string++ == quote);
+	return --string;
+
+ error:
+	g_string_truncate (target, oldlen);
+	return NULL;	
+}
+
 static GnmExpr const *
 oo_func_map_in (GnmConventions const *convs, Workbook *scope,
 		char const *name, GnmExprList *args);
@@ -1197,6 +1228,7 @@ oo_conventions_new (void)
 	conv->arg_sep		= ';';
 	conv->array_col_sep	= ';';
 	conv->array_row_sep	= '|';
+	conv->input.string	= odf_strunescape;
 	conv->input.func	= oo_func_map_in;
 	conv->input.range_ref	= oo_expr_rangeref_parse;
 	conv->sheet_name_sep	= '.';
diff --git a/plugins/openoffice/openoffice-write.c b/plugins/openoffice/openoffice-write.c
index a5e4fb3..9fb71f6 100644
--- a/plugins/openoffice/openoffice-write.c
+++ b/plugins/openoffice/openoffice-write.c
@@ -2400,6 +2400,11 @@ odf_expr_func_handler (GnmConventionsOut *out, GnmExprFunction const *func)
 static void
 odf_string_handler (GnmConventionsOut *out, GOString const *str)
 {
+	/* Constant strings are surrounded by double-quote characters */
+	/* (QUOTATION MARK, U+0022); a literal double-quote character '"'*/
+	/* (QUOTATION MARK, U+0022) as */
+	/* string content is escaped by duplicating it. */
+
 	gchar const *string = str->str;
 	g_string_append_c (out->accum, '"');
 	/* This loop should be UTF-8 safe.  */
diff --git a/src/parse-util.c b/src/parse-util.c
index 0af15fb..5a704d2 100644
--- a/src/parse-util.c
+++ b/src/parse-util.c
@@ -1332,6 +1332,12 @@ std_external_wb (G_GNUC_UNUSED GnmConventions const *convs,
 	return gnm_app_workbook_get_by_name (wb_name, ref_uri);
 }
 
+static char const *
+std_string_parser (char const *in, GString *target,
+		   G_GNUC_UNUSED GnmConventions const *convs)
+{
+	return go_strunescape (target, in);
+}
 
 /**
  * gnm_conventions_new_full :
@@ -1359,6 +1365,7 @@ gnm_conventions_new_full (unsigned size)
 	convs->intersection_char	= ' ';
 	convs->exp_is_left_associative  = FALSE;
 	convs->input.range_ref		= rangeref_parse;
+	convs->input.string		= std_string_parser;
 	convs->input.name		= std_name_parser;
 	convs->input.func		= std_func_map;
 	convs->input.external_wb	= std_external_wb;
diff --git a/src/parse-util.h b/src/parse-util.h
index 7270e07..cbe4b05 100644
--- a/src/parse-util.h
+++ b/src/parse-util.h
@@ -151,12 +151,15 @@ struct _GnmConventions {
 					  GnmConventions const *convs);
 					/* GError **err); */
 
+		/* Called to unescape strings */
+		char const *(*string) (char const *in, GString *target,
+				       GnmConventions const *convs);
+
 		/* Called a lot for anything that might be a function name or
 		 * defined name.  */
 		char const *(*name) (char const *in,
 				     GnmConventions const *convs);
 
-
 		/* Must return non-NULL, and absorb the args, including the list. */
 		GnmExpr const *(*func) (GnmConventions const *convs,
 				        /* make scope more useful, eg a
diff --git a/src/parser.y b/src/parser.y
index f599b47..1944056 100644
--- a/src/parser.y
+++ b/src/parser.y
@@ -1357,7 +1357,7 @@ yylex (void)
 	case '\'':
 	case '"': {
 		GString *s = g_string_new (NULL);
-		char const *end = go_strunescape (s, start);
+		char const *end = state->convs->input.string (start, s, state->convs);
 
 		if (end == NULL) {
 			size_t len = strlen (start);



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