[libgsf] xml: fix indentation after non-pretty-printed section.



commit 9c9c021f867c03d2a889cdfe2616c4108053f976
Author: Morten Welinder <terra gnome org>
Date:   Thu Apr 9 13:12:21 2015 -0400

    xml: fix indentation after non-pretty-printed section.

 ChangeLog         |   10 ++++
 NEWS              |    1 +
 gsf/gsf-libxml.c  |   54 ++++++++++++++++++++---
 gsf/gsf-libxml.h  |    3 +
 tests/.gitignore  |    1 +
 tests/Makefile.am |    2 +-
 tests/test-xml.c  |  124 ++++++++++++++++++++++++++++++----------------------
 7 files changed, 134 insertions(+), 61 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index bab795f..5c12238 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2015-04-09  Morten Welinder  <terra gnome org>
+
+       * tests/test-xml.c: Add meaning code in here.
+
+       * gsf/gsf-libxml.c (gsf_xml_out_end_element): Only indent closing
+       tag if we're at the beginning of the line because we
+       pretty-printed the previous closing tag.
+       (gsf_xml_out_get_pretty_print, gsf_xml_out_set_pretty_print): New
+       convenience functions.
+
 2015-03-30  Morten Welinder  <terra gnome org>
 
        * gsf/gsf-libxml.c (gsf_xml_in_doc_add_nodes): Introduce new flag
diff --git a/NEWS b/NEWS
index aa21a8b..21e0ab3 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,7 @@ Morten:
        * Ensure floats roundtrip through our xml functions.
        * Improve handling of unknown xml tags.
        * xml parser improvements.
+       * xml pretty-printing improvements.
 
 --------------------------------------------------------------------------
 libgsf 1.14.32
diff --git a/gsf/gsf-libxml.c b/gsf/gsf-libxml.c
index 7e589bf..eb3fb0b 100644
--- a/gsf/gsf-libxml.c
+++ b/gsf/gsf-libxml.c
@@ -700,7 +700,7 @@ lookup_child (GsfXMLInInternal *state, int default_ns_id,
 }
 
 static void
-gsf_xml_dump_state (GsfXMLInInternal *state)
+gsf_xml_in_dump_state (GsfXMLInInternal *state)
 {
        GSList *ptr = state->pub.node_stack = g_slist_reverse (state->pub.node_stack);
        if (ptr != NULL)        /* skip toplevel catch all */
@@ -830,7 +830,7 @@ gsf_xml_in_start_element (GsfXMLInInternal *state, xmlChar const *name, xmlChar
                return;
 
        g_printerr ("Unexpected element '%s' in state : \n\t", name);
-       gsf_xml_dump_state (state);
+       gsf_xml_in_dump_state (state);
 }
 
 static void
@@ -1471,6 +1471,7 @@ enum {
 typedef enum {
        GSF_XML_OUT_NOCONTENT,
        GSF_XML_OUT_CHILD,
+       GSF_XML_OUT_CHILD_PRETTY,
        GSF_XML_OUT_CONTENT
 } GsfXMLOutState;
 
@@ -1614,7 +1615,7 @@ gsf_xml_out_new (GsfOutput *output)
  * @xout: #GsfXMLOut
  * @type: the document type declaration
  *
- * Store some optional some &lt;!DOCTYPE .. &gt; content
+ * Store some optional &lt;!DOCTYPE .. &gt; content
  **/
 void
 gsf_xml_out_set_doc_type (GsfXMLOut *xout, char const *type)
@@ -1624,6 +1625,44 @@ gsf_xml_out_set_doc_type (GsfXMLOut *xout, char const *type)
        priv->doc_type = g_strdup (type);
 }
 
+/**
+ * gsf_xml_out_get_pretty_print:
+ * @xout: #GsfXMLOut
+ *
+ * Returns: the current state of the pretty-print flag.  Note, that
+ * gsf_xml_out_set_pretty_print will return the same value.
+ **/
+gboolean
+gsf_xml_out_get_pretty_print (GsfXMLOut *xout)
+{
+       g_return_val_if_fail (GSF_IS_XML_OUT (xout), TRUE);
+       return xout->priv->pretty_print;
+}
+
+/**
+ * gsf_xml_out_set_pretty_print:
+ * @xout: #GsfXMLOut
+ * @pp: new state of pretty-print flag.
+ *
+ * Returns: the previous state of the pretty-print flag.
+ **/
+gboolean
+gsf_xml_out_set_pretty_print (GsfXMLOut *xout, gboolean pp)
+{
+       gboolean res;
+
+       g_return_val_if_fail (GSF_IS_XML_OUT (xout), TRUE);
+
+       pp = !!pp;
+
+       res = xout->priv->pretty_print;
+       if (pp != res) {
+               xout->priv->pretty_print = pp;
+               g_object_notify (G_OBJECT (xout), "pretty-print");
+       }
+       return res;
+}
+
 static inline void
 gsf_xml_out_indent (GsfXMLOut *xout)
 {
@@ -1704,23 +1743,24 @@ gsf_xml_out_end_element (GsfXMLOut *xout)
        priv->stack = g_slist_remove (priv->stack, id);
        priv->indent--;
        switch (priv->state) {
-       case GSF_XML_OUT_NOCONTENT :
+       case GSF_XML_OUT_NOCONTENT:
                if (priv->pretty_print)
                        gsf_output_write (xout->output, 3, "/>\n");
                else
                        gsf_output_write (xout->output, 2, "/>");
                break;
 
-       case GSF_XML_OUT_CHILD :
+       case GSF_XML_OUT_CHILD_PRETTY:
                gsf_xml_out_indent (xout);
        /* fall through */
-       case GSF_XML_OUT_CONTENT :
+       case GSF_XML_OUT_CHILD:
+       case GSF_XML_OUT_CONTENT:
                if (priv->pretty_print)
                        gsf_output_printf (xout->output, "</%s>\n", id);
                else
                        gsf_output_printf (xout->output, "</%s>", id);
        }
-       priv->state = GSF_XML_OUT_CHILD;
+       priv->state = priv->pretty_print ? GSF_XML_OUT_CHILD_PRETTY : GSF_XML_OUT_CHILD;
        return id;
 }
 
diff --git a/gsf/gsf-libxml.h b/gsf/gsf-libxml.h
index 103fe9f..709c359 100644
--- a/gsf/gsf-libxml.h
+++ b/gsf/gsf-libxml.h
@@ -184,6 +184,9 @@ void            gsf_xml_out_set_doc_type    (GsfXMLOut *xout, char const *type);
 void       gsf_xml_out_start_element   (GsfXMLOut *xout, char const *id);
 char const *gsf_xml_out_end_element    (GsfXMLOut *xout);
 
+gboolean    gsf_xml_out_get_pretty_print (GsfXMLOut *xout);
+gboolean    gsf_xml_out_set_pretty_print (GsfXMLOut *xout, gboolean pp);
+
 void gsf_xml_out_simple_element                (GsfXMLOut *xout, char const *id,
                                         char const *content);
 void gsf_xml_out_simple_int_element    (GsfXMLOut *xout, char const *id,
diff --git a/tests/.gitignore b/tests/.gitignore
index 5a6b875..b498cc9 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -31,6 +31,7 @@ test-out-printf
 test-outmem-printf
 test-restore-msole
 test-textline
+test-xml
 test-zip-out
 test-zip-out-subdirs
 test-zip1
diff --git a/tests/Makefile.am b/tests/Makefile.am
index bc945ae..075066f 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -36,7 +36,7 @@ check_PROGRAMS = test-msole1 test-msole2 test-cp-msole test-msvba     \
                 test-out-gzip1 test-out-gzip2 test-gzip1 test-gzip2    \
                 test-out-bzip test-bzip                                \
                 test-dump-msole test-restore-msole test-msvba-zip      \
-                test-http test-gio # test-xml
+                test-http test-gio test-xml
 
 EXTRA_DIST = LibGsfTest.pm $(SUPPS) $(TESTS)
 .PHONY: $(TESTS)
diff --git a/tests/test-xml.c b/tests/test-xml.c
index 61f1a12..7ab9c58 100644
--- a/tests/test-xml.c
+++ b/tests/test-xml.c
@@ -2,7 +2,7 @@
 /*
  * test-xml.c: Test libxml2 wrappers
  *
- * Copyright (C) 2003-2006     Jody Goldberg <jody gnome org>
+ * Copyright (C) 2015  Morten Welinder <terra gnome org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of version 2.1 of the GNU Lesser General Public
@@ -20,56 +20,76 @@
  */
 
 #include <stdio.h>
-#include <gsf/gsf-utils.h>
-#include <gsf/gsf-input-stdio.h>
-#include <gsf/gsf-infile.h>
-#include <gsf/gsf-output-stdio.h>
-#include <gsf/gsf-outfile.h>
+#include <gsf/gsf.h>
 
 static int
-test (char *argv[])
+test_xml_indent (void)
 {
-       GsfInput   *input;
-       GsfOutput  *output;
-       GError     *err = NULL;
-       int         rval = 0;
-
-       input = gsf_input_stdio_new (argv[1], &err);
-       if (input == NULL) {
-
-               g_return_val_if_fail (err != NULL, 1);
-
-               g_warning ("'%s' error: %s\n", argv[1], err->message);
-               g_error_free (err);
-               return 1;
-       }
-
-       output = gsf_output_stdio_new (argv[2], &err);
-       if (output == NULL) {
-
-               g_return_val_if_fail (err != NULL, 1);
-
-               g_warning ("'%s' error: %s\n", argv[2], err->message);
-               g_error_free (err);
-
-               g_object_unref (G_OBJECT (input));
-               return 1;
-       }
-
-       if (gsf_input_copy (input, output) == FALSE) {
-               rval = 1;
-               err = (GError*) gsf_output_error (output);
-               if (err != NULL) {
-                       g_warning ("'%s' error: %s\n", argv[2], err->message);
-               }
-       }
-
-       g_object_unref (G_OBJECT (input));
-
-       gsf_output_close (output);
-       g_object_unref (G_OBJECT (output));
-
-       return rval;
+       GsfOutput *mem = gsf_output_memory_new ();
+       GsfXMLOut *xml = gsf_xml_out_new (mem);
+       const char *data;
+       gboolean pprint;
+       int err;
+       const char *expected =
+               "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+               "<outer>\n"
+               "  <data/>\n"
+               "  <data attr=\"val\"/>\n"
+               "  <data>text</data>\n"
+               "  <data>\n"
+               "    <inner>text</inner>\n"
+               "  </data>\n"
+               "  <data>text</data>\n"
+               "  <data><inner>text</inner></data>\n"
+               "</outer>\n";
+
+       gsf_xml_out_start_element (xml, "outer");
+
+       gsf_xml_out_start_element (xml, "data");
+       gsf_xml_out_end_element (xml);
+
+       gsf_xml_out_start_element (xml, "data");
+       gsf_xml_out_add_cstr_unchecked (xml, "attr", "val");
+       gsf_xml_out_end_element (xml);
+
+       gsf_xml_out_start_element (xml, "data");
+       gsf_xml_out_add_cstr_unchecked (xml, NULL, "text");
+       gsf_xml_out_end_element (xml);
+
+       gsf_xml_out_start_element (xml, "data");
+       gsf_xml_out_start_element (xml, "inner");
+       gsf_xml_out_add_cstr_unchecked (xml, NULL, "text");
+       gsf_xml_out_end_element (xml);
+       gsf_xml_out_end_element (xml);
+
+       gsf_xml_out_start_element (xml, "data");
+       pprint = gsf_xml_out_set_pretty_print (xml, FALSE);
+       gsf_xml_out_add_cstr_unchecked (xml, NULL, "text");
+       gsf_xml_out_set_pretty_print (xml, pprint);
+       gsf_xml_out_end_element (xml);
+
+       gsf_xml_out_start_element (xml, "data");
+       pprint = gsf_xml_out_set_pretty_print (xml, FALSE);
+       gsf_xml_out_start_element (xml, "inner");
+       gsf_xml_out_add_cstr_unchecked (xml, NULL, "text");
+       gsf_xml_out_end_element (xml);
+       gsf_xml_out_set_pretty_print (xml, pprint);
+       gsf_xml_out_end_element (xml);
+
+       gsf_xml_out_end_element (xml);
+
+       g_object_unref (xml);
+
+       data = (const char *)gsf_output_memory_get_bytes (GSF_OUTPUT_MEMORY (mem));
+       g_printerr ("Got\n%s\n", data);
+
+       err = !g_str_equal (data, expected);
+       if (err)
+               g_printerr ("Expected\n%s\n", expected);
+
+       g_object_unref (mem);
+
+       return err;
 }
 
 int
@@ -77,13 +97,11 @@ main (int argc, char *argv[])
 {
        int res;
 
-       if (argc != 3) {
-               fprintf (stderr, "%s : files\n", argv [0]);
-               return 1;
-       }
+       (void)argc;
+       (void)argv;
 
        gsf_init ();
-       res = test (argv);
+       res = test_xml_indent ();
        gsf_shutdown ();
 
        return res;


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