[gnumeric] ssdiff: add --xml option.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] ssdiff: add --xml option.
- Date: Mon, 24 Dec 2012 22:13:34 +0000 (UTC)
commit 137ecaff9c601f5f258027f176e00b0cf4454262
Author: Morten Welinder <terra gnome org>
Date: Mon Dec 24 17:12:51 2012 -0500
ssdiff: add --xml option.
The format is subject to change, but this introduces xml output format.
ChangeLog | 1 +
doc/C/ssdiff.1 | 5 ++
src/ssdiff.c | 162 +++++++++++++++++++++++++++++++++++++++++++++++++-------
3 files changed, 148 insertions(+), 20 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 7be0f11..da14001 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,7 @@
* src/ssdiff.c (def_cell_changed): Merge cell_added and
cell_removed handlers into the cell_changed handler.
+ (main): Add --xml option.
* configure.in: ssconvert, ssindex, and ssgrep are no longer
configurable. We need ssconvert for the test and it's silly
diff --git a/doc/C/ssdiff.1 b/doc/C/ssdiff.1
index 4f52634..95f8ab8 100644
--- a/doc/C/ssdiff.1
+++ b/doc/C/ssdiff.1
@@ -22,6 +22,11 @@ This program follows the usual GNU command line syntax, with single
letter options starting with a single dash (`-') and longer options
starting with two dashes (`--').
+.SS "Output options"
+.TP
+.B \-x, \-\-xml
+Display differences in xml format
+
.SS "Help options"
.TP
.B \-V, \-\-version
diff --git a/src/ssdiff.c b/src/ssdiff.c
index 76bc3fb..57d1397 100644
--- a/src/ssdiff.c
+++ b/src/ssdiff.c
@@ -21,8 +21,14 @@
#include "sheet.h"
#include "cell.h"
#include "value.h"
+#include <gsf/gsf-libxml.h>
+#include <gsf/gsf-output-stdio.h>
+
+/* FIXME: Namespace? */
+#define DIFF "ssdiff:"
static gboolean ssdiff_show_version = FALSE;
+static gboolean ssdiff_xml = FALSE;
static const GOptionEntry ssdiff_options [] = {
{
@@ -32,6 +38,13 @@ static const GOptionEntry ssdiff_options [] = {
NULL
},
+ {
+ "xml", 'x',
+ 0, G_OPTION_ARG_NONE, &ssdiff_xml,
+ N_("Output in xml format"),
+ NULL
+ },
+
/* ---------------------------------------- */
{ NULL }
@@ -42,11 +55,12 @@ static const GOptionEntry ssdiff_options [] = {
typedef struct GnmDiffState_ GnmDiffState;
typedef struct {
- /* A sheet was removed. */
- void (*sheet_removed) (GnmDiffState *state, Sheet const *os);
+ /* Start looking at a sheet. Either sheet might be NULL. */
+ void (*sheet_start) (GnmDiffState *state,
+ Sheet const *os, Sheet const *ns);
- /* A sheet was added. */
- void (*sheet_added) (GnmDiffState *state, 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);
@@ -66,6 +80,11 @@ struct GnmDiffState_ {
} old, new;
const GnmDiffActions *actions;
+
+ GsfOutput *output;
+ GsfXMLOut *xml;
+
+ Sheet const *pending_sheet;
};
/* -------------------------------------------------------------------------- */
@@ -85,45 +104,120 @@ def_cell_name (GnmCell const *oc)
}
static void
-def_sheet_removed (GnmDiffState *state, Sheet const *os)
+def_sheet_start (GnmDiffState *state, Sheet const *os, Sheet const *ns)
{
- g_printerr (_("Sheet %s removed.\n"), os->name_quoted);
+ if (os && !ns)
+ gsf_output_printf (state->output, _("Sheet %s removed.\n"), os->name_quoted);
+ else if (!os && ns)
+ gsf_output_printf (state->output, _("Sheet %s added.\n"), ns->name_quoted);
}
static void
-def_sheet_added (GnmDiffState *state, Sheet const *ns)
+def_sheet_end (GnmDiffState *state)
{
- g_printerr (_("Sheet %s added.\n"), ns->name_quoted);
+ (void)state;
}
static void
def_sheet_order_changed (GnmDiffState *state)
{
- g_printerr (_("Sheet order changed.\n"));
+ gsf_output_printf (state->output, _("Sheet order changed.\n"));
}
static void
def_cell_changed (GnmDiffState *state, GnmCell const *oc, GnmCell const *nc)
{
if (oc && nc)
- g_printerr (_("Cell %s changed.\n"), def_cell_name (oc));
+ gsf_output_printf (state->output, _("Cell %s changed.\n"), def_cell_name (oc));
else if (oc)
- g_printerr (_("Cell %s removed.\n"), def_cell_name (oc));
+ gsf_output_printf (state->output, _("Cell %s removed.\n"), def_cell_name (oc));
else if (nc)
- g_printerr (_("Cell %s added.\n"), def_cell_name (nc));
+ gsf_output_printf (state->output, _("Cell %s added.\n"), def_cell_name (nc));
else
g_assert_not_reached ();
}
static const GnmDiffActions default_actions = {
- def_sheet_removed,
- def_sheet_added,
+ def_sheet_start,
+ def_sheet_end,
def_sheet_order_changed,
def_cell_changed
};
/* -------------------------------------------------------------------------- */
+static void
+xml_delayed_sheet_start (GnmDiffState *state)
+{
+ gsf_xml_out_start_element (state->xml, DIFF "Sheet");
+ gsf_xml_out_add_cstr (state->xml, "Name", state->pending_sheet->name_unquoted);
+ state->pending_sheet = NULL;
+}
+
+static void
+xml_sheet_start (GnmDiffState *state, Sheet const *os, Sheet const *ns)
+{
+ state->pending_sheet = os ? os : ns;
+ if (!(os && ns)) {
+ xml_delayed_sheet_start (state);
+ gsf_xml_out_add_int (state->xml, "Old", os != NULL);
+ gsf_xml_out_add_int (state->xml, "New", ns != NULL);
+ }
+}
+
+static void
+xml_sheet_end (GnmDiffState *state)
+{
+ if (state->pending_sheet == NULL)
+ gsf_xml_out_end_element (state->xml); /* </Sheet> */
+}
+
+static void
+xml_sheet_order_changed (GnmDiffState *state)
+{
+ gsf_xml_out_start_element (state->xml, DIFF "SheetOrder");
+ /* What signals that there was a change? */
+ gsf_xml_out_end_element (state->xml); /* </SheetOrder> */
+}
+
+static void
+xml_cell_changed (GnmDiffState *state, GnmCell const *oc, GnmCell const *nc)
+{
+ const GnmCellPos *pos;
+
+ if (state->pending_sheet)
+ xml_delayed_sheet_start (state);
+
+ gsf_xml_out_start_element (state->xml, DIFF "Cell");
+
+ pos = oc ? &oc->pos : &nc->pos;
+ gsf_xml_out_add_int (state->xml, "Row", pos->row);
+ gsf_xml_out_add_int (state->xml, "Col", pos->col);
+
+ if (oc) {
+ char *txt = gnm_cell_get_entered_text (oc);
+ gsf_xml_out_add_cstr (state->xml, "old", txt);
+ g_free (txt);
+ }
+
+ if (nc) {
+ char *txt = gnm_cell_get_entered_text (nc);
+ gsf_xml_out_add_cstr (state->xml, "new", txt);
+ g_free (txt);
+ }
+
+ gsf_xml_out_end_element (state->xml); /* </Cell> */
+}
+
+static const GnmDiffActions xml_actions = {
+ xml_sheet_start,
+ xml_sheet_end,
+ xml_sheet_order_changed,
+ xml_cell_changed
+};
+
+/* -------------------------------------------------------------------------- */
+
static gboolean
compare_corresponding_cells (GnmCell const *co, GnmCell const *cn)
{
@@ -210,7 +304,7 @@ diff_sheets (GnmDiffState *state, Sheet *old_sheet, Sheet *new_sheet)
static int
diff (char const *oldfilename, char const *newfilename,
GOIOContext *ioc,
- GnmDiffActions const *actions)
+ GnmDiffActions const *actions, GsfOutput *output)
{
GnmDiffState state;
int res = 0;
@@ -222,6 +316,10 @@ diff (char const *oldfilename, char const *newfilename,
state.actions = actions;
state.ioc = ioc;
+ state.output = output;
+ if (ssdiff_xml)
+ state.xml = gsf_xml_out_new (output);
+
state.old.url = go_shell_arg_to_uri (oldfilename);
state.new.url = go_shell_arg_to_uri (newfilename);
@@ -247,14 +345,17 @@ diff (char const *oldfilename, char const *newfilename,
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.actions->sheet_removed (&state, old_sheet);
+ }
+
+ state.actions->sheet_end (&state);
}
count = workbook_sheet_count (state.new.wb);
@@ -264,8 +365,10 @@ diff (char const *oldfilename, char const *newfilename,
new_sheet->name_unquoted);
if (old_sheet)
; /* Nothing -- already done above. */
- else
- state.actions->sheet_added (&state, new_sheet);
+ else {
+ state.actions->sheet_start (&state, NULL, new_sheet);
+ state.actions->sheet_end (&state);
+ }
}
if (sheet_order_changed)
@@ -278,6 +381,8 @@ out:
g_object_unref (state.old.wb);
if (state.new.wb)
g_object_unref (state.new.wb);
+ if (state.xml)
+ g_object_unref (state.xml);
return res;
error:
@@ -293,6 +398,8 @@ main (int argc, char const **argv)
GOCmdContext *cc;
GOptionContext *ocontext;
GError *error = NULL;
+ const GnmDiffActions *actions;
+ GsfOutput *output;
/* No code before here, we need to init threads */
argv = gnm_pre_parse_init (argc, argv);
@@ -316,6 +423,20 @@ main (int argc, char const **argv)
return 0;
}
+ output = gsf_output_stdio_new_FILE ("<stdout>", stdout, TRUE);
+ if (!output) {
+ /* Unlikely. */
+ g_printerr (_("%s: Failed to write to stdout.\n"),
+ g_get_prgname ());
+ return 1;
+ }
+
+ if (ssdiff_xml) {
+ actions = &xml_actions;
+ } else {
+ actions = &default_actions;
+ }
+
gnm_init ();
cc = cmd_context_stderr_new ();
@@ -330,7 +451,7 @@ main (int argc, char const **argv)
if (argc == 3) {
GOIOContext *ioc = go_io_context_new (cc);
- res = diff (argv[1], argv[2], ioc, &default_actions);
+ res = diff (argv[1], argv[2], ioc, actions, output);
g_object_unref (ioc);
} else {
g_printerr (_("Usage: %s [OPTION...] %s\n"),
@@ -341,6 +462,7 @@ main (int argc, char const **argv)
/* Release cached string. */
def_cell_name (NULL);
+ g_object_unref (output);
go_component_set_default_command_context (NULL);
g_object_unref (cc);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]