[gnumeric] ssdiff: move comparison engine into its own file.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] ssdiff: move comparison engine into its own file.
- Date: Mon, 9 Apr 2018 01:43:48 +0000 (UTC)
commit 53e138688d0fc857b6922ed53f4e0576ea80c6af
Author: Morten Welinder <terra gnome org>
Date: Sat Apr 7 21:30:13 2018 -0400
ssdiff: move comparison engine into its own file.
src/Makefile.am | 160 ++++++++--------
src/sheet-diff.c | 542 ++++++++++++++++++++++++++++++++++++++++++++++++++
src/sheet-diff.h | 72 +++++++
src/ssdiff.c | 579 +++++-------------------------------------------------
4 files changed, 741 insertions(+), 612 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index e87c6ed..ce654bc 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -104,44 +104,50 @@ libspreadsheet_la_SOURCES = \
gnm-marshalers.c \
application.c \
auto-format.c \
- cell.c \
cell-draw.c \
+ cell.c \
cellspan.c \
clipboard.c \
- criteria.c \
cmd-edit.c \
collect.c \
colrow.c \
- command-context.c \
command-context-stderr.c \
+ command-context.c \
commands.c \
- complete.c \
complete-sheet.c \
+ complete.c \
complex.c \
consolidate.c \
+ criteria.c \
dependent.c \
- expr.c \
expr-deriv.c \
expr-name.c \
+ expr.c \
file-autoft.c \
format-template.c \
- func.c \
func-builtin.c \
+ func.c \
gnm-commands-slicer.c \
gnm-datetime.c \
gnm-format.c \
gnm-graph-window.c \
- gnm-pane.c \
gnm-pane-impl.h \
+ gnm-pane.c \
+ gnm-plugin.c \
gnm-random.c \
+ gnm-so-filled.c \
+ gnm-so-line.c \
+ gnm-so-path.c \
+ gnm-so-polygon.c \
+ gnumeric-conf.c \
gnumeric-simple-canvas.c \
graph.c \
- gutils.c \
gui-clipboard.c \
gui-file.c \
gui-util.c \
- hlink.c \
+ gutils.c \
history.c \
+ hlink.c \
input-msg.c \
item-bar.c \
item-cursor.c \
@@ -152,15 +158,17 @@ libspreadsheet_la_SOURCES = \
mstyle.c \
number-match.c \
outoflinedocs.c \
- parser.y \
parse-util.c \
+ parser.y \
pattern.c \
position.c \
- preview-grid.c \
preview-grid-impl.h \
+ preview-grid.c \
+ print-cell.c \
print-info.c \
- rangefunc.c \
+ print.c \
rangefunc-strings.c \
+ rangefunc.c \
ranges.c \
rendered-value.c \
search.c \
@@ -170,50 +178,43 @@ libspreadsheet_la_SOURCES = \
sf-dpq.c \
sf-gamma.c \
sf-trig.c \
- sheet.c \
- sheet-view.c \
- sheet-control.c \
- sheet-control-gui.c \
- sheet-merge.c \
sheet-autofill.c \
+ sheet-control-gui.c \
+ sheet-control.c \
+ sheet-diff.c \
sheet-filter.c \
- sheet-utils.c \
- sheet-object.c \
+ sheet-merge.c \
sheet-object-cell-comment.c \
- gnm-so-filled.c \
- gnm-so-line.c \
- gnm-so-path.c \
- gnm-so-polygon.c \
sheet-object-component.c \
sheet-object-graph.c \
sheet-object-image.c \
sheet-object-widget.c \
+ sheet-object.c \
sheet-style.c \
- gnm-plugin.c \
+ sheet-utils.c \
+ sheet-view.c \
+ sheet.c \
sort.c \
- stf.c \
stf-export.c \
stf-parse.c \
- style.c \
+ stf.c \
style-border.c \
style-color.c \
style-conditions.c \
+ style.c \
undo.c \
validation.c \
- value.c \
value-sheet.c \
- workbook.c \
- workbook-cmd-format.c \
- workbook-view.c \
- workbook-control.c \
- wbc-gtk.c \
+ value.c \
wbc-gtk-actions.c \
wbc-gtk-edit.c \
+ wbc-gtk.c \
+ workbook-cmd-format.c \
+ workbook-control.c \
+ workbook-view.c \
+ workbook.c \
xml-sax-read.c \
- xml-sax-write.c \
- gnumeric-conf.c \
- print.c \
- print-cell.c
+ xml-sax-write.c
nodist_libspreadsheet_la_SOURCES = gnmresources.c gnmresources.h
@@ -224,30 +225,30 @@ libspreadsheet_includedir = $(includedir)/libspreadsheet-@GNUMERIC_API_VER@/spre
libspreadsheet_include_HEADERS = \
application.h \
auto-format.h \
- cell.h \
cell-draw.h \
+ cell.h \
cellspan.h \
clipboard.h \
cmd-edit.h \
collect.h \
colrow.h \
- command-context.h \
command-context-stderr.h \
+ command-context.h \
commands.h \
- complete.h \
complete-sheet.h \
+ complete.h \
complex.h \
consolidate.h \
criteria.h \
dependent.h \
- expr.h \
expr-deriv.h \
expr-impl.h \
expr-name.h \
+ expr.h \
file-autoft.h \
format-template.h \
- func.h \
func-builtin.h \
+ func.h \
gnm-command-impl.h \
gnm-commands-slicer.h \
gnm-data-cache-source.h \
@@ -255,26 +256,32 @@ libspreadsheet_include_HEADERS = \
gnm-format.h \
gnm-graph-window.h \
gnm-pane.h \
+ gnm-plugin.h \
gnm-random.h \
gnm-sheet-slicer.h \
+ gnm-so-filled.h \
+ gnm-so-line.h \
+ gnm-so-path.h \
+ gnm-so-polygon.h \
gnm-style-impl.h \
- gnumeric.h \
+ gnumeric-conf.h \
gnumeric-fwd.h \
gnumeric-simple-canvas.h \
+ gnumeric.h \
+ go-data-cache-field.h \
go-data-cache-source.h \
go-data-cache.h \
- go-data-cache-field.h \
- go-data-slicer.h \
go-data-slicer-field.h \
+ go-data-slicer.h \
go-val.h \
graph.h \
- gutils.h \
gui-clipboard.h \
gui-file.h \
gui-util.h \
- hlink.h \
- hlink-impl.h \
+ gutils.h \
history.h \
+ hlink-impl.h \
+ hlink.h \
input-msg.h \
item-bar.h \
item-cursor.h \
@@ -289,9 +296,11 @@ libspreadsheet_include_HEADERS = \
pattern.h \
position.h \
preview-grid.h \
+ print-cell.h \
print-info.h \
- rangefunc.h \
+ print.h \
rangefunc-strings.h \
+ rangefunc.h \
ranges.h \
regression.h \
rendered-value.h \
@@ -302,58 +311,51 @@ libspreadsheet_include_HEADERS = \
sf-dpq.h \
sf-gamma.h \
sf-trig.h \
- sheet.h \
- sheet-view.h \
- sheet-control.h \
- sheet-control-priv.h \
- sheet-control-gui.h \
- sheet-control-gui-priv.h \
- sheet-merge.h \
- sheet-private.h \
sheet-autofill.h \
- sheet-filter.h \
- sheet-utils.h \
+ sheet-control-gui-priv.h \
+ sheet-control-gui.h \
+ sheet-control-priv.h \
+ sheet-control.h \
+ sheet-diff.h \
sheet-filter-combo.h \
- sheet-object.h \
- sheet-object-impl.h \
+ sheet-filter.h \
+ sheet-merge.h \
sheet-object-cell-comment.h \
- sheet-object-widget-impl.h \
- gnm-so-filled.h \
- gnm-so-line.h \
- gnm-so-path.h \
- gnm-so-polygon.h \
sheet-object-component.h \
sheet-object-graph.h \
sheet-object-image.h \
+ sheet-object-impl.h \
+ sheet-object-widget-impl.h \
sheet-object-widget.h \
+ sheet-object.h \
+ sheet-private.h \
sheet-style.h \
- gnm-plugin.h \
+ sheet-utils.h \
+ sheet-view.h \
+ sheet.h \
sort.h \
- stf.h \
stf-export.h \
stf-parse.h \
- style.h \
+ stf.h \
style-border.h \
style-color.h \
style-conditions.h \
style-font.h \
+ style.h \
undo.h \
- validation.h \
validation-combo.h \
+ validation.h \
value.h \
- workbook.h \
- workbook-priv.h \
+ wbc-gtk-impl.h \
+ wbc-gtk.h \
workbook-cmd-format.h \
- workbook-view.h \
- workbook-control.h \
workbook-control-priv.h \
- wbc-gtk.h \
- wbc-gtk-impl.h \
+ workbook-control.h \
+ workbook-priv.h \
+ workbook-view.h \
+ workbook.h \
xml-io-version.h \
- xml-sax.h \
- gnumeric-conf.h \
- print.h \
- print-cell.h
+ xml-sax.h
gnumeric_SOURCES = \
io-context-gtk.c \
diff --git a/src/sheet-diff.c b/src/sheet-diff.c
new file mode 100644
index 0000000..0b3e3e5
--- /dev/null
+++ b/src/sheet-diff.c
@@ -0,0 +1,542 @@
+/*
+ * sheet-diff.c: Code for comparing sheets.
+ *
+ * Copyright (C) 2018 Morten Welinder (terra gnome org)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+#include <gnumeric-config.h>
+#include "gnumeric.h"
+#include "sheet-diff.h"
+#include "sheet.h"
+#include "cell.h"
+#include "expr.h"
+#include "value.h"
+#include "sheet-style.h"
+#include "mstyle.h"
+#include "ranges.h"
+#include "expr-name.h"
+#include "workbook.h"
+#include "workbook-priv.h"
+#include <string.h>
+
+/* ------------------------------------------------------------------------- */
+
+static gboolean
+null_diff_start (G_GNUC_UNUSED GnmDiffState *state)
+{
+ return FALSE;
+}
+
+static void
+null_diff_end (G_GNUC_UNUSED GnmDiffState *state)
+{
+}
+
+static void
+null_sheet_start (G_GNUC_UNUSED GnmDiffState *state,
+ G_GNUC_UNUSED Sheet const *os,
+ G_GNUC_UNUSED Sheet const *ns)
+{
+}
+
+static void
+null_sheet_end (G_GNUC_UNUSED GnmDiffState *state)
+{
+}
+
+static void
+null_sheet_order_changed (G_GNUC_UNUSED GnmDiffState *state)
+{
+}
+
+static void
+null_sheet_attr_int_changed (G_GNUC_UNUSED GnmDiffState *state,
+ G_GNUC_UNUSED const char *name,
+ G_GNUC_UNUSED int o,
+ G_GNUC_UNUSED int n)
+{
+}
+
+static void
+null_colrow_changed (G_GNUC_UNUSED GnmDiffState *state,
+ G_GNUC_UNUSED ColRowInfo const *oc, G_GNUC_UNUSED ColRowInfo const *nc,
+ G_GNUC_UNUSED gboolean is_cols, G_GNUC_UNUSED int i)
+{
+}
+
+static void
+null_cell_changed (G_GNUC_UNUSED GnmDiffState *state,
+ G_GNUC_UNUSED GnmCell const *oc, GnmCell const *nc)
+{
+}
+
+static void
+null_style_changed (G_GNUC_UNUSED GnmDiffState *state,
+ G_GNUC_UNUSED GnmRange const *r,
+ G_GNUC_UNUSED GnmStyle const *os, G_GNUC_UNUSED GnmStyle const *ns)
+{
+}
+
+static void
+null_name_changed (G_GNUC_UNUSED GnmDiffState *state,
+ G_GNUC_UNUSED GnmNamedExpr const *on, G_GNUC_UNUSED GnmNamedExpr const *nn)
+{
+
+}
+
+#define DISPATCH(method) (istate->actions->method ? istate->actions->method : null_ ## method)
+
+/* ------------------------------------------------------------------------- */
+
+typedef struct {
+ GnmDiffState *ustate;
+
+ const GnmDiffActions *actions;
+ gboolean diff_found;
+ gboolean error;
+
+ Sheet *old_sheet, *new_sheet;
+ GnmRange common_range;
+
+ Workbook *old_wb, *new_wb;
+} GnmDiffIState;
+
+/* ------------------------------------------------------------------------- */
+
+static gboolean
+compare_texpr_equal (GnmExprTop const *oe, GnmParsePos const *opp,
+ GnmExprTop const *ne, GnmParsePos const *npp,
+ GnmConventions const *convs)
+{
+ char *so, *sn;
+ gboolean eq;
+
+ if (gnm_expr_top_equal (oe, ne))
+ return TRUE;
+
+ // Not equal, but with references to sheets, that is not
+ // necessary. Compare as strings.
+
+ so = gnm_expr_top_as_string (oe, opp, convs);
+ sn = gnm_expr_top_as_string (ne, npp, convs);
+
+ eq = g_strcmp0 (so, sn) == 0;
+
+ g_free (so);
+ g_free (sn);
+
+ return eq;
+}
+
+static gboolean
+compare_corresponding_cells (GnmCell const *co, GnmCell const *cn)
+{
+ gboolean has_expr = gnm_cell_has_expr (co);
+ gboolean has_value = co->value != NULL;
+
+ if (has_expr != gnm_cell_has_expr (cn))
+ return TRUE;
+ if (has_expr) {
+ GnmParsePos opp, npp;
+ parse_pos_init_cell (&opp, co);
+ parse_pos_init_cell (&npp, cn);
+ return !compare_texpr_equal (co->base.texpr, &opp,
+ cn->base.texpr, &npp,
+ sheet_get_conventions (cn->base.sheet));
+ }
+
+ if (has_value != (cn->value != NULL))
+ return TRUE;
+ if (has_value)
+ return !(value_equal (co->value, cn->value) &&
+ go_format_eq (VALUE_FMT (co->value),
+ VALUE_FMT (cn->value)));
+
+
+ return FALSE;
+}
+
+static gboolean
+ignore_cell (GnmCell const *cell)
+{
+ if (cell) {
+ if (gnm_cell_has_expr (cell)) {
+ return gnm_expr_top_is_array_elem (cell->base.texpr,
+ NULL, NULL);
+ } else {
+ return VALUE_IS_EMPTY (cell->value);
+ }
+ }
+ return FALSE;
+}
+
+static void
+diff_sheets_cells (GnmDiffIState *istate)
+{
+ GPtrArray *old_cells = sheet_cells (istate->old_sheet, NULL);
+ GPtrArray *new_cells = sheet_cells (istate->new_sheet, NULL);
+ size_t io = 0, in = 0;
+
+ // Make code below simpler.
+ g_ptr_array_add (old_cells, NULL);
+ g_ptr_array_add (new_cells, NULL);
+
+ while (TRUE) {
+ GnmCell const *co, *cn;
+
+ while (ignore_cell ((co = g_ptr_array_index (old_cells, io))))
+ io++;
+
+ while (ignore_cell ((cn = g_ptr_array_index (new_cells, in))))
+ in++;
+
+ if (co && cn) {
+ int order = co->pos.row == cn->pos.row
+ ? co->pos.col - cn->pos.col
+ : co->pos.row - cn->pos.row;
+ if (order < 0)
+ cn = NULL;
+ else if (order > 0)
+ co = NULL;
+ else {
+ if (compare_corresponding_cells (co, cn)) {
+ istate->diff_found = TRUE;
+ DISPATCH(cell_changed) (istate->ustate, co, cn);
+ }
+ io++, in++;
+ continue;
+ }
+ }
+
+ if (co) {
+ istate->diff_found = TRUE;
+ DISPATCH(cell_changed) (istate->ustate, co, NULL);
+ io++;
+ } else if (cn) {
+ istate->diff_found = TRUE;
+ DISPATCH(cell_changed) (istate->ustate, NULL, cn);
+ in++;
+ } else
+ break;
+ }
+
+ g_ptr_array_free (old_cells, TRUE);
+ g_ptr_array_free (new_cells, TRUE);
+}
+
+static void
+diff_sheets_colrow (GnmDiffIState *istate, gboolean is_cols)
+{
+ ColRowInfo const *old_def =
+ sheet_colrow_get_default (istate->old_sheet, is_cols);
+ ColRowInfo const *new_def =
+ sheet_colrow_get_default (istate->new_sheet, is_cols);
+ int i, U;
+
+ if (!colrow_equal (old_def, new_def)) {
+ istate->diff_found = TRUE;
+ DISPATCH(colrow_changed) (istate->ustate, old_def, new_def, is_cols, -1);
+ }
+
+ U = is_cols
+ ? istate->common_range.end.col
+ : istate->common_range.end.row;
+ for (i = 0; i <= U; i++) {
+ ColRowInfo const *ocr =
+ sheet_colrow_get (istate->old_sheet, i, is_cols);
+ ColRowInfo const *ncr =
+ sheet_colrow_get (istate->new_sheet, i, is_cols);
+
+ if (ocr == ncr)
+ continue; // Considered equal, even if defaults are different
+ if (!ocr) ocr = old_def;
+ if (!ncr) ncr = new_def;
+ if (!colrow_equal (ocr, ncr)) {
+ istate->diff_found = TRUE;
+ DISPATCH(colrow_changed) (istate->ustate, ocr, ncr, is_cols, i);
+ }
+ }
+}
+
+#define DO_INT(field,attr) \
+ do { \
+ if (istate->old_sheet->field != istate->new_sheet->field) { \
+ istate->diff_found = TRUE; \
+ DISPATCH(sheet_attr_int_changed) \
+ (istate->ustate, attr, istate->old_sheet->field, istate->new_sheet->field); \
+ } \
+ } while (0)
+
+static void
+diff_sheets_attrs (GnmDiffIState *istate)
+{
+ GnmSheetSize const *os = gnm_sheet_get_size (istate->old_sheet);
+ GnmSheetSize const *ns = gnm_sheet_get_size (istate->new_sheet);
+
+ if (os->max_cols != ns->max_cols) {
+ istate->diff_found = TRUE;
+ DISPATCH(sheet_attr_int_changed)
+ (istate->ustate, "Cols", os->max_cols, ns->max_cols);
+ }
+ if (os->max_rows != ns->max_rows) {
+ istate->diff_found = TRUE;
+ DISPATCH(sheet_attr_int_changed)
+ (istate->ustate, "Rows", os->max_rows, ns->max_rows);
+ }
+
+ DO_INT (display_formulas, "DisplayFormulas");
+ DO_INT (hide_zero, "HideZero");
+ DO_INT (hide_grid, "HideGrid");
+ DO_INT (hide_col_header, "HideColHeader");
+ DO_INT (hide_row_header, "HideRowHeader");
+ DO_INT (display_outlines, "DisplayOutlines");
+ DO_INT (outline_symbols_below, "OutlineSymbolsBelow");
+ DO_INT (outline_symbols_right, "OutlineSymbolsRight");
+ DO_INT (text_is_rtl, "RTL_Layout");
+ DO_INT (is_protected, "Protected");
+ DO_INT (visibility, "Visibility");
+}
+#undef DO_INT
+
+struct cb_diff_sheets_styles {
+ GnmDiffIState *istate;
+ GnmStyle *old_style;
+};
+
+static void
+cb_diff_sheets_styles_2 (G_GNUC_UNUSED gpointer key,
+ gpointer sr_, gpointer user_data)
+{
+ GnmStyleRegion *sr = sr_;
+ struct cb_diff_sheets_styles *data = user_data;
+ GnmDiffIState *istate = data->istate;
+ GnmRange r = sr->range;
+
+ if (gnm_style_find_differences (data->old_style, sr->style, TRUE) == 0)
+ return;
+
+ istate->diff_found = TRUE;
+
+ DISPATCH(style_changed) (istate->ustate, &r, data->old_style, sr->style);
+}
+
+static void
+cb_diff_sheets_styles_1 (G_GNUC_UNUSED gpointer key,
+ gpointer sr_, gpointer user_data)
+{
+ GnmStyleRegion *sr = sr_;
+ struct cb_diff_sheets_styles *data = user_data;
+ GnmDiffIState *istate = data->istate;
+
+ data->old_style = sr->style;
+ sheet_style_range_foreach (istate->new_sheet, &sr->range,
+ cb_diff_sheets_styles_2,
+ data);
+}
+
+static void
+diff_sheets_styles (GnmDiffIState *istate)
+{
+ struct cb_diff_sheets_styles data;
+
+ data.istate = istate;
+ sheet_style_range_foreach (istate->old_sheet, &istate->common_range,
+ cb_diff_sheets_styles_1,
+ &data);
+}
+
+static int
+cb_expr_name_by_name (GnmNamedExpr const *a, GnmNamedExpr const *b)
+{
+ return g_strcmp0 (expr_name_name (a), expr_name_name (b));
+}
+
+static void
+diff_names (GnmDiffIState *istate,
+ GnmNamedExprCollection const *onames, GnmNamedExprCollection const *nnames)
+{
+ GSList *old_names = gnm_named_expr_collection_list (onames);
+ GSList *new_names = gnm_named_expr_collection_list (nnames);
+ GSList *lo, *ln;
+ GnmConventions const *convs;
+
+ if (istate->new_sheet)
+ convs = sheet_get_conventions (istate->new_sheet);
+ else
+ // Hmm... It's not terribly important where we get them
+ convs = sheet_get_conventions (workbook_sheet_by_index (istate->new_wb, 0));
+
+ old_names = g_slist_sort (old_names, (GCompareFunc)cb_expr_name_by_name);
+ new_names = g_slist_sort (new_names, (GCompareFunc)cb_expr_name_by_name);
+
+ lo = old_names;
+ ln = new_names;
+ while (lo || ln) {
+ GnmNamedExpr const *on = lo ? lo->data : NULL;
+ GnmNamedExpr const *nn = ln ? ln->data : NULL;
+
+ if (!nn || (on && cb_expr_name_by_name (on, nn) < 0)) {
+ // Old name got removed
+ istate->diff_found = TRUE;
+ DISPATCH(name_changed) (istate->ustate, on, nn);
+ lo = lo->next;
+ continue;
+ }
+
+ if (!on || (nn && cb_expr_name_by_name (on, nn) > 0)) {
+ // New name got added
+ istate->diff_found = TRUE;
+ DISPATCH(name_changed) (istate->ustate, on, nn);
+ ln = ln->next;
+ continue;
+ }
+
+ if (!compare_texpr_equal (on->texpr, &on->pos,
+ nn->texpr, &nn->pos,
+ convs)) {
+ istate->diff_found = TRUE;
+ DISPATCH(name_changed) (istate->ustate, on, nn);
+ }
+
+ lo = lo->next;
+ ln = ln->next;
+ }
+
+ g_slist_free (old_names);
+ g_slist_free (new_names);
+}
+
+static void
+real_diff_sheets (GnmDiffIState *istate, Sheet *old_sheet, Sheet *new_sheet)
+{
+ GnmRange or, nr;
+
+ istate->old_sheet = old_sheet;
+ istate->new_sheet = new_sheet;
+
+ range_init_full_sheet (&or, old_sheet);
+ range_init_full_sheet (&nr, new_sheet);
+ range_intersection (&istate->common_range, &or, &nr);
+
+ diff_sheets_attrs (istate);
+ diff_names (istate, istate->old_sheet->names, istate->new_sheet->names);
+ diff_sheets_colrow (istate, TRUE);
+ diff_sheets_colrow (istate, FALSE);
+ diff_sheets_cells (istate);
+ diff_sheets_styles (istate);
+
+ istate->old_sheet = istate->new_sheet = NULL;
+}
+
+gboolean
+gnm_diff_sheets (const GnmDiffActions *actions, GnmDiffState *state,
+ Sheet *old_sheet, Sheet *new_sheet)
+{
+ GnmDiffIState istate;
+
+ memset (&istate, 0, sizeof (istate));
+ istate.ustate = state;
+ istate.actions = actions;
+ istate.diff_found = FALSE;
+ istate.error = FALSE;
+
+ real_diff_sheets (&istate, old_sheet, new_sheet);
+
+ return istate.diff_found;
+}
+
+static void
+real_diff_workbooks (GnmDiffIState *istate,
+ Workbook *old_wb, Workbook *new_wb)
+{
+ int last_index = -1;
+ int i, count;
+ gboolean sheet_order_changed = FALSE;
+
+ istate->old_wb = old_wb;
+ istate->new_wb = new_wb;
+
+ if (DISPATCH(diff_start) (istate->ustate)) {
+ istate->error = TRUE;
+ return;
+ }
+
+ diff_names (istate, old_wb->names, new_wb->names);
+
+ // This doesn't handle sheet renames very well, but simply considers
+ // that a sheet deletion and a sheet insert.
+ count = workbook_sheet_count (old_wb);
+ for (i = 0; i < count; i++) {
+ Sheet *old_sheet = workbook_sheet_by_index (old_wb, i);
+ Sheet *new_sheet = workbook_sheet_by_name (new_wb,
+ old_sheet->name_unquoted);
+ DISPATCH(sheet_start) (istate->ustate, old_sheet, new_sheet);
+
+ if (new_sheet) {
+ if (new_sheet->index_in_wb < last_index)
+ sheet_order_changed = TRUE;
+ last_index = new_sheet->index_in_wb;
+
+ real_diff_sheets (istate, old_sheet, new_sheet);
+ } else
+ istate->diff_found = TRUE;
+
+ DISPATCH(sheet_end) (istate->ustate);
+ }
+
+ count = workbook_sheet_count (new_wb);
+ for (i = 0; i < count; i++) {
+ Sheet *new_sheet = workbook_sheet_by_index (new_wb, i);
+ Sheet *old_sheet = workbook_sheet_by_name (old_wb,
+ new_sheet->name_unquoted);
+ if (old_sheet)
+ ; // Nothing -- already done above.
+ else {
+ istate->diff_found = TRUE;
+ DISPATCH(sheet_start) (istate->ustate, old_sheet, new_sheet);
+ DISPATCH(sheet_end) (istate->ustate);
+ }
+ }
+
+ if (sheet_order_changed) {
+ istate->diff_found = TRUE;
+ DISPATCH(sheet_order_changed) (istate->ustate);
+ }
+
+ DISPATCH(diff_end) (istate->ustate);
+}
+
+int
+gnm_diff_workbooks (const GnmDiffActions *actions, GnmDiffState *state,
+ Workbook *old_wb, Workbook *new_wb)
+{
+ GnmDiffIState istate;
+
+ memset (&istate, 0, sizeof (istate));
+ istate.ustate = state;
+ istate.actions = actions;
+ istate.diff_found = FALSE;
+ istate.error = FALSE;
+
+ real_diff_workbooks (&istate, old_wb, new_wb);
+
+ return istate.error
+ ? 2
+ : (istate.diff_found
+ ? 1
+ : 0);
+}
diff --git a/src/sheet-diff.h b/src/sheet-diff.h
new file mode 100644
index 0000000..726accf
--- /dev/null
+++ b/src/sheet-diff.h
@@ -0,0 +1,72 @@
+#ifndef GNM_SHEET_DIFF_H
+#define GNM_SHEET_DIFF_H
+
+#include "gnumeric.h"
+
+G_BEGIN_DECLS
+
+typedef struct GnmDiffState_ GnmDiffState;
+
+typedef struct {
+ // Start comparison of two workbooks.
+ gboolean (*diff_start) (GnmDiffState *state);
+
+ // Finish comparison started with above.
+ void (*diff_end) (GnmDiffState *state);
+
+ // Clean up allocations
+ // This is not actually called by code here
+ void (*dtor) (GnmDiffState *state);
+
+ /* ------------------------------ */
+
+ // Start looking at a sheet. Either sheet might be NULL.
+ void (*sheet_start) (GnmDiffState *state,
+ Sheet const *os, Sheet const *ns);
+
+ // Finish sheet started with above.
+ void (*sheet_end) (GnmDiffState *state);
+
+ // The order of sheets has changed.
+ void (*sheet_order_changed) (GnmDiffState *state);
+
+ // An integer attribute of the sheet has changed.
+ void (*sheet_attr_int_changed) (GnmDiffState *state, const char *name,
+ int o, int n);
+
+ /* ------------------------------ */
+
+ // Column or Row information changed
+ void (*colrow_changed) (GnmDiffState *state,
+ ColRowInfo const *oc, ColRowInfo const *nc,
+ gboolean is_cols, int i);
+
+ /* ------------------------------ */
+
+ // A cell was changed/added/removed.
+ void (*cell_changed) (GnmDiffState *state,
+ GnmCell const *oc, GnmCell const *nc);
+
+ /* ------------------------------ */
+
+ // The style of an area was changed.
+ void (*style_changed) (GnmDiffState *state, GnmRange const *r,
+ GnmStyle const *os, GnmStyle const *ns);
+
+ /* ------------------------------ */
+
+ // A defined name was changed
+ void (*name_changed) (GnmDiffState *state,
+ GnmNamedExpr const *on, GnmNamedExpr const *nn);
+} GnmDiffActions;
+
+
+gboolean gnm_diff_sheets (const GnmDiffActions *actions, GnmDiffState *state,
+ Sheet *old_sheet, Sheet *new_sheet);
+
+int gnm_diff_workbooks (const GnmDiffActions *actions, GnmDiffState *state,
+ Workbook *old_wb, Workbook *new_wb);
+
+G_END_DECLS
+
+#endif /* GNM_SHEET_DIFF_H */
diff --git a/src/ssdiff.c b/src/ssdiff.c
index b6cb81e..2205fd0 100644
--- a/src/ssdiff.c
+++ b/src/ssdiff.c
@@ -31,7 +31,7 @@
#include "hlink.h"
#include "input-msg.h"
#include "expr-name.h"
-#include "workbook-priv.h"
+#include "sheet-diff.h"
#include <gsf/gsf-libxml.h>
#include <gsf/gsf-output-stdio.h>
#include <gsf/gsf-input.h>
@@ -80,60 +80,6 @@ static const GOptionEntry ssdiff_options [] = {
/* -------------------------------------------------------------------------- */
-typedef struct GnmDiffState_ GnmDiffState;
-
-typedef struct {
- // Start comparison of two workbooks.
- gboolean (*diff_start) (GnmDiffState *state);
-
- // Finish comparison started with above.
- void (*diff_end) (GnmDiffState *state);
-
- // Clean up allocations
- void (*dtor) (GnmDiffState *state);
-
- /* ------------------------------ */
-
- // Start looking at a sheet. Either sheet might be NULL.
- void (*sheet_start) (GnmDiffState *state,
- Sheet const *os, Sheet const *ns);
-
- // Finish sheet started with above.
- void (*sheet_end) (GnmDiffState *state);
-
- // The order of sheets has changed.
- void (*sheet_order_changed) (GnmDiffState *state);
-
- // An integer attribute of the sheet has changed.
- void (*sheet_attr_int_changed) (GnmDiffState *state, const char *name,
- int o, int n);
-
- /* ------------------------------ */
-
- // Column or Row information changed
- void (*colrow_changed) (GnmDiffState *state,
- ColRowInfo const *oc, ColRowInfo const *nc,
- gboolean is_cols, int i);
-
- /* ------------------------------ */
-
- // A cell was changed/added/removed.
- void (*cell_changed) (GnmDiffState *state,
- GnmCell const *oc, GnmCell const *nc);
-
- /* ------------------------------ */
-
- // The style of an area was changed.
- void (*style_changed) (GnmDiffState *state, GnmRange const *r,
- GnmStyle const *os, GnmStyle const *ns);
-
- /* ------------------------------ */
-
- // A defined name was changed
- void (*name_changed) (GnmDiffState *state,
- GnmNamedExpr const *on, GnmNamedExpr const *nn);
-} GnmDiffActions;
-
typedef struct {
char *url;
GsfInput *input;
@@ -145,81 +91,20 @@ struct GnmDiffState_ {
GOIOContext *ioc;
GnmDiffStateFile old, new;
- const GnmDiffActions *actions;
-
- gboolean diff_found;
-
GsfOutput *output;
- // Valid when comparing sheets
- Sheet *old_sheet, *new_sheet;
- GnmRange common_range;
-
// The following for xml mode.
GsfXMLOut *xml;
const char *xml_section;
GnmConventions *xml_convs;
// The following for highlight mode.
+ Sheet *highlight_sheet;
GnmDiffStateFile highlight;
GOFileSaver const *highlight_fs;
GnmStyle *highlight_style;
};
-static gboolean
-null_diff_start (G_GNUC_UNUSED GnmDiffState *state)
-{
- return FALSE;
-}
-
-static void
-null_diff_end (G_GNUC_UNUSED GnmDiffState *state)
-{
-}
-
-static void
-null_dtor (G_GNUC_UNUSED GnmDiffState *state)
-{
-}
-
-static void
-null_sheet_start (G_GNUC_UNUSED GnmDiffState *state,
- G_GNUC_UNUSED Sheet const *os,
- G_GNUC_UNUSED Sheet const *ns)
-{
-}
-
-static void
-null_sheet_end (G_GNUC_UNUSED GnmDiffState *state)
-{
-}
-
-static void
-null_sheet_order_changed (G_GNUC_UNUSED GnmDiffState *state)
-{
-}
-
-static void
-null_sheet_attr_int_changed (G_GNUC_UNUSED GnmDiffState *state,
- G_GNUC_UNUSED const char *name,
- G_GNUC_UNUSED int o,
- G_GNUC_UNUSED int n)
-{
-}
-
-static void
-null_colrow_changed (G_GNUC_UNUSED GnmDiffState *state,
- G_GNUC_UNUSED ColRowInfo const *oc, G_GNUC_UNUSED ColRowInfo const *nc,
- G_GNUC_UNUSED gboolean is_cols, G_GNUC_UNUSED int i)
-{
-}
-
-static void
-null_name_changed (G_GNUC_UNUSED GnmDiffState *state,
- G_GNUC_UNUSED GnmNamedExpr const *on, G_GNUC_UNUSED GnmNamedExpr const *nn)
-{
-}
-
/* -------------------------------------------------------------------------- */
static gboolean
@@ -353,17 +238,13 @@ def_name_changed (GnmDiffState *state,
}
static const GnmDiffActions default_actions = {
- null_diff_start,
- null_diff_end,
- null_dtor,
- def_sheet_start,
- null_sheet_end,
- def_sheet_order_changed,
- def_sheet_attr_int_changed,
- def_colrow_changed,
- def_cell_changed,
- def_style_changed,
- def_name_changed,
+ .sheet_start = def_sheet_start,
+ .sheet_order_changed = def_sheet_order_changed,
+ .sheet_attr_int_changed = def_sheet_attr_int_changed,
+ .colrow_changed = def_colrow_changed,
+ .cell_changed = def_cell_changed,
+ .style_changed = def_style_changed,
+ .name_changed = def_name_changed,
};
/* -------------------------------------------------------------------------- */
@@ -846,17 +727,16 @@ xml_name_changed (GnmDiffState *state,
}
static const GnmDiffActions xml_actions = {
- xml_diff_start,
- xml_diff_end,
- xml_dtor,
- xml_sheet_start,
- xml_sheet_end,
- null_sheet_order_changed,
- xml_sheet_attr_int_changed,
- xml_colrow_changed,
- xml_cell_changed,
- xml_style_changed,
- xml_name_changed,
+ .diff_start = xml_diff_start,
+ .diff_end = xml_diff_end,
+ .dtor = xml_dtor,
+ .sheet_start = xml_sheet_start,
+ .sheet_end = xml_sheet_end,
+ .sheet_attr_int_changed = xml_sheet_attr_int_changed,
+ .colrow_changed = xml_colrow_changed,
+ .cell_changed = xml_cell_changed,
+ .style_changed = xml_style_changed,
+ .name_changed = xml_name_changed,
};
/* -------------------------------------------------------------------------- */
@@ -908,11 +788,26 @@ highlight_dtor (GnmDiffState *state)
}
static void
-highlight_apply (GnmDiffState *state, const GnmRange *r)
+highlight_sheet_start (GnmDiffState *state,
+ G_GNUC_UNUSED Sheet const *os, Sheet const *ns)
{
// We want the highlight sheet corresponding to new_sheet.
- Sheet *sheet = workbook_sheet_by_index (state->highlight.wb,
- state->new_sheet->index_in_wb);
+ state->highlight_sheet = ns
+ ? workbook_sheet_by_index (state->highlight.wb, ns->index_in_wb)
+ : NULL;
+}
+
+static void
+highlight_sheet_end (GnmDiffState *state)
+{
+ state->highlight_sheet = NULL;
+}
+
+static void
+highlight_apply (GnmDiffState *state, const GnmRange *r)
+{
+ Sheet *sheet = state->highlight_sheet;
+
g_return_if_fail (IS_SHEET (sheet));
gnm_style_ref (state->highlight_style);
@@ -937,347 +832,17 @@ highlight_style_changed (GnmDiffState *state, GnmRange const *r,
static const GnmDiffActions highlight_actions = {
- highlight_diff_start,
- highlight_diff_end,
- highlight_dtor,
- null_sheet_start,
- null_sheet_end,
- null_sheet_order_changed,
- null_sheet_attr_int_changed,
- null_colrow_changed,
- highlight_cell_changed,
- highlight_style_changed,
- null_name_changed,
+ .diff_start = highlight_diff_start,
+ .diff_end = highlight_diff_end,
+ .dtor = highlight_dtor,
+ .sheet_start = highlight_sheet_start,
+ .sheet_end = highlight_sheet_end,
+ .cell_changed = highlight_cell_changed,
+ .style_changed = highlight_style_changed,
};
/* -------------------------------------------------------------------------- */
-static gboolean
-compare_texpr_equal (GnmExprTop const *oe, GnmParsePos const *opp,
- GnmExprTop const *ne, GnmParsePos const *npp,
- GnmConventions const *convs)
-{
- char *so, *sn;
- gboolean eq;
-
- if (gnm_expr_top_equal (oe, ne))
- return TRUE;
-
- // Not equal, but with references to sheets, that is not
- // necessary. Compare as strings.
-
- so = gnm_expr_top_as_string (oe, opp, convs);
- sn = gnm_expr_top_as_string (ne, npp, convs);
-
- eq = g_strcmp0 (so, sn) == 0;
-
- g_free (so);
- g_free (sn);
-
- return eq;
-}
-
-static gboolean
-compare_corresponding_cells (GnmCell const *co, GnmCell const *cn)
-{
- gboolean has_expr = gnm_cell_has_expr (co);
- gboolean has_value = co->value != NULL;
-
- if (has_expr != gnm_cell_has_expr (cn))
- return TRUE;
- if (has_expr) {
- GnmParsePos opp, npp;
- parse_pos_init_cell (&opp, co);
- parse_pos_init_cell (&npp, cn);
- return !compare_texpr_equal (co->base.texpr, &opp,
- cn->base.texpr, &npp,
- sheet_get_conventions (cn->base.sheet));
- }
-
- if (has_value != (cn->value != NULL))
- return TRUE;
- if (has_value)
- return !(value_equal (co->value, cn->value) &&
- go_format_eq (VALUE_FMT (co->value),
- VALUE_FMT (cn->value)));
-
-
- return FALSE;
-}
-
-static gboolean
-ignore_cell (GnmCell const *cell)
-{
- if (cell) {
- if (gnm_cell_has_expr (cell)) {
- return gnm_expr_top_is_array_elem (cell->base.texpr,
- NULL, NULL);
- } else {
- return VALUE_IS_EMPTY (cell->value);
- }
- }
- return FALSE;
-}
-
-static void
-diff_sheets_cells (GnmDiffState *state)
-{
- GPtrArray *old_cells = sheet_cells (state->old_sheet, NULL);
- GPtrArray *new_cells = sheet_cells (state->new_sheet, NULL);
- size_t io = 0, in = 0;
-
- // Make code below simpler.
- g_ptr_array_add (old_cells, NULL);
- g_ptr_array_add (new_cells, NULL);
-
- while (TRUE) {
- GnmCell const *co, *cn;
-
- while (ignore_cell ((co = g_ptr_array_index (old_cells, io))))
- io++;
-
- while (ignore_cell ((cn = g_ptr_array_index (new_cells, in))))
- in++;
-
- if (co && cn) {
- int order = co->pos.row == cn->pos.row
- ? co->pos.col - cn->pos.col
- : co->pos.row - cn->pos.row;
- if (order < 0)
- cn = NULL;
- else if (order > 0)
- co = NULL;
- else {
- if (compare_corresponding_cells (co, cn)) {
- state->diff_found = TRUE;
- state->actions->cell_changed (state, co, cn);
- }
- io++, in++;
- continue;
- }
- }
-
- if (co) {
- state->diff_found = TRUE;
- state->actions->cell_changed (state, co, NULL);
- io++;
- } else if (cn) {
- state->diff_found = TRUE;
- state->actions->cell_changed (state, NULL, cn);
- in++;
- } else
- break;
- }
-
- g_ptr_array_free (old_cells, TRUE);
- g_ptr_array_free (new_cells, TRUE);
-}
-
-static void
-diff_sheets_colrow (GnmDiffState *state, gboolean is_cols)
-{
- ColRowInfo const *old_def =
- sheet_colrow_get_default (state->old_sheet, is_cols);
- ColRowInfo const *new_def =
- sheet_colrow_get_default (state->new_sheet, is_cols);
- int i, U;
-
- if (!colrow_equal (old_def, new_def)) {
- state->diff_found = TRUE;
- state->actions->colrow_changed (state, old_def, new_def, is_cols, -1);
- }
-
- U = is_cols
- ? state->common_range.end.col
- : state->common_range.end.row;
- for (i = 0; i <= U; i++) {
- ColRowInfo const *ocr =
- sheet_colrow_get (state->old_sheet, i, is_cols);
- ColRowInfo const *ncr =
- sheet_colrow_get (state->new_sheet, i, is_cols);
-
- if (ocr == ncr)
- continue; // Considered equal, even if defaults are different
- if (!ocr) ocr = old_def;
- if (!ncr) ncr = new_def;
- if (!colrow_equal (ocr, ncr)) {
- state->diff_found = TRUE;
- state->actions->colrow_changed (state, ocr, ncr, is_cols, i);
- }
- }
-}
-
-#define DO_INT(field,attr) \
- do { \
- if (state->old_sheet->field != state->new_sheet->field) { \
- state->diff_found = TRUE; \
- state->actions->sheet_attr_int_changed \
- (state, attr, state->old_sheet->field, state->new_sheet->field); \
- } \
- } while (0)
-
-static void
-diff_sheets_attrs (GnmDiffState *state)
-{
- GnmSheetSize const *os = gnm_sheet_get_size (state->old_sheet);
- GnmSheetSize const *ns = gnm_sheet_get_size (state->new_sheet);
-
- if (os->max_cols != ns->max_cols) {
- state->diff_found = TRUE;
- state->actions->sheet_attr_int_changed
- (state, "Cols", os->max_cols, ns->max_cols);
- }
- if (os->max_rows != ns->max_rows) {
- state->diff_found = TRUE;
- state->actions->sheet_attr_int_changed
- (state, "Rows", os->max_rows, ns->max_rows);
- }
-
- DO_INT (display_formulas, "DisplayFormulas");
- DO_INT (hide_zero, "HideZero");
- DO_INT (hide_grid, "HideGrid");
- DO_INT (hide_col_header, "HideColHeader");
- DO_INT (hide_row_header, "HideRowHeader");
- DO_INT (display_outlines, "DisplayOutlines");
- DO_INT (outline_symbols_below, "OutlineSymbolsBelow");
- DO_INT (outline_symbols_right, "OutlineSymbolsRight");
- DO_INT (text_is_rtl, "RTL_Layout");
- DO_INT (is_protected, "Protected");
- DO_INT (visibility, "Visibility");
-}
-#undef DO_INT
-
-struct cb_diff_sheets_styles {
- GnmDiffState *state;
- GnmStyle *old_style;
-};
-
-static void
-cb_diff_sheets_styles_2 (G_GNUC_UNUSED gpointer key,
- gpointer sr_, gpointer user_data)
-{
- GnmStyleRegion *sr = sr_;
- struct cb_diff_sheets_styles *data = user_data;
- GnmDiffState *state = data->state;
- GnmRange r = sr->range;
-
- if (gnm_style_find_differences (data->old_style, sr->style, TRUE) == 0)
- return;
-
- state->diff_found = TRUE;
-
- state->actions->style_changed (state, &r, data->old_style, sr->style);
-}
-
-static void
-cb_diff_sheets_styles_1 (G_GNUC_UNUSED gpointer key,
- gpointer sr_, gpointer user_data)
-{
- GnmStyleRegion *sr = sr_;
- struct cb_diff_sheets_styles *data = user_data;
- GnmDiffState *state = data->state;
-
- data->old_style = sr->style;
- sheet_style_range_foreach (state->new_sheet, &sr->range,
- cb_diff_sheets_styles_2,
- data);
-}
-
-static void
-diff_sheets_styles (GnmDiffState *state)
-{
- struct cb_diff_sheets_styles data;
-
- data.state = state;
- sheet_style_range_foreach (state->old_sheet, &state->common_range,
- cb_diff_sheets_styles_1,
- &data);
-}
-
-static int
-cb_expr_name_by_name (GnmNamedExpr const *a, GnmNamedExpr const *b)
-{
- return g_strcmp0 (expr_name_name (a), expr_name_name (b));
-}
-
-static void
-diff_names (GnmDiffState *state,
- GnmNamedExprCollection const *onames, GnmNamedExprCollection const *nnames)
-{
- GSList *old_names = gnm_named_expr_collection_list (onames);
- GSList *new_names = gnm_named_expr_collection_list (nnames);
- GSList *lo, *ln;
- GnmConventions const *convs;
-
- if (state->new_sheet)
- convs = sheet_get_conventions (state->new_sheet);
- else
- // Hmm... It's not terribly important where we get them
- convs = sheet_get_conventions (workbook_sheet_by_index (state->new.wb, 0));
-
- old_names = g_slist_sort (old_names, (GCompareFunc)cb_expr_name_by_name);
- new_names = g_slist_sort (new_names, (GCompareFunc)cb_expr_name_by_name);
-
- lo = old_names;
- ln = new_names;
- while (lo || ln) {
- GnmNamedExpr const *on = lo ? lo->data : NULL;
- GnmNamedExpr const *nn = ln ? ln->data : NULL;
-
- if (!nn || (on && cb_expr_name_by_name (on, nn) < 0)) {
- // Old name got removed
- state->diff_found = TRUE;
- state->actions->name_changed (state, on, nn);
- lo = lo->next;
- continue;
- }
-
- if (!on || (nn && cb_expr_name_by_name (on, nn) > 0)) {
- // New name got added
- state->diff_found = TRUE;
- state->actions->name_changed (state, on, nn);
- ln = ln->next;
- continue;
- }
-
- if (!compare_texpr_equal (on->texpr, &on->pos,
- nn->texpr, &nn->pos,
- convs)) {
- state->diff_found = TRUE;
- state->actions->name_changed (state, on, nn);
- }
-
- lo = lo->next;
- ln = ln->next;
- }
-
- g_slist_free (old_names);
- g_slist_free (new_names);
-}
-
-
-static void
-diff_sheets (GnmDiffState *state, Sheet *old_sheet, Sheet *new_sheet)
-{
- GnmRange or, nr;
-
- state->old_sheet = old_sheet;
- state->new_sheet = new_sheet;
-
- range_init_full_sheet (&or, old_sheet);
- range_init_full_sheet (&nr, new_sheet);
- range_intersection (&state->common_range, &or, &nr);
-
- diff_sheets_attrs (state);
- diff_names (state, state->old_sheet->names, state->new_sheet->names);
- diff_sheets_colrow (state, TRUE);
- diff_sheets_colrow (state, FALSE);
- diff_sheets_cells (state);
- diff_sheets_styles (state);
-
- state->old_sheet = state->new_sheet = NULL;
-}
-
static int
diff (char const *oldfilename, char const *newfilename,
GOIOContext *ioc,
@@ -1285,15 +850,11 @@ diff (char const *oldfilename, char const *newfilename,
{
GnmDiffState state;
int res = 0;
- int i, count;
- gboolean sheet_order_changed = FALSE;
- int last_index = -1;
GnmLocale *locale;
locale = gnm_push_C_locale ();
memset (&state, 0, sizeof (state));
- state.actions = actions;
state.ioc = ioc;
state.output = output;
@@ -1304,63 +865,15 @@ diff (char const *oldfilename, char const *newfilename,
/* ---------------------------------------- */
- if (state.actions->diff_start (&state))
- goto error;
-
- diff_names (&state, state.old.wb->names, state.new.wb->names);
-
- // This doesn't handle sheet renames very well, but simply considers
- // that a sheet deletion and a sheet insert.
- count = workbook_sheet_count (state.old.wb);
- for (i = 0; i < count; i++) {
- Sheet *old_sheet = workbook_sheet_by_index (state.old.wb, i);
- Sheet *new_sheet = workbook_sheet_by_name (state.new.wb,
- old_sheet->name_unquoted);
- state.actions->sheet_start (&state, old_sheet, new_sheet);
-
- if (new_sheet) {
- if (new_sheet->index_in_wb < last_index)
- sheet_order_changed = TRUE;
- last_index = new_sheet->index_in_wb;
-
- diff_sheets (&state, old_sheet, new_sheet);
- } else
- state.diff_found = TRUE;
-
- state.actions->sheet_end (&state);
- }
-
- count = workbook_sheet_count (state.new.wb);
- for (i = 0; i < count; i++) {
- Sheet *new_sheet = workbook_sheet_by_index (state.new.wb, i);
- Sheet *old_sheet = workbook_sheet_by_name (state.old.wb,
- new_sheet->name_unquoted);
- if (old_sheet)
- ; // Nothing -- already done above.
- else {
- state.diff_found = TRUE;
- state.actions->sheet_start (&state, old_sheet, new_sheet);
- state.actions->sheet_end (&state);
- }
- }
-
- if (sheet_order_changed) {
- state.diff_found = TRUE;
- state.actions->sheet_order_changed (&state);
- }
-
- state.actions->diff_end (&state);
+ res = gnm_diff_workbooks (actions, &state, state.old.wb, state.new.wb);
out:
clear_file_state (&state.old);
clear_file_state (&state.new);
- state.actions->dtor (&state);
+ actions->dtor (&state);
gnm_pop_C_locale (locale);
- if (res == 0)
- res = state.diff_found ? 1 : 0;
-
return res;
error:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]