summaryrefslogtreecommitdiff
path: root/tree.c
diff options
context:
space:
mode:
authorMike Hommey <glandium@debian.org>2009-03-01 10:55:27 +0100
committerMike Hommey <glandium@debian.org>2009-03-01 10:55:27 +0100
commite248b20a3b7df364cc9617b8685b4c190338bcd2 (patch)
treef289c8584c4a44dd9cdb87003b193488da8b00f3 /tree.c
parent0c8f97ec9edb09da2e0b19c4f9ddf8c725cebc59 (diff)
downloadlibxml2-e248b20a3b7df364cc9617b8685b4c190338bcd2.tar.gz
Import upstream version 2.7.3upstream/2.7.3.dfsg
Diffstat (limited to 'tree.c')
-rw-r--r--tree.c219
1 files changed, 212 insertions, 7 deletions
diff --git a/tree.c b/tree.c
index 76926fd..8e393da 100644
--- a/tree.c
+++ b/tree.c
@@ -14,7 +14,7 @@
#include "libxml.h"
#include <string.h> /* for memset() only ! */
-
+#include <limits.h>
#ifdef HAVE_CTYPE_H
#include <ctype.h>
#endif
@@ -3216,7 +3216,10 @@ xmlAddChildList(xmlNodePtr parent, xmlNodePtr cur) {
cur = cur->next;
}
cur->parent = parent;
- cur->doc = parent->doc; /* the parent may not be linked to a doc ! */
+ /* the parent may not be linked to a doc ! */
+ if (cur->doc != parent->doc) {
+ xmlSetTreeDoc(cur, parent->doc);
+ }
parent->last = cur;
return(cur);
@@ -3309,9 +3312,7 @@ xmlAddChild(xmlNodePtr parent, xmlNodePtr cur) {
if (cur->type == XML_ATTRIBUTE_NODE) {
if (parent->type != XML_ELEMENT_NODE)
return(NULL);
- if (parent->properties == NULL) {
- parent->properties = (xmlAttrPtr) cur;
- } else {
+ if (parent->properties != NULL) {
/* check if an attribute with the same name exists */
xmlAttrPtr lastattr;
@@ -3326,8 +3327,13 @@ xmlAddChild(xmlNodePtr parent, xmlNodePtr cur) {
}
if (lastattr == (xmlAttrPtr) cur)
return(cur);
+
+ }
+ if (parent->properties == NULL) {
+ parent->properties = (xmlAttrPtr) cur;
+ } else {
/* find the end */
- lastattr = parent->properties;
+ xmlAttrPtr lastattr = parent->properties;
while (lastattr->next != NULL) {
lastattr = lastattr->next;
}
@@ -3367,6 +3373,199 @@ xmlGetLastChild(xmlNodePtr parent) {
return(parent->last);
}
+#ifdef LIBXML_TREE_ENABLED
+/*
+ * 5 interfaces from DOM ElementTraversal
+ */
+
+/**
+ * xmlChildElementCount:
+ * @parent: the parent node
+ *
+ * Finds the current number of child nodes of that element which are
+ * element nodes.
+ * Note the handling of entities references is different than in
+ * the W3C DOM element traversal spec since we don't have back reference
+ * from entities content to entities references.
+ *
+ * Returns the count of element child or 0 if not available
+ */
+unsigned long
+xmlChildElementCount(xmlNodePtr parent) {
+ unsigned long ret = 0;
+ xmlNodePtr cur = NULL;
+
+ if (parent == NULL)
+ return(0);
+ switch (parent->type) {
+ case XML_ELEMENT_NODE:
+ case XML_ENTITY_NODE:
+ case XML_DOCUMENT_NODE:
+ case XML_HTML_DOCUMENT_NODE:
+ cur = parent->children;
+ break;
+ default:
+ return(0);
+ }
+ while (cur != NULL) {
+ if (cur->type == XML_ELEMENT_NODE)
+ ret++;
+ cur = cur->next;
+ }
+ return(ret);
+}
+
+/**
+ * xmlFirstElementChild:
+ * @parent: the parent node
+ *
+ * Finds the first child node of that element which is a Element node
+ * Note the handling of entities references is different than in
+ * the W3C DOM element traversal spec since we don't have back reference
+ * from entities content to entities references.
+ *
+ * Returns the first element child or NULL if not available
+ */
+xmlNodePtr
+xmlFirstElementChild(xmlNodePtr parent) {
+ xmlNodePtr cur = NULL;
+
+ if (parent == NULL)
+ return(NULL);
+ switch (parent->type) {
+ case XML_ELEMENT_NODE:
+ case XML_ENTITY_NODE:
+ case XML_DOCUMENT_NODE:
+ case XML_HTML_DOCUMENT_NODE:
+ cur = parent->children;
+ break;
+ default:
+ return(NULL);
+ }
+ while (cur != NULL) {
+ if (cur->type == XML_ELEMENT_NODE)
+ return(cur);
+ cur = cur->next;
+ }
+ return(NULL);
+}
+
+/**
+ * xmlLastElementChild:
+ * @parent: the parent node
+ *
+ * Finds the last child node of that element which is a Element node
+ * Note the handling of entities references is different than in
+ * the W3C DOM element traversal spec since we don't have back reference
+ * from entities content to entities references.
+ *
+ * Returns the last element child or NULL if not available
+ */
+xmlNodePtr
+xmlLastElementChild(xmlNodePtr parent) {
+ xmlNodePtr cur = NULL;
+
+ if (parent == NULL)
+ return(NULL);
+ switch (parent->type) {
+ case XML_ELEMENT_NODE:
+ case XML_ENTITY_NODE:
+ case XML_DOCUMENT_NODE:
+ case XML_HTML_DOCUMENT_NODE:
+ cur = parent->last;
+ break;
+ default:
+ return(NULL);
+ }
+ while (cur != NULL) {
+ if (cur->type == XML_ELEMENT_NODE)
+ return(cur);
+ cur = cur->prev;
+ }
+ return(NULL);
+}
+
+/**
+ * xmlPreviousElementSibling:
+ * @node: the current node
+ *
+ * Finds the first closest previous sibling of the node which is an
+ * element node.
+ * Note the handling of entities references is different than in
+ * the W3C DOM element traversal spec since we don't have back reference
+ * from entities content to entities references.
+ *
+ * Returns the previous element sibling or NULL if not available
+ */
+xmlNodePtr
+xmlPreviousElementSibling(xmlNodePtr node) {
+ if (node == NULL)
+ return(NULL);
+ switch (node->type) {
+ case XML_ELEMENT_NODE:
+ case XML_TEXT_NODE:
+ case XML_CDATA_SECTION_NODE:
+ case XML_ENTITY_REF_NODE:
+ case XML_ENTITY_NODE:
+ case XML_PI_NODE:
+ case XML_COMMENT_NODE:
+ case XML_XINCLUDE_START:
+ case XML_XINCLUDE_END:
+ node = node->prev;
+ break;
+ default:
+ return(NULL);
+ }
+ while (node != NULL) {
+ if (node->type == XML_ELEMENT_NODE)
+ return(node);
+ node = node->next;
+ }
+ return(NULL);
+}
+
+/**
+ * xmlNextElementSibling:
+ * @node: the current node
+ *
+ * Finds the first closest next sibling of the node which is an
+ * element node.
+ * Note the handling of entities references is different than in
+ * the W3C DOM element traversal spec since we don't have back reference
+ * from entities content to entities references.
+ *
+ * Returns the next element sibling or NULL if not available
+ */
+xmlNodePtr
+xmlNextElementSibling(xmlNodePtr node) {
+ if (node == NULL)
+ return(NULL);
+ switch (node->type) {
+ case XML_ELEMENT_NODE:
+ case XML_TEXT_NODE:
+ case XML_CDATA_SECTION_NODE:
+ case XML_ENTITY_REF_NODE:
+ case XML_ENTITY_NODE:
+ case XML_PI_NODE:
+ case XML_COMMENT_NODE:
+ case XML_DTD_NODE:
+ case XML_XINCLUDE_START:
+ case XML_XINCLUDE_END:
+ node = node->next;
+ break;
+ default:
+ return(NULL);
+ }
+ while (node != NULL) {
+ if (node->type == XML_ELEMENT_NODE)
+ return(node);
+ node = node->next;
+ }
+ return(NULL);
+}
+
+#endif /* LIBXML_TREE_ENABLED */
+
/**
* xmlFreeNodeList:
* @cur: the first node in the list
@@ -6996,7 +7195,13 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size)
case XML_BUFFER_ALLOC_DOUBLEIT:
/*take care of empty case*/
newSize = (buf->size ? buf->size*2 : size + 10);
- while (size > newSize) newSize *= 2;
+ while (size > newSize) {
+ if (newSize > UINT_MAX / 2) {
+ xmlTreeErrMemory("growing buffer");
+ return 0;
+ }
+ newSize *= 2;
+ }
break;
case XML_BUFFER_ALLOC_EXACT:
newSize = size+10;