[librest] xml-node: Define the order in which attributes & children are printed



commit 8f461d0d4a1e74f2540191b25d719f826e357e6b
Author: Debarshi Ray <debarshir gnome org>
Date:   Fri Oct 13 19:14:16 2017 +0200

    xml-node: Define the order in which attributes & children are printed
    
    The order in which GHashTable returns its key-value pairs is undefined.
    Therefore the output of rest_xml_node_print can change based on the
    GHashTable implementation. While not strictly necessary, it would be
    nice to avoid that. Having a stable order, even if it is not
    documented and depends on the current RestXmlNode code, is handy for
    testing.
    
    This was the main reason behind the tests/xml.c breakage.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=788960

 rest/rest-xml-node.c |   23 ++++++++++++++++++++++-
 1 files changed, 22 insertions(+), 1 deletions(-)
---
diff --git a/rest/rest-xml-node.c b/rest/rest-xml-node.c
index 5a444ce..5e64851 100644
--- a/rest/rest-xml-node.c
+++ b/rest/rest-xml-node.c
@@ -280,6 +280,9 @@ rest_xml_node_print (RestXmlNode *node)
 {
   GHashTableIter iter;
   gpointer       key, value;
+  GList          *attrs = NULL;
+  GList          *children = NULL;
+  GList          *l;
   GString        *xml = g_string_new (NULL);
   RestXmlNode   *n;
 
@@ -288,13 +291,29 @@ rest_xml_node_print (RestXmlNode *node)
 
   g_hash_table_iter_init (&iter, node->attrs);
   while (g_hash_table_iter_next (&iter, &key, &value))
-    g_string_append_printf (xml, " %s=\'%s\'", (char *)key, (char *)value);
+    {
+      char *attr = g_strdup_printf ("%s=\'%s\'", (char *)key, (char *)value);
+      attrs = g_list_prepend (attrs, attr);
+    }
+
+  attrs = g_list_sort (attrs, (GCompareFunc) g_strcmp0);
+  for (l = attrs; l; l = l->next)
+    {
+      const char *attr = (const char *) l->data;
+      g_string_append_printf (xml, " %s", attr);
+    }
 
   g_string_append (xml, ">");
 
   g_hash_table_iter_init (&iter, node->children);
   while (g_hash_table_iter_next (&iter, &key, &value))
+    children = g_list_prepend (children, key);
+
+  children = g_list_sort (children, (GCompareFunc) g_strcmp0);
+  for (l = children; l; l = l->next)
     {
+      const char *name = (const char *) l->data;
+      RestXmlNode *value = (RestXmlNode *) g_hash_table_lookup (node->children, name);
       char *child = rest_xml_node_print ((RestXmlNode *) value);
 
       g_string_append (xml, child);
@@ -314,6 +333,8 @@ rest_xml_node_print (RestXmlNode *node)
       g_free (sibling);
     }
 
+  g_list_free_full (attrs, g_free);
+  g_list_free (children);
   return g_string_free (xml, FALSE);
 }
 


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