diff -u -r1.3 global.data --- global.data 4 Nov 2001 20:19:12 -0000 1.3 +++ global.data 24 May 2002 15:48:28 -0000 @@ -19,3 +19,5 @@ #const xmlChar,xmlStringText,[] #const xmlChar,xmlStringTextNoenc,[] int,xmlSubstituteEntitiesDefaultValue +xmlRegisterNodeFunc,xmlRegisterNodeDefaultValue +xmlDeregisterNodeFunc,xmlDeregisterNodeDefaultValue Index: globals.c =================================================================== RCS file: /cvs/gnome/gnome-xml/globals.c,v retrieving revision 1.14 diff -u -r1.14 globals.c --- globals.c 18 Mar 2002 19:37:03 -0000 1.14 +++ globals.c 24 May 2002 15:48:28 -0000 @@ -218,6 +218,9 @@ */ int xmlSubstituteEntitiesDefaultValue = 0; +xmlRegisterNodeFunc xmlRegisterNodeDefaultValue = NULL; +xmlDeregisterNodeFunc xmlDeregisterNodeDefaultValue = NULL; + /* * Error handling */ @@ -440,8 +443,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 * @@ -631,4 +666,22 @@ return (&xmlSubstituteEntitiesDefaultValue); 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); } Index: tree.c =================================================================== RCS file: /cvs/gnome/gnome-xml/tree.c,v retrieving revision 1.206 diff -u -r1.206 tree.c --- tree.c 5 May 2002 06:57:27 -0000 1.206 +++ tree.c 24 May 2002 15:48:29 -0000 @@ -336,6 +336,8 @@ doc->extSubset = cur; cur->doc = doc; + if (xmlRegisterNodeDefaultValue) + xmlRegisterNodeDefaultValue((xmlNodePtr)cur); return(cur); } @@ -461,6 +463,10 @@ #endif return; } + + if (xmlDeregisterNodeDefaultValue) + xmlDeregisterNodeDefaultValue((xmlNodePtr)cur); + if (cur->children != NULL) { xmlNodePtr next, c = cur->children; @@ -528,6 +534,9 @@ cur->compression = -1; /* not initialized */ cur->doc = cur; cur->charset = XML_CHAR_ENCODING_UTF8; + + if (xmlRegisterNodeDefaultValue) + xmlRegisterNodeDefaultValue((xmlNodePtr)cur); return(cur); } @@ -548,6 +557,10 @@ #endif return; } + + if (xmlDeregisterNodeDefaultValue) + xmlDeregisterNodeDefaultValue((xmlNodePtr)cur); + /* * Do this before freeing the children list to avoid ID lookups */ @@ -1123,6 +1136,9 @@ cur->prev = prev; } } + + if (xmlRegisterNodeDefaultValue) + xmlRegisterNodeDefaultValue((xmlNodePtr)cur); return(cur); } @@ -1200,6 +1216,9 @@ cur->prev = prev; } } + + if (xmlRegisterNodeDefaultValue) + xmlRegisterNodeDefaultValue((xmlNodePtr)cur); return(cur); } @@ -1252,6 +1271,9 @@ tmp = tmp->next; } } + + if (xmlRegisterNodeDefaultValue) + xmlRegisterNodeDefaultValue((xmlNodePtr)cur); return(cur); } @@ -1293,6 +1315,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) || @@ -1390,6 +1416,9 @@ if (content != NULL) { cur->content = xmlStrdup(content); } + + if (xmlRegisterNodeDefaultValue) + xmlRegisterNodeDefaultValue((xmlNodePtr)cur); return(cur); } @@ -1428,6 +1457,9 @@ cur->name = xmlStrdup(name); cur->ns = ns; + + if (xmlRegisterNodeDefaultValue) + xmlRegisterNodeDefaultValue(cur); return(cur); } @@ -1460,6 +1492,7 @@ UPDATE_LAST_CHILD_AND_PARENT(cur) } } + return(cur); } @@ -1516,6 +1549,9 @@ cur->type = XML_DOCUMENT_FRAG_NODE; cur->doc = doc; + + if (xmlRegisterNodeDefaultValue) + xmlRegisterNodeDefaultValue(cur); return(cur); } @@ -1546,6 +1582,9 @@ if (content != NULL) { cur->content = xmlStrdup(content); } + + if (xmlRegisterNodeDefaultValue) + xmlRegisterNodeDefaultValue(cur); return(cur); } @@ -1646,6 +1685,9 @@ cur->name = xmlStrndup(name, len); } else cur->name = xmlStrdup(name); + + if (xmlRegisterNodeDefaultValue) + xmlRegisterNodeDefaultValue(cur); return(cur); } @@ -1697,6 +1739,9 @@ cur->children = (xmlNodePtr) ent; cur->last = (xmlNodePtr) ent; } + + if (xmlRegisterNodeDefaultValue) + xmlRegisterNodeDefaultValue(cur); return(cur); } @@ -1745,6 +1790,9 @@ if (content != NULL) { cur->content = xmlStrndup(content, len); } + + if (xmlRegisterNodeDefaultValue) + xmlRegisterNodeDefaultValue(cur); return(cur); } @@ -1794,6 +1842,9 @@ if (content != NULL) { cur->content = xmlStrdup(content); } + + if (xmlRegisterNodeDefaultValue) + xmlRegisterNodeDefaultValue(cur); return(cur); } @@ -1826,6 +1877,9 @@ if (content != NULL) { cur->content = xmlStrndup(content, len); } + + if (xmlRegisterNodeDefaultValue) + xmlRegisterNodeDefaultValue(cur); return(cur); } @@ -2245,6 +2299,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 { @@ -2254,7 +2311,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. */ @@ -2324,13 +2381,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); @@ -2340,16 +2399,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); @@ -2435,6 +2501,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); @@ -2499,6 +2569,7 @@ #endif return; } + /* use xmlFreeDtd for DTD nodes */ if (cur->type == XML_DTD_NODE) { xmlFreeDtd((xmlDtdPtr) cur); @@ -2508,6 +2579,10 @@ xmlFreeNs((xmlNsPtr) cur); return; } + + if (xmlDeregisterNodeDefaultValue) + xmlDeregisterNodeDefaultValue(cur); + if ((cur->children != NULL) && (cur->type != XML_ENTITY_REF_NODE)) xmlFreeNodeList(cur->children); Index: include/libxml/globals.h =================================================================== RCS file: /cvs/gnome/gnome-xml/include/libxml/globals.h,v retrieving revision 1.7 diff -u -r1.7 globals.h --- include/libxml/globals.h 11 Feb 2002 08:54:05 -0000 1.7 +++ include/libxml/globals.h 24 May 2002 15:48:30 -0000 @@ -51,6 +51,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; @@ -87,6 +92,9 @@ int xmlSaveNoEmptyTags; int xmlIndentTreeOutput; + + xmlRegisterNodeFunc xmlRegisterNodeDefaultValue; + xmlDeregisterNodeFunc xmlDeregisterNodeDefaultValue; }; #ifdef __cplusplus @@ -99,6 +107,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 @@ -317,6 +328,22 @@ (*(__xmlSubstituteEntitiesDefaultValue())) #else 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