[Freeswitch-svn] [commit] r4081 - in freeswitch/trunk/src: . include

Freeswitch SVN mikej at freeswitch.org
Mon Jan 29 11:58:37 EST 2007


Author: mikej
Date: Mon Jan 29 11:58:37 2007
New Revision: 4081

Modified:
   freeswitch/trunk/src/include/switch_xml.h
   freeswitch/trunk/src/switch_xml.c

Log:
merge changes from ezXML 0.8.6
- fixed a bug in ezxml_add_child() that can occur when adding tags out of order
- for consistency, ezxml_set_attr() now returns the tag given
- added ezxml_move() and supporting functions ezxml_cut() and ezxml_insert()
- fixed a bug where parsing an empty file could cause a segfault


Modified: freeswitch/trunk/src/include/switch_xml.h
==============================================================================
--- freeswitch/trunk/src/include/switch_xml.h	(original)
+++ freeswitch/trunk/src/include/switch_xml.h	Mon Jan 29 11:58:37 2007
@@ -256,9 +256,10 @@
 ///\param xml the xml node
 ///\param name the attribute name
 ///\param value the attribute value
-SWITCH_DECLARE(void) switch_xml_set_attr(switch_xml_t xml, const char *name, const char *value);
+///\return the tag given
+SWITCH_DECLARE(switch_xml_t) switch_xml_set_attr(switch_xml_t xml, const char *name, const char *value);
 
-///\ Wrapper for switch_xml_set_attr() that strdup()s name/value. Value cannot be NULL
+///\brief Wrapper for switch_xml_set_attr() that strdup()s name/value. Value cannot be NULL
 ///\param xml the xml node
 ///\param name the attribute name
 ///\param value the attribute value
@@ -272,10 +273,19 @@
 ///\return an xml node or NULL
 SWITCH_DECLARE(switch_xml_t) switch_xml_set_flag(switch_xml_t xml, switch_xml_flag_t flag);
 
+///\brief removes a tag along with its subtags without freeing its memory
+///\param xml the xml node
+SWITCH_DECLARE(switch_xml_t) switch_xml_cut(switch_xml_t xml);
+
+///\brief inserts an existing tag into an ezxml structure
+SWITCH_DECLARE(switch_xml_t) switch_xml_insert(switch_xml_t xml, switch_xml_t dest, switch_size_t off);
+
+///\brief Moves an existing tag to become a subtag of dest at the given offset from
+///\ the start of dest's character content. Returns the moved tag.
+#define switch_xml_move(xml, dest, off) switch_xml_insert(switch_xml_cut(xml), dest, off)
 
 ///\brief removes a tag along with all its subtags
-///\param xml the xml node
-SWITCH_DECLARE(void) switch_xml_remove(switch_xml_t xml);
+#define switch_xml_remove(xml) switch_xml_free(switch_xml_cut(xml))
 
 ///\brief open the Core xml root
 ///\param reload if it's is already open close it and open it again as soon as permissable (blocking)

Modified: freeswitch/trunk/src/switch_xml.c
==============================================================================
--- freeswitch/trunk/src/switch_xml.c	(original)
+++ freeswitch/trunk/src/switch_xml.c	Mon Jan 29 11:58:37 2007
@@ -28,10 +28,10 @@
  *
  * switch_xml.c -- XML PARSER
  *
- * Derived from EZXML http://ezxml.sourceforge.net
+ * Derived from switch_xml http://switch_xml.sourceforge.net
  * Original Copyright
  *
- * Copyright 2004, 2005 Aaron Voisine <aaron at voisine.org>
+ * Copyright 2004, 2006 Aaron Voisine <aaron at voisine.org>
  *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
@@ -696,7 +696,7 @@
             if (switch_xml_close_tag(root, d, s)) return &root->xml;
             if (isspace((int)(*s = q))) s += strspn(s, SWITCH_XML_WS);
         }
-        else if (! strncmp(s, "!--", 3)) { // comment
+        else if (! strncmp(s, "!--", 3)) { // xml comment
             if (! (s = strstr(s + 3, "--")) || (*(s += 2) != '>' && *s) ||
                 (! *s && e != '>')) return switch_xml_err(root, d, "unclosed <!--");
         }
@@ -1286,8 +1286,8 @@
 	}
 }
 
-// converts an switch_xml structure back to xml, returning it as a string that must
-// be freed
+// converts an switch_xml structure back to xml, returning a string of xml date that
+// must be freed
 SWITCH_DECLARE(char *) switch_xml_toxml(switch_xml_t xml)
 {
     switch_xml_t p = (xml) ? xml->parent : NULL, o = (xml) ? xml->ordered : NULL;
@@ -1410,51 +1410,64 @@
     return &root->xml;
 }
 
-// Adds a child tag. off is the offset of the child tag relative to the start
-// of the parent tag's character content. returns the child tag
-switch_xml_t switch_xml_add_child(switch_xml_t xml, const char *name, switch_size_t off)
+// inserts an existing tag into an switch_xml structure
+SWITCH_DECLARE(switch_xml_t) switch_xml_insert(switch_xml_t xml, switch_xml_t dest, switch_size_t off)
 {
-    switch_xml_t cur, head, child;
+    switch_xml_t cur, prev, head;
 
-    if (! xml) return NULL;
-    child = (switch_xml_t)memset(malloc(sizeof(struct switch_xml)), '\0',
-                            sizeof(struct switch_xml));
-    child->name = (char *)name;
-    child->attr = SWITCH_XML_NIL;
-    child->off = off;
-    child->parent = xml;
-    child->txt = "";
+    xml->next = xml->sibling = xml->ordered = NULL;
+    xml->off = off;
+    xml->parent = dest;
 
-    if ((head = xml->child)) { // already have sub tags
+    if ((head = dest->child)) { // already have sub tags
         if (head->off <= off) { // not first subtag
             for (cur = head; cur->ordered && cur->ordered->off <= off;
                  cur = cur->ordered);
-            child->ordered = cur->ordered;
-            cur->ordered = child;
+            xml->ordered = cur->ordered;
+            cur->ordered = xml;
         }
         else { // first subtag
-            child->ordered = head;
-            xml->child = child;
+            xml->ordered = head;
+            dest->child = xml;
         }
 
-        for (cur = head; cur->sibling && strcmp(cur->name, name);
-             cur = cur->sibling); // find tag type
-        if (! strcmp(cur->name, name) && cur->off <= off) { //not first of type
+        for (cur = head, prev = NULL; cur && strcmp(cur->name, xml->name);
+             prev = cur, cur = cur->sibling); // find tag type
+        if (cur && cur->off <= off) { // not first of type
             while (cur->next && cur->next->off <= off) cur = cur->next;
-            child->next = cur->next;
-            cur->next = child;
+            xml->next = cur->next;
+            cur->next = xml;
         }
         else { // first tag of this type
-            if (cur->off > off) child->next = cur; // not only tag of this type
-            for (cur = head; cur->sibling && cur->sibling->off <= off;
-                 cur = cur->sibling);
-            child->sibling = cur->sibling;
-            cur->sibling = child;
+            if (prev && cur) prev->sibling = cur->sibling; // remove old first
+            xml->next = cur; // old first tag is now next
+            for (cur = head, prev = NULL; cur && cur->off <= off;
+                 prev = cur, cur = cur->sibling); // new sibling insert point
+            xml->sibling = cur;
+            if (prev) prev->sibling = xml;
         }
     }
-    else xml->child = child; // only sub tag
-    
-    return child;
+    else dest->child = xml; // only sub tag
+
+    return xml;
+}
+
+// Adds a child tag. off is the offset of the child tag relative to the start
+// of the parent tag's character content. Returns the child tag
+switch_xml_t switch_xml_add_child(switch_xml_t xml, const char *name, switch_size_t off)
+{
+    switch_xml_t child;
+
+    if (! xml) return NULL;
+    child = (switch_xml_t)memset(malloc(sizeof(struct switch_xml)), '\0',
+                            sizeof(struct switch_xml));
+    child->name = (char *)name;
+    child->attr = SWITCH_XML_NIL;
+    child->off = off;
+    child->parent = xml;
+    child->txt = "";
+
+    return switch_xml_insert(child, xml, off);
 }
 
 // sets the character content for the given tag and returns the tag
@@ -1468,15 +1481,15 @@
 }
 
 // Sets the given tag attribute or adds a new attribute if not found. A value
-// of NULL will remove the specified attribute.
-SWITCH_DECLARE(void) switch_xml_set_attr(switch_xml_t xml, const char *name, const char *value)
+// of NULL will remove the specified attribute.  Returns the tag given
+SWITCH_DECLARE(switch_xml_t) switch_xml_set_attr(switch_xml_t xml, const char *name, const char *value)
 {
     int l = 0, c;
 
-    if (! xml) return;
+    if (! xml) return NULL;
     while (xml->attr[l] && strcmp(xml->attr[l], name)) l += 2;
     if (! xml->attr[l]) { // not found, add as new attribute
-        if (! value) return; // nothing to do
+        if (! value) return xml; // nothing to do
         if (xml->attr == SWITCH_XML_NIL) { // first attribute
             xml->attr = malloc(4 * sizeof(char *));
             xml->attr[1] = strdup(""); // empty list of malloced names/vals
@@ -1506,6 +1519,8 @@
                 (c / 2) - (l / 2)); // fix list of which name/vals are malloced
     }
     xml->flags &= ~SWITCH_XML_DUP; // clear strdup() flag
+
+	return xml;
 }
 
 // sets a flag for the given tag and returns the tag
@@ -1515,12 +1530,12 @@
     return xml;
 }
 
-// removes a tag along with all its subtags
-SWITCH_DECLARE(void) switch_xml_remove(switch_xml_t xml)
+// removes a tag along with its subtags without freeing its memory
+SWITCH_DECLARE(switch_xml_t) switch_xml_cut(switch_xml_t xml)
 {
     switch_xml_t cur;
 
-    if (! xml) return; // nothing to do
+    if (! xml) return NULL; // nothing to do
     if (xml->next) xml->next->sibling = xml->sibling; // patch sibling list
 
     if (xml->parent) { // not root tag
@@ -1545,8 +1560,8 @@
             if (cur->next) cur->next = cur->next->next; // patch next list
         }        
     }
-    xml->ordered = NULL; // prevent switch_xml_free() from clobbering ordered list
-    switch_xml_free(xml);
+	xml->ordered = xml->sibling = xml->next =  NULL; // prevent switch_xml_free() from clobbering ordered list
+    return xml;
 }
 
 /* For Emacs:



More information about the Freeswitch-svn mailing list