applied an old patch from Lukas Schroeder to track node creation and
* global.data globals.c tree.c include/libxml/globals.h: applied
an old patch from Lukas Schroeder to track node creation and
destruction. Probably missing a lot of references at the moment
and not usable reliably.
Daniel
diff --git a/ChangeLog b/ChangeLog
index c1cc0cf..360b36d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Wed Jan 1 21:57:28 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+ * global.data globals.c tree.c include/libxml/globals.h: applied
+ an old patch from Lukas Schroeder to track node creation and
+ destruction. Probably missing a lot of references at the moment
+ and not usable reliably.
+
Wed Jan 1 20:12:07 CET 2003 Daniel Veillard <daniel@veillard.com>
* NEWS doc/Makefile.am doc/news.xsl: generate the NEWS file
diff --git a/global.data b/global.data
index 43d2fb5..6b170dd 100644
--- a/global.data
+++ b/global.data
@@ -20,3 +20,5 @@
#const xmlChar,xmlStringText,[]
#const xmlChar,xmlStringTextNoenc,[]
int,xmlSubstituteEntitiesDefaultValue
+xmlRegisterNodeFunc,xmlRegisterNodeDefaultValue
+xmlDeregisterNodeFunc,xmlDeregisterNodeDefaultValue
diff --git a/globals.c b/globals.c
index 72865c3..7244692 100644
--- a/globals.c
+++ b/globals.c
@@ -219,6 +219,9 @@
*/
int xmlSubstituteEntitiesDefaultValue = 0;
+xmlRegisterNodeFunc xmlRegisterNodeDefaultValue = NULL;
+xmlDeregisterNodeFunc xmlDeregisterNodeDefaultValue = NULL;
+
/*
* Error handling
*/
@@ -450,8 +453,40 @@
gs->xmlPedanticParserDefaultValue = 0;
gs->xmlSaveNoEmptyTags = 0;
gs->xmlSubstituteEntitiesDefaultValue = 0;
+
+ gs->xmlRegisterNodeDefaultValue = NULL;
+ gs->xmlDeregisterNodeDefaultValue = NULL;
}
+/**
+ * xmlRegisterNodeDefault
+ * @func: function pointer to the new RegisterNodeFunc
+ *
+ */
+xmlRegisterNodeFunc
+xmlRegisterNodeDefault(xmlRegisterNodeFunc func)
+{
+ xmlRegisterNodeFunc old = xmlRegisterNodeDefaultValue;
+
+ xmlRegisterNodeDefaultValue = func;
+ return(old);
+}
+
+/**
+ * xmlDeegisterNodeDefault
+ * @func: function pointer to the new DeregisterNodeFunc
+ *
+ */
+xmlDeregisterNodeFunc
+xmlDeregisterNodeDefault(xmlDeregisterNodeFunc func)
+{
+ xmlDeregisterNodeFunc old = xmlDeregisterNodeDefaultValue;
+
+ xmlDeregisterNodeDefaultValue = func;
+ return(old);
+}
+
+
#ifdef LIBXML_DOCB_ENABLED
#undef docbDefaultSAXHandler
xmlSAXHandler *
@@ -651,3 +686,21 @@
else
return (&xmlGetGlobalState()->xmlSubstituteEntitiesDefaultValue);
}
+
+#undef xmlRegisterNodeDefaultValue
+xmlRegisterNodeFunc *
+__xmlRegisterNodeDefaultValue(void) {
+ if (IS_MAIN_THREAD)
+ return (&xmlRegisterNodeDefaultValue);
+ else
+ return (&xmlGetGlobalState()->xmlRegisterNodeDefaultValue);
+}
+
+#undef xmlDeregisterNodeDefaultValue
+xmlDeregisterNodeFunc *
+__xmlDeregisterNodeDefaultValue(void) {
+ if (IS_MAIN_THREAD)
+ return (&xmlDeregisterNodeDefaultValue);
+ else
+ return (&xmlGetGlobalState()->xmlDeregisterNodeDefaultValue);
+}
diff --git a/include/libxml/globals.h b/include/libxml/globals.h
index fc6c01e..ce98a11 100644
--- a/include/libxml/globals.h
+++ b/include/libxml/globals.h
@@ -52,6 +52,11 @@
#undef xmlRealloc
#undef xmlSaveNoEmptyTags
#undef xmlSubstituteEntitiesDefaultValue
+#undef xmlRegisterNodeDefaultValue
+#undef xmlDeregisterNodeDefaultValue
+
+typedef void (*xmlRegisterNodeFunc)(xmlNodePtr node);
+typedef void (*xmlDeregisterNodeFunc)(xmlNodePtr node);
typedef struct _xmlGlobalState xmlGlobalState;
typedef xmlGlobalState *xmlGlobalStatePtr;
@@ -89,6 +94,9 @@
int xmlSaveNoEmptyTags;
int xmlIndentTreeOutput;
const char *xmlTreeIndentString;
+
+ xmlRegisterNodeFunc xmlRegisterNodeDefaultValue;
+ xmlDeregisterNodeFunc xmlDeregisterNodeDefaultValue;
};
#ifdef __cplusplus
@@ -101,6 +109,9 @@
void xmlInitializeGlobalState(xmlGlobalStatePtr gs);
+xmlRegisterNodeFunc xmlRegisterNodeDefault(xmlRegisterNodeFunc func);
+xmlDeregisterNodeFunc xmlDeregisterNodeDefault(xmlDeregisterNodeFunc func);
+
/*
* In general the memory allocation entry points are not kept
* thread specific but this can be overridden by LIBXML_THREAD_ALLOC_ENABLED
@@ -329,6 +340,22 @@
LIBXML_DLL_IMPORT extern int xmlSubstituteEntitiesDefaultValue;
#endif
+extern xmlRegisterNodeFunc *__xmlRegisterNodeDefaultValue(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlRegisterNodeDefaultValue \
+(*(__xmlRegisterNodeDefaultValue()))
+#else
+LIBXML_DLL_IMPORT extern xmlRegisterNodeFunc xmlRegisterNodeDefaultValue;
+#endif
+
+extern xmlDeregisterNodeFunc *__xmlDeregisterNodeDefaultValue(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlDeregisterNodeDefaultValue \
+(*(__xmlDeregisterNodeDefaultValue()))
+#else
+LIBXML_DLL_IMPORT extern xmlDeregisterNodeFunc xmlDeregisterNodeDefaultValue;
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/tree.c b/tree.c
index 67b7d16..7df24d5 100644
--- a/tree.c
+++ b/tree.c
@@ -338,6 +338,8 @@
doc->extSubset = cur;
cur->doc = doc;
+ if (xmlRegisterNodeDefaultValue)
+ xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
return(cur);
}
@@ -463,6 +465,10 @@
#endif
return;
}
+
+ if (xmlDeregisterNodeDefaultValue)
+ xmlDeregisterNodeDefaultValue((xmlNodePtr)cur);
+
if (cur->children != NULL) {
xmlNodePtr next, c = cur->children;
@@ -530,6 +536,9 @@
cur->compression = -1; /* not initialized */
cur->doc = cur;
cur->charset = XML_CHAR_ENCODING_UTF8;
+
+ if (xmlRegisterNodeDefaultValue)
+ xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
return(cur);
}
@@ -550,6 +559,10 @@
#endif
return;
}
+
+ if (xmlDeregisterNodeDefaultValue)
+ xmlDeregisterNodeDefaultValue((xmlNodePtr)cur);
+
/*
* Do this before freeing the children list to avoid ID lookups
*/
@@ -1127,6 +1140,9 @@
cur->prev = prev;
}
}
+
+ if (xmlRegisterNodeDefaultValue)
+ xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
return(cur);
}
@@ -1204,6 +1220,9 @@
cur->prev = prev;
}
}
+
+ if (xmlRegisterNodeDefaultValue)
+ xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
return(cur);
}
@@ -1333,6 +1352,9 @@
tmp = tmp->next;
}
}
+
+ if (xmlRegisterNodeDefaultValue)
+ xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
return(cur);
}
@@ -1374,6 +1396,10 @@
#endif
return;
}
+
+ if (xmlDeregisterNodeDefaultValue)
+ xmlDeregisterNodeDefaultValue((xmlNodePtr)cur);
+
/* Check for ID removal -> leading to invalid references ! */
if ((cur->parent != NULL) && (cur->parent->doc != NULL) &&
((cur->parent->doc->intSubset != NULL) ||
@@ -1471,6 +1497,9 @@
if (content != NULL) {
cur->content = xmlStrdup(content);
}
+
+ if (xmlRegisterNodeDefaultValue)
+ xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
return(cur);
}
@@ -1509,6 +1538,9 @@
cur->name = xmlStrdup(name);
cur->ns = ns;
+
+ if (xmlRegisterNodeDefaultValue)
+ xmlRegisterNodeDefaultValue(cur);
return(cur);
}
@@ -1579,6 +1611,7 @@
UPDATE_LAST_CHILD_AND_PARENT(cur)
}
}
+
return(cur);
}
@@ -1667,6 +1700,9 @@
cur->type = XML_DOCUMENT_FRAG_NODE;
cur->doc = doc;
+
+ if (xmlRegisterNodeDefaultValue)
+ xmlRegisterNodeDefaultValue(cur);
return(cur);
}
@@ -1697,6 +1733,9 @@
if (content != NULL) {
cur->content = xmlStrdup(content);
}
+
+ if (xmlRegisterNodeDefaultValue)
+ xmlRegisterNodeDefaultValue(cur);
return(cur);
}
@@ -1797,6 +1836,9 @@
cur->name = xmlStrndup(name, len);
} else
cur->name = xmlStrdup(name);
+
+ if (xmlRegisterNodeDefaultValue)
+ xmlRegisterNodeDefaultValue(cur);
return(cur);
}
@@ -1848,6 +1890,9 @@
cur->children = (xmlNodePtr) ent;
cur->last = (xmlNodePtr) ent;
}
+
+ if (xmlRegisterNodeDefaultValue)
+ xmlRegisterNodeDefaultValue(cur);
return(cur);
}
@@ -1896,6 +1941,9 @@
if (content != NULL) {
cur->content = xmlStrndup(content, len);
}
+
+ if (xmlRegisterNodeDefaultValue)
+ xmlRegisterNodeDefaultValue(cur);
return(cur);
}
@@ -1945,6 +1993,9 @@
if (content != NULL) {
cur->content = xmlStrdup(content);
}
+
+ if (xmlRegisterNodeDefaultValue)
+ xmlRegisterNodeDefaultValue(cur);
return(cur);
}
@@ -1977,6 +2028,9 @@
if (content != NULL) {
cur->content = xmlStrndup(content, len);
}
+
+ if (xmlRegisterNodeDefaultValue)
+ xmlRegisterNodeDefaultValue(cur);
return(cur);
}
@@ -2398,6 +2452,9 @@
/*
* add the first element at the end of the children list.
*/
+ if (cur->parent == parent)
+ return(cur);
+
if (parent->children == NULL) {
parent->children = cur;
} else {
@@ -2407,7 +2464,7 @@
if ((cur->type == XML_TEXT_NODE) &&
(parent->last->type == XML_TEXT_NODE) &&
(cur->name == parent->last->name)) {
- xmlNodeAddContent(parent->last, cur->content);
+ xmlNodeAddContent(parent->last, cur->content);
/*
* if it's the only child, nothing more to be done.
*/
@@ -2477,13 +2534,15 @@
*/
if (cur->type == XML_TEXT_NODE) {
if ((parent->type == XML_TEXT_NODE) &&
- (parent->content != NULL)) {
+ (parent->content != NULL) &&
+ (parent != cur)) {
xmlNodeAddContent(parent, cur->content);
xmlFreeNode(cur);
return(parent);
}
if ((parent->last != NULL) && (parent->last->type == XML_TEXT_NODE) &&
- (parent->last->name == cur->name)) {
+ (parent->last->name == cur->name) &&
+ (parent->last != cur)) {
xmlNodeAddContent(parent->last, cur->content);
xmlFreeNode(cur);
return(parent->last);
@@ -2493,16 +2552,23 @@
/*
* add the new element at the end of the children list.
*/
+ prev = cur->parent;
cur->parent = parent;
if (cur->doc != parent->doc) {
xmlSetTreeDoc(cur, parent->doc);
}
+ /* this check prevents a loop on tree-traversions if a developer
+ * tries to add a node to its parent multiple times
+ */
+ if (prev == parent)
+ return(cur);
/*
* Coalescing
*/
if ((parent->type == XML_TEXT_NODE) &&
- (parent->content != NULL)) {
+ (parent->content != NULL) &&
+ (parent != cur)) {
xmlNodeAddContent(parent, cur->content);
xmlFreeNode(cur);
return(parent);
@@ -2588,6 +2654,10 @@
next = cur->next;
/* unroll to speed up freeing the document */
if (cur->type != XML_DTD_NODE) {
+
+ if (xmlDeregisterNodeDefaultValue)
+ xmlDeregisterNodeDefaultValue(cur);
+
if ((cur->children != NULL) &&
(cur->type != XML_ENTITY_REF_NODE))
xmlFreeNodeList(cur->children);
@@ -2655,6 +2725,7 @@
#endif
return;
}
+
/* use xmlFreeDtd for DTD nodes */
if (cur->type == XML_DTD_NODE) {
xmlFreeDtd((xmlDtdPtr) cur);
@@ -2668,6 +2739,10 @@
xmlFreeProp((xmlAttrPtr) cur);
return;
}
+
+ if (xmlDeregisterNodeDefaultValue)
+ xmlDeregisterNodeDefaultValue(cur);
+
if ((cur->children != NULL) &&
(cur->type != XML_ENTITY_REF_NODE))
xmlFreeNodeList(cur->children);