diff --git a/storage/connect/libdoc.cpp b/storage/connect/libdoc.cpp index 95b98931680..2a786ef0eef 100644 --- a/storage/connect/libdoc.cpp +++ b/storage/connect/libdoc.cpp @@ -30,6 +30,53 @@ extern char version[]; extern int trace; } // "C" +#if defined(_DEBUG) +static xmlFreeFunc Free; +static xmlMallocFunc Malloc; +static xmlMallocFunc MallocA; +static xmlReallocFunc Realloc; +static xmlStrdupFunc Strdup; + +void xmlMyFree(void *mem) +{ + if (trace) + htrc("Freeing at %p\n", mem); + Free(mem); +} // end of xmlMyFree + +void *xmlMyMalloc(size_t size) +{ + void *p = Malloc(size); + if (trace) + htrc("Allocating %.5d at %p\n", size, p); + return p; +} // end of xmlMyMalloc + +void *xmlMyMallocAtomic(size_t size) +{ + void *p = MallocA(size); + if (trace) + htrc("Atom alloc %.5d at %p\n", size, p); + return p; +} // end of xmlMyMallocAtomic + +void *xmlMyRealloc(void *mem, size_t size) +{ + void *p = Realloc(mem, size); + if (trace) + htrc("ReAlloc %.5d to %p from %p\n", size, p, mem); + return p; +} // end of xmlMyRealloc + +char *xmlMyStrdup(const char *str) +{ + char *p = Strdup(str); + if (trace) + htrc("Duplicating to %p from %p %s\n", p, str, str); + return p; +} // end of xmlMyStrdup +#endif // _DEBUG + /******************************************************************/ /* Return a LIBXMLDOC as a XMLDOC. */ /******************************************************************/ @@ -44,6 +91,17 @@ PXDOC GetLibxmlDoc(PGLOBAL g, char *nsl, char *nsdf, /******************************************************************/ void XmlInitParserLib(void) { +#if defined(_DEBUG) +int rc = xmlGcMemGet(&Free, &Malloc, &MallocA, &Realloc, &Strdup); + +if (!rc) + rc = xmlGcMemSetup(xmlMyFree, + xmlMyMalloc, + xmlMyMallocAtomic, + xmlMyRealloc, + xmlMyStrdup); + +#endif // _DEBUG xmlInitParser(); } // end of XmlInitParserLib @@ -63,6 +121,9 @@ void CloseXML2File(PGLOBAL g, PFBLOCK fp, bool all) { PX2BLOCK xp = (PX2BLOCK)fp; + if (trace) + htrc("CloseXML2File: xp=%p count=%d\n", xp, (xp) ? xp->Count : 0); + if (xp && xp->Count > 1 && !all) { xp->Count--; } else if (xp && xp->Count > 0) { @@ -101,6 +162,9 @@ bool LIBXMLDOC::Initialize(PGLOBAL g) /******************************************************************/ bool LIBXMLDOC::ParseFile(char *fn) { + if (trace) + htrc("ParseFile\n"); + if ((Docp = xmlParseFile(fn))) { if (Docp->encoding) Encoding = (char*)Docp->encoding; @@ -149,6 +213,9 @@ bool LIBXMLDOC::NewDoc(PGLOBAL g, char *ver) /******************************************************************/ void LIBXMLDOC::AddComment(PGLOBAL g, char *txtp) { + if (trace) + htrc("AddComment: %s\n", txtp); + xmlNodePtr cp = xmlNewDocComment(Docp, BAD_CAST txtp); xmlAddChild((xmlNodePtr)Docp, cp); } // end of AddText @@ -158,6 +225,9 @@ void LIBXMLDOC::AddComment(PGLOBAL g, char *txtp) /******************************************************************/ PXNODE LIBXMLDOC::GetRoot(PGLOBAL g) { + if (trace) + htrc("GetRoot\n"); + xmlNodePtr root = xmlDocGetRootElement(Docp); if (!root) @@ -171,6 +241,9 @@ PXNODE LIBXMLDOC::GetRoot(PGLOBAL g) /******************************************************************/ PXNODE LIBXMLDOC::NewRoot(PGLOBAL g, char *name) { + if (trace) + htrc("NewRoot: %s\n", name); + xmlNodePtr root = xmlNewDocNode(Docp, NULL, BAD_CAST name, NULL); if (root) { @@ -186,6 +259,9 @@ PXNODE LIBXMLDOC::NewRoot(PGLOBAL g, char *name) /******************************************************************/ PXNODE LIBXMLDOC::NewPnode(PGLOBAL g, char *name) { + if (trace) + htrc("NewNode: %s\n", name); + xmlNodePtr nop; if (name) { @@ -224,6 +300,9 @@ int LIBXMLDOC::DumpDoc(PGLOBAL g, char *ofn) int rc = 0; FILE *of; + if (trace) + htrc("DumpDoc: %s\n", ofn); + if (!(of= global_fopen(g, MSGID_CANNOT_OPEN, ofn, "w"))) return -1; @@ -264,6 +343,9 @@ int LIBXMLDOC::DumpDoc(PGLOBAL g, char *ofn) /******************************************************************/ void LIBXMLDOC::CloseDoc(PGLOBAL g, PFBLOCK xp) { + if (trace) + htrc("CloseDoc: xp=%p count=%d\n", xp, (xp) ? xp->Count : 0); + if (xp && xp->Count == 1) { if (Xop) xmlXPathFreeObject(Xop); @@ -284,12 +366,18 @@ xmlNodeSetPtr LIBXMLDOC::GetNodeList(PGLOBAL g, xmlNodePtr np, char *xp) xmlNodeSetPtr nl; if (trace) - htrc("GetNodeList %s np=%p\n", xp, np); + htrc("GetNodeList: %s np=%p\n", xp, np); if (!Ctxp) { // Init Xpath + if (trace) + htrc("Calling xmlPathInit\n"); + xmlXPathInit(); + if (trace) + htrc("Calling xmlXPathNewContext Docp=%p\n", Docp); + // Create xpath evaluation context if (!(Ctxp = xmlXPathNewContext(Docp))) { strcpy(g->Message, MSG(XPATH_CNTX_ERR)); @@ -301,7 +389,11 @@ xmlNodeSetPtr LIBXMLDOC::GetNodeList(PGLOBAL g, xmlNodePtr np, char *xp) } // endif xpathCtx // Register namespaces from list (if any) - for (PNS nsp = Namespaces; nsp; nsp = nsp->Next) + for (PNS nsp = Namespaces; nsp; nsp = nsp->Next) { + if (trace) + htrc("Calling xmlXPathRegisterNs Prefix=%s Uri=%s\n", + nsp->Prefix, nsp->Uri); + if (xmlXPathRegisterNs(Ctxp, BAD_CAST nsp->Prefix, BAD_CAST nsp->Uri)) { sprintf(g->Message, MSG(REGISTER_ERR), nsp->Prefix, nsp->Uri); @@ -312,12 +404,22 @@ xmlNodeSetPtr LIBXMLDOC::GetNodeList(PGLOBAL g, xmlNodePtr np, char *xp) return NULL; } // endif Registering - } else - xmlXPathFreeNodeSetList(Xop); // To be checked + } // endfor nsp + + } else { + if (trace) + htrc("Calling xmlXPathFreeNodeSetList Xop=%p\n", Xop); + + xmlXPathFreeObject(Xop); +// xmlXPathFreeNodeSetList(Xop); // Caused memory leak + } // endif Ctxp // Set the context to the calling node Ctxp->node = np; + if (trace) + htrc("Calling xmlXPathEval %s Ctxp=%p\n", xp, Ctxp); + // Evaluate table xpath if (!(Xop = xmlXPathEval(BAD_CAST xp, Ctxp))) { sprintf(g->Message, MSG(XPATH_EVAL_ERR), xp); @@ -439,6 +541,9 @@ int XML2NODE::GetType(void) /******************************************************************/ PXNODE XML2NODE::GetNext(PGLOBAL g) { + if (trace) + htrc("GetNext\n"); + if (!Nodep->next) Next = NULL; else if (!Next) @@ -452,6 +557,9 @@ PXNODE XML2NODE::GetNext(PGLOBAL g) /******************************************************************/ PXNODE XML2NODE::GetChild(PGLOBAL g) { + if (trace) + htrc("GetChild\n"); + if (!Nodep->children) Children = NULL; else if (!Children) @@ -467,6 +575,9 @@ RCODE XML2NODE::GetContent(PGLOBAL g, char *buf, int len) { RCODE rc = RC_OK; + if (trace) + htrc("GetContent\n"); + if (Content) xmlFree(Content); @@ -505,18 +616,24 @@ RCODE XML2NODE::GetContent(PGLOBAL g, char *buf, int len) } else *buf = '\0'; + if (trace) + htrc("GetContent: %s\n", buf); + return rc; - } // end of GetText + } // end of GetContent /******************************************************************/ /* Set the content of a node. */ /******************************************************************/ bool XML2NODE::SetContent(PGLOBAL g, char *txtp, int len) { + if (trace) + htrc("SetContent: %s\n", txtp); + xmlChar *buf = xmlEncodeEntitiesReentrant(Docp, BAD_CAST txtp); if (trace) - htrc("SetContent %s -> %s\n", txtp, buf); + htrc("SetContent: %s -> %s\n", txtp, buf); xmlNodeSetContent(Nodep, buf); xmlFree(buf); @@ -528,6 +645,9 @@ bool XML2NODE::SetContent(PGLOBAL g, char *txtp, int len) /******************************************************************/ PXNODE XML2NODE::Clone(PGLOBAL g, PXNODE np) { + if (trace) + htrc("Clone: np=%p\n", np); + if (np) { ((PNODE2)np)->Nodep = Nodep; return np; @@ -542,7 +662,7 @@ PXNODE XML2NODE::Clone(PGLOBAL g, PXNODE np) PXLIST XML2NODE::GetChildElements(PGLOBAL g, char *xp, PXLIST lp) { if (trace) - htrc("GetChildElements %s\n", xp); + htrc("GetChildElements: %s\n", xp); return SelectNodes(g, (xp) ? xp : (char*)"*", lp); } // end of GetChildElements @@ -553,7 +673,7 @@ PXLIST XML2NODE::GetChildElements(PGLOBAL g, char *xp, PXLIST lp) PXLIST XML2NODE::SelectNodes(PGLOBAL g, char *xp, PXLIST lp) { if (trace) - htrc("SelectNodes %s\n", xp); + htrc("SelectNodes: %s\n", xp); xmlNodeSetPtr nl = ((PXDOC2)Doc)->GetNodeList(g, Nodep, xp); @@ -571,7 +691,7 @@ PXLIST XML2NODE::SelectNodes(PGLOBAL g, char *xp, PXLIST lp) PXNODE XML2NODE::SelectSingleNode(PGLOBAL g, char *xp, PXNODE np) { if (trace) - htrc("SelectSingleNode %s\n", xp); + htrc("SelectSingleNode: %s\n", xp); xmlNodeSetPtr nl = ((PXDOC2)Doc)->GetNodeList(g, Nodep, xp); @@ -593,7 +713,7 @@ PXNODE XML2NODE::SelectSingleNode(PGLOBAL g, char *xp, PXNODE np) PXATTR XML2NODE::GetAttribute(PGLOBAL g, char *name, PXATTR ap) { if (trace) - htrc("GetAttribute %s\n", name); + htrc("GetAttribute: %s\n", name); xmlAttrPtr atp = xmlHasProp(Nodep, BAD_CAST name); @@ -618,7 +738,7 @@ PXNODE XML2NODE::AddChildNode(PGLOBAL g, char *name, PXNODE np) char *p, *pn, *pf = NULL; if (trace) - htrc("AddChildNode %s\n", name); + htrc("AddChildNode: %s\n", name); // Is a prefix specified if ((pn = strchr(name, ':'))) { @@ -669,7 +789,7 @@ PXNODE XML2NODE::AddChildNode(PGLOBAL g, char *name, PXNODE np) PXATTR XML2NODE::AddProperty(PGLOBAL g, char *name, PXATTR ap) { if (trace) - htrc("AddProperty %s\n", name); + htrc("AddProperty: %s\n", name); xmlAttrPtr atp = xmlNewProp(Nodep, BAD_CAST name, NULL); @@ -692,7 +812,7 @@ PXATTR XML2NODE::AddProperty(PGLOBAL g, char *name, PXATTR ap) void XML2NODE::AddText(PGLOBAL g, char *txtp) { if (trace) - htrc("AddText %s\n", txtp); + htrc("AddText: %s\n", txtp); // This is to avoid a blank line when inserting a new line xmlNodePtr np = xmlGetLastChild(Nodep); @@ -711,6 +831,9 @@ void XML2NODE::AddText(PGLOBAL g, char *txtp) /******************************************************************/ void XML2NODE::DeleteChild(PGLOBAL g, PXNODE dnp) { + if (trace) + htrc("DeleteChild: node=%p\n", dnp); + xmlNodePtr np = ((PNODE2)dnp)->Nodep; xmlNodePtr text = np->next; @@ -750,7 +873,7 @@ int XML2NODELIST::GetLength(void) PXNODE XML2NODELIST::GetItem(PGLOBAL g, int n, PXNODE np) { if (trace) - htrc("GetItem %d\n", n); + htrc("GetItem: %d\n", n); if (!Listp || Listp->nodeNr <= n) return NULL; @@ -781,7 +904,7 @@ XML2ATTR::XML2ATTR(PXDOC dp, xmlAttrPtr ap, xmlNodePtr np) bool XML2ATTR::SetText(PGLOBAL g, char *txtp, int len) { if (trace) - htrc("SetText %s %d\n", txtp, len); + htrc("SetText: %s %d\n", txtp, len); xmlSetProp(Parent, Atrp->name, BAD_CAST txtp); return false;