[gnumeric] .gnumeric: if we see a shared array formula, fix it.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] .gnumeric: if we see a shared array formula, fix it.
- Date: Wed, 25 Apr 2018 22:24:14 +0000 (UTC)
commit d78f0b632330554ab91ba6cd92c4261eebbf397e
Author: Morten Welinder <terra gnome org>
Date: Wed Apr 25 18:23:32 2018 -0400
.gnumeric: if we see a shared array formula, fix it.
ChangeLog | 7 +++++
NEWS | 1 +
samples/formula-tests.gnumeric | Bin 4330 -> 5051 bytes
src/xml-sax-read.c | 48 +++++++++++++++++++++++++---------------
4 files changed, 38 insertions(+), 18 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 0b79669..993aeed 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2018-04-25 Morten Welinder <terra gnome org>
+
+ * src/xml-sax-read.c (xml_sax_cell_content): Read shared array
+ expressions as we used to, but immediately unshare. I had an old
+ file with such a thing and it not supposed to happen. That
+ formula would likely have been created in early 2007.
+
2018-04-24 Morten Welinder <terra gnome org>
* src/commands.c (cmd_paste_copy_impl): Simplify now that
diff --git a/NEWS b/NEWS
index af5b16f..ac9d265 100644
--- a/NEWS
+++ b/NEWS
@@ -22,6 +22,7 @@ Morten:
* Fix problem with image pasting.
* Allow pasting an image into Gnumeric. [#366816]
* Full-column paste includes column width. [#121722]
+ * Auto-fix shared array formulas in gnumeric files.
--------------------------------------------------------------------------
Gnumeric 1.12.39
diff --git a/samples/formula-tests.gnumeric b/samples/formula-tests.gnumeric
index c0b27cd..d408cf8 100644
Binary files a/samples/formula-tests.gnumeric and b/samples/formula-tests.gnumeric differ
diff --git a/src/xml-sax-read.c b/src/xml-sax-read.c
index 71a6418..e6c1a03 100644
--- a/src/xml-sax-read.c
+++ b/src/xml-sax-read.c
@@ -2115,7 +2115,7 @@ xml_sax_cell_content (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
int const row = state->cell.row;
int const array_cols = state->array_cols;
int const array_rows = state->array_rows;
- int const expr_id = state->expr_id;
+ int expr_id = state->expr_id;
int const value_type = state->value_type;
gboolean const seen_contents = state->seen_cell_contents;
GOFormat *value_fmt = state->value_fmt;
@@ -2162,7 +2162,9 @@ xml_sax_cell_content (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
g_return_if_fail (content[0] == '=');
xml_cell_set_array_expr (state, cell, cc, content + 1,
array_cols, array_rows);
- goto done;
+ texpr = cell->base.texpr;
+ if (texpr) gnm_expr_top_ref (texpr);
+ goto store_shared;
}
// ----------------------------------------
@@ -2180,7 +2182,14 @@ xml_sax_cell_content (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
texpr = g_hash_table_lookup (state->expr_map,
GINT_TO_POINTER (expr_id));
- if (!texpr) {
+ if (texpr && gnm_expr_top_is_array_corner (texpr)) {
+ g_printerr ("Shared array formula -- how did that happen?\n");
+ texpr = gnm_expr_top_new (gnm_expr_copy (texpr->expr));
+ expr_id = -1;
+ } else if (texpr) {
+ gnm_expr_top_ref (texpr);
+ expr_id = -1;
+ } else {
char *msg = g_strdup_printf
("Looking up shared expression id %d",
expr_id);
@@ -2189,11 +2198,7 @@ xml_sax_cell_content (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
g_free (msg);
texpr = gnm_expr_top_new_constant (value_new_string_nocopy (s));
- g_hash_table_insert (state->expr_map,
- GINT_TO_POINTER (expr_id),
- (gpointer)texpr);
}
- gnm_expr_top_ref (texpr);
goto assign_and_done;
}
@@ -2249,13 +2254,11 @@ xml_sax_cell_content (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
gpointer id = GINT_TO_POINTER (expr_id);
GnmExprTop const *texpr0 =
g_hash_table_lookup (state->expr_map, id);
- if (!texpr0) {
- gnm_expr_top_ref (texpr);
- g_hash_table_insert (state->expr_map,
- id,
- (gpointer)texpr);
- } else if (!is_post_52_array)
- g_warning ("XML-IO : Duplicate shared expression");
+ if (texpr0) {
+ if (!is_post_52_array)
+ g_warning ("XML-IO: Duplicate shared expression");
+ expr_id = -1;
+ }
}
}
@@ -2264,17 +2267,26 @@ assign_and_done:
v = value_new_empty ();
if (cell) {
// Regular case
- if (texpr) {
+ if (texpr)
gnm_cell_set_expr_and_value (cell, texpr, v, TRUE);
- gnm_expr_top_unref (texpr);
- } else
+ else
gnm_cell_set_value (cell, v);
} else {
// Clipboard case
- cc->texpr = texpr;
+ cc->texpr = texpr ? gnm_expr_top_ref (texpr) : NULL;
cc->val = v;
}
+store_shared:
+ if (texpr) {
+ if (expr_id > 0)
+ g_hash_table_insert (state->expr_map,
+ GINT_TO_POINTER (expr_id),
+ (gpointer)texpr);
+ else
+ gnm_expr_top_unref (texpr);
+ }
+
done:
go_format_unref (value_fmt);
g_free (value_result);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]