cleaning up XPath error reporting that time. applied the two patches for

* error.c include/libxml/xmlerror.h include/libxml/xpath.h
  include/libxml/xpathInternals.h xpath.c: cleaning up XPath
  error reporting that time.
* threads.c: applied the two patches for TLS threads
  on Windows from Jesse Pelton
* parser.c: tiny safety patch for xmlStrPrintf() make sure the
  return is always zero terminated. Should also help detecting
  passing wrong buffer size easilly.
* result/VC/* result/valid/rss.xml.err result/valid/xlink.xml.err:
  updated the results to follow the errors string generated by
  last commit.
Daniel
diff --git a/ChangeLog b/ChangeLog
index 795696d..38228d8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+Tue Oct  7 23:19:39 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* error.c include/libxml/xmlerror.h include/libxml/xpath.h
+	  include/libxml/xpathInternals.h xpath.c: cleaning up XPath
+	  error reporting that time. 
+	* threads.c: applied the two patches for TLS threads
+	  on Windows from Jesse Pelton
+	* parser.c: tiny safety patch for xmlStrPrintf() make sure the
+	  return is always zero terminated. Should also help detecting
+	  passing wrong buffer size easilly.
+	* result/VC/* result/valid/rss.xml.err result/valid/xlink.xml.err:
+	  updated the results to follow the errors string generated by
+	  last commit.
+
 Tue Oct  7 14:16:45 CEST 2003 Daniel Veillard <daniel@veillard.com>
 
 	* relaxng.c include/libxml/xmlerror.h: last cleanup of error
diff --git a/error.c b/error.c
index f2fe378..59c7037 100644
--- a/error.c
+++ b/error.c
@@ -262,13 +262,13 @@
         if (input != NULL) {
             if (input->filename)
                 channel(data, "%s:%d: ", input->filename, input->line);
-            else
+            else if ((line != 0) && (domain == XML_FROM_PARSER))
                 channel(data, "Entity: line %d: ", input->line);
         }
     } else {
         if (file != NULL)
             channel(data, "%s:%d: ", file, line);
-        else
+        else if ((line != 0) && (domain == XML_FROM_PARSER))
             channel(data, "Entity: line %d: ", line);
     }
     if (name != NULL) {
@@ -362,11 +362,24 @@
         if (cur != NULL) {
             if (cur->filename)
                 channel(data, "%s:%d: \n", cur->filename, cur->line);
-            else
+            else if ((line != 0) && (domain == XML_FROM_PARSER))
                 channel(data, "Entity: line %d: \n", cur->line);
             xmlParserPrintFileContextInternal(cur, channel, data);
         }
     }
+    if ((domain == XML_FROM_XPATH) && (err->str1 != NULL) &&
+        (err->int1 < 100) &&
+	(err->int1 < xmlStrlen((const xmlChar *)err->str1))) {
+	xmlChar buf[150];
+	int i;
+
+	channel(data, "%s\n", err->str1);
+	for (i=0;i < err->int1;i++)
+	     buf[i] = ' ';
+	buf[i++] = '^';
+	buf[i] = 0;
+	channel(data, "%s\n", buf);
+    }
 }
 
 /**
diff --git a/include/libxml/xmlerror.h b/include/libxml/xmlerror.h
index 2d65360..7c21aec 100644
--- a/include/libxml/xmlerror.h
+++ b/include/libxml/xmlerror.h
@@ -375,7 +375,29 @@
     XML_RNGP_VALUE_EMPTY,
     XML_RNGP_VALUE_NO_CONTENT,
     XML_RNGP_XMLNS_NAME,
-    XML_RNGP_XML_NS
+    XML_RNGP_XML_NS,
+    XML_XPATH_EXPRESSION_OK = 1200,
+    XML_XPATH_NUMBER_ERROR,
+    XML_XPATH_UNFINISHED_LITERAL_ERROR,
+    XML_XPATH_START_LITERAL_ERROR,
+    XML_XPATH_VARIABLE_REF_ERROR,
+    XML_XPATH_UNDEF_VARIABLE_ERROR,
+    XML_XPATH_INVALID_PREDICATE_ERROR,
+    XML_XPATH_EXPR_ERROR,
+    XML_XPATH_UNCLOSED_ERROR,
+    XML_XPATH_UNKNOWN_FUNC_ERROR,
+    XML_XPATH_INVALID_OPERAND,
+    XML_XPATH_INVALID_TYPE,
+    XML_XPATH_INVALID_ARITY,
+    XML_XPATH_INVALID_CTXT_SIZE,
+    XML_XPATH_INVALID_CTXT_POSITION,
+    XML_XPATH_MEMORY_ERROR,
+    XML_XPTR_SYNTAX_ERROR,
+    XML_XPTR_RESOURCE_ERROR,
+    XML_XPTR_SUB_RESOURCE_ERROR,
+    XML_XPATH_UNDEF_PREFIX_ERROR,
+    XML_XPATH_ENCODING_ERROR,
+    XML_XPATH_INVALID_CHAR_ERROR
 } xmlParserErrors;
 
 /**
@@ -389,7 +411,16 @@
  */
 typedef void (*xmlGenericErrorFunc) (void *ctx,
 				 const char *msg,
-				 ...);
+	 			 ...);
+/**
+ * xmlStructuredErrorFunc:
+ * @userData:  user provided data for the error callback
+ * @error:  the error being raised.
+ *
+ * Signature of the function to use when there is an error and
+ * the module handles the new error reporting mechanism.
+ */
+typedef void (*xmlStructuredErrorFunc) (void *userData, xmlErrorPtr error);
 
 /*
  * Use the following function to reset the two global variables
diff --git a/include/libxml/xpath.h b/include/libxml/xpath.h
index d7471df..dbd1b77 100644
--- a/include/libxml/xpath.h
+++ b/include/libxml/xpath.h
@@ -13,6 +13,7 @@
 #define __XML_XPATH_H__
 
 #include <libxml/xmlversion.h>
+#include <libxml/xmlerror.h>
 #include <libxml/tree.h>
 #include <libxml/hash.h>
 
@@ -253,6 +254,12 @@
     /* temporary namespace lists kept for walking the namespace axis */
     xmlNsPtr *tmpNsList;		/* Array of namespaces */
     int tmpNsNr;			/* number of namespace in scope */
+
+    /* error reporting mechanism */
+    void *userData;                     /* user specific data block */
+    xmlStructuredErrorFunc error;       /* the callback in case of errors */
+    xmlError lastError;			/* the last error */
+    xmlNodePtr debugNode;		/* the source node XSLT */
 };
 
 /*
diff --git a/include/libxml/xpathInternals.h b/include/libxml/xpathInternals.h
index 6b9e996..269edb8 100644
--- a/include/libxml/xpathInternals.h
+++ b/include/libxml/xpathInternals.h
@@ -250,8 +250,7 @@
  * Macro to raise an XPath error and return.
  */
 #define XP_ERROR(X)							\
-    { xmlXPatherror(ctxt, __FILE__, __LINE__, X);			\
-      ctxt->error = (X); return; }
+    { xmlXPathErr(ctxt, X); return; }
 
 /**
  * XP_ERROR0:
@@ -260,8 +259,7 @@
  * Macro to raise an XPath error and return 0.
  */
 #define XP_ERROR0(X)							\
-    { xmlXPatherror(ctxt, __FILE__, __LINE__, X);			\
-      ctxt->error = (X); return(0); }
+    { xmlXPathErr(ctxt, X); return(0); }
 
 /**
  * CHECK_TYPE:
@@ -377,6 +375,10 @@
 				 int line,
 				 int no);
 
+XMLPUBFUN void XMLCALL
+		xmlXPathErr	(xmlXPathParserContextPtr ctxt,
+				 int error);
+
 #ifdef LIBXML_DEBUG_ENABLED
 XMLPUBFUN void XMLCALL		
 		xmlXPathDebugDumpObject	(FILE *output,
diff --git a/parser.c b/parser.c
index e5ce1da..33fe5ee 100644
--- a/parser.c
+++ b/parser.c
@@ -2449,6 +2449,7 @@
     va_start(args, msg);
     ret = vsnprintf((char *) buf, len, (const char *) msg, args);
     va_end(args);
+    buf[len - 1] = 0; /* be safe ! */
     
     return(ret);
 }
diff --git a/result/VC/AttributeDefaultLegal b/result/VC/AttributeDefaultLegal
index 739c664..6b61686 100644
--- a/result/VC/AttributeDefaultLegal
+++ b/result/VC/AttributeDefaultLegal
@@ -7,6 +7,6 @@
 ./test/VC/AttributeDefaultLegal:8: validity error : Attribute doc of bad2: invalid default value
 <!ATTLIST doc bad2 IDREFS "abc:1 1abc_2">
                                         ^
-./test/VC/AttributeDefaultLegal:11: validity error : No declaration for attribute val of element doc
+./test/VC/AttributeDefaultLegal:11: element doc: validity error : No declaration for attribute val of element doc
 <doc val="v1"/>
              ^
diff --git a/result/VC/ElementValid2 b/result/VC/ElementValid2
index c78caff..db47c89 100644
--- a/result/VC/ElementValid2
+++ b/result/VC/ElementValid2
@@ -1,3 +1,3 @@
-./test/VC/ElementValid2:4: validity error : No declaration for element p
+./test/VC/ElementValid2:4: element p: validity error : No declaration for element p
 <doc><p/></doc>
          ^
diff --git a/result/VC/ElementValid3 b/result/VC/ElementValid3
index 02ffe0d..2fc236d 100644
--- a/result/VC/ElementValid3
+++ b/result/VC/ElementValid3
@@ -1,3 +1,3 @@
-./test/VC/ElementValid3:4: validity error : Element doc was declared EMPTY this one has content
+./test/VC/ElementValid3:4: element doc: validity error : Element doc was declared EMPTY this one has content
 <doc>Oops, this element was declared EMPTY</doc>
                                                 ^
diff --git a/result/VC/ElementValid4 b/result/VC/ElementValid4
index 00d737d..4791db5 100644
--- a/result/VC/ElementValid4
+++ b/result/VC/ElementValid4
@@ -1,3 +1,3 @@
-./test/VC/ElementValid4:7: validity error : Element c is not declared in doc list of possible children
+./test/VC/ElementValid4:7: element doc: validity error : Element c is not declared in doc list of possible children
 <doc> This <b>seems</b> Ok <a/> but this <c>was not declared</c></doc>
                                                                       ^
diff --git a/result/VC/ElementValid5 b/result/VC/ElementValid5
index 7dd5d7d..bd064f6 100644
--- a/result/VC/ElementValid5
+++ b/result/VC/ElementValid5
@@ -1,3 +1,3 @@
-./test/VC/ElementValid5:7: validity error : Element doc content does not follow the DTD, expecting (a , b* , c+), got (a b c b)
+./test/VC/ElementValid5:7: element doc: validity error : Element doc content does not follow the DTD, expecting (a , b* , c+), got (a b c b)
 <doc><a/><b> but this</b><c>was not declared</c><b>seems</b></doc>
                                                                   ^
diff --git a/result/VC/ElementValid6 b/result/VC/ElementValid6
index ff5f52f..1cbf8fd 100644
--- a/result/VC/ElementValid6
+++ b/result/VC/ElementValid6
@@ -1,3 +1,3 @@
-./test/VC/ElementValid6:7: validity error : Element doc content does not follow the DTD, expecting (a , b? , c+)?, got (a b)
+./test/VC/ElementValid6:7: element doc: validity error : Element doc content does not follow the DTD, expecting (a , b? , c+)?, got (a b)
 <doc><a/><b>lacks c</b></doc>
                              ^
diff --git a/result/VC/ElementValid7 b/result/VC/ElementValid7
index a800f90..4ce9dbf 100644
--- a/result/VC/ElementValid7
+++ b/result/VC/ElementValid7
@@ -1,3 +1,3 @@
-./test/VC/ElementValid7:7: validity error : Element doc content does not follow the DTD, expecting ((a | b)* , c+ , a , b? , c , a?), got (a b a c c a)
+./test/VC/ElementValid7:7: element doc: validity error : Element doc content does not follow the DTD, expecting ((a | b)* , c+ , a , b? , c , a?), got (a b a c c a)
 <doc><a/><b/><a/><c/><c/><a/></doc>
                                    ^
diff --git a/result/VC/Enumeration b/result/VC/Enumeration
index 394f576..30896fc 100644
--- a/result/VC/Enumeration
+++ b/result/VC/Enumeration
@@ -1,3 +1,3 @@
-./test/VC/Enumeration:5: validity error : Value "v4" for attribute val of doc is not among the enumerated set
+./test/VC/Enumeration:5: element doc: validity error : Value "v4" for attribute val of doc is not among the enumerated set
 <doc val="v4"></doc>
              ^
diff --git a/result/VC/NS2 b/result/VC/NS2
index ac095d3..abd1f88 100644
--- a/result/VC/NS2
+++ b/result/VC/NS2
@@ -1,3 +1,3 @@
-./test/VC/NS2:9: validity error : No declaration for attribute attr of element doc
+./test/VC/NS2:9: element doc: validity error : No declaration for attribute attr of element doc
 <ns:doc ns:attr="val" xmlns:ns="http://www.example.org/test/">
                                                              ^
diff --git a/result/VC/NS3 b/result/VC/NS3
index e798978..72c0117 100644
--- a/result/VC/NS3
+++ b/result/VC/NS3
@@ -1,9 +1,9 @@
-./test/VC/NS3:9: validity error : Value for attribute xmlns of foo is different from default "http://example.com/fooo"
+./test/VC/NS3:9: element foo: validity error : Value for attribute xmlns of foo is different from default "http://example.com/fooo"
 xmlns="http://example.com/foo" xmlns:foo="http://example.com/fo" foo:info="toto"
                                                                                ^
-./test/VC/NS3:9: validity error : Value for attribute xmlns of foo must be "http://example.com/fooo"
+./test/VC/NS3:9: element foo: validity error : Value for attribute xmlns of foo must be "http://example.com/fooo"
 xmlns="http://example.com/foo" xmlns:foo="http://example.com/fo" foo:info="toto"
                                                                                ^
-./test/VC/NS3:9: validity error : Element foo namespace name for default namespace does not match the DTD
+./test/VC/NS3:9: element foo: validity error : Element foo namespace name for default namespace does not match the DTD
 mlns="http://example.com/foo" xmlns:foo="http://example.com/fo" foo:info="toto"/
                                                                                ^
diff --git a/result/VC/OneID b/result/VC/OneID
index 422e87c..4a73cbe 100644
--- a/result/VC/OneID
+++ b/result/VC/OneID
@@ -1,7 +1,7 @@
 ./test/VC/OneID:4: validity error : Element doc has too may ID attributes defined : id
 <!ATTLIST doc id ID #IMPLIED>
                             ^
-Element doc has too many ID attributes defined : id
+./test/VC/OneID:0: validity error : Element doc has too many ID attributes defined : id
 ./test/VC/OneID:4: validity error : Element doc has 2 ID attribute defined in the internal subset : id
 <!ATTLIST doc id ID #IMPLIED>
                             ^
diff --git a/result/VC/OneID2 b/result/VC/OneID2
index 7dbd4bc..b46663b 100644
--- a/result/VC/OneID2
+++ b/result/VC/OneID2
@@ -1,7 +1,7 @@
 ./test/VC/OneID2:3: validity error : Element doc has too may ID attributes defined : id
 <!ATTLIST doc id ID #IMPLIED>
                             ^
-Element doc has too many ID attributes defined : id
+Entity: line 0: validity error : Element doc has too many ID attributes defined : id
 ./test/VC/OneID2:3: validity error : Element doc has 2 ID attribute defined in the internal subset : id
 <!ATTLIST doc id ID #IMPLIED>
                             ^
diff --git a/result/VC/OneID3 b/result/VC/OneID3
index 6c3041e..994051a 100644
--- a/result/VC/OneID3
+++ b/result/VC/OneID3
@@ -1,7 +1,7 @@
 test/VC/dtds/doc.dtd:2: validity error : Element doc has too may ID attributes defined : val
 <!ATTLIST doc val ID #IMPLIED>
                              ^
-Element doc has too many ID attributes defined : val
+./test/VC/OneID3:0: validity error : Element doc has too many ID attributes defined : val
 test/VC/dtds/doc.dtd:2: validity error : Element doc has 2 ID attribute defined in the external subset : val
 <!ATTLIST doc val ID #IMPLIED>
                              ^
diff --git a/result/noent/slashdot16.xml b/result/noent/slashdot16.xml
new file mode 100644
index 0000000..f4b168d
--- /dev/null
+++ b/result/noent/slashdot16.xml
Binary files differ
diff --git a/result/slashdot16.xml b/result/slashdot16.xml
new file mode 100644
index 0000000..f4b168d
--- /dev/null
+++ b/result/slashdot16.xml
Binary files differ
diff --git a/result/valid/rss.xml.err b/result/valid/rss.xml.err
index fd7b7d1..2ec7c9e 100644
--- a/result/valid/rss.xml.err
+++ b/result/valid/rss.xml.err
@@ -1,3 +1,3 @@
-./test/valid/rss.xml:177: validity error : Element rss does not carry attribute version
+./test/valid/rss.xml:177: element rss: validity error : Element rss does not carry attribute version
 </rss>
       ^
diff --git a/result/valid/xlink.xml.err b/result/valid/xlink.xml.err
index bf011c8..08c84bd 100644
--- a/result/valid/xlink.xml.err
+++ b/result/valid/xlink.xml.err
@@ -1,6 +1,6 @@
-./test/valid/xlink.xml:450: validity error : ID dt-arc already defined
+./test/valid/xlink.xml:450: element termdef: validity error : ID dt-arc already defined
 	<p><termdef id="dt-arc" term="Arc">An <term>arc</term> is contained within an e
 	                                  ^
-./test/valid/xlink.xml:530: validity error : IDREF attribute def references an unknown ID "dt-xlg"
+./test/valid/xlink.xml:530: element termref: validity error : IDREF attribute def references an unknown ID "dt-xlg"
 
 ^
diff --git a/threads.c b/threads.c
index b51caa2..63d50b0 100644
--- a/threads.c
+++ b/threads.c
@@ -336,7 +336,8 @@
 
 
 #ifdef HAVE_WIN32_THREADS
-#if !defined(HAVE_COMPILER_TLS) && defined(LIBXML_STATIC)
+#if !defined(HAVE_COMPILER_TLS)
+#if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
 typedef struct _xmlGlobalStateCleanupHelperParams
 {
     HANDLE thread;
@@ -352,7 +353,20 @@
     free(params);
     _endthread();
 }
-#endif /* HAVE_COMPILER_TLS && LIBXML_STATIC */
+#else /* LIBXML_STATIC && !LIBXML_STATIC_FOR_DLL */
+
+typedef struct _xmlGlobalStateCleanupHelperParams
+{
+    void *memory;
+    struct _xmlGlobalStateCleanupHelperParams * prev;
+    struct _xmlGlobalStateCleanupHelperParams * next;
+} xmlGlobalStateCleanupHelperParams;
+
+static xmlGlobalStateCleanupHelperParams * cleanup_helpers_head = NULL;
+static CRITICAL_SECTION cleanup_helpers_cs;
+
+#endif /* LIBXMLSTATIC && !LIBXML_STATIC_FOR_DLL */
+#endif /* HAVE_COMPILER_TLS */
 #endif /* HAVE_WIN32_THREADS */
 
 /**
@@ -387,23 +401,37 @@
     return &tlstate;
 #else /* HAVE_COMPILER_TLS */
     xmlGlobalState *globalval;
+    xmlGlobalStateCleanupHelperParams * p;
 
     if (run_once_init) { 
 	run_once_init = 0; 
 	xmlOnceInit(); 
     }
-    if ((globalval = (xmlGlobalState *) TlsGetValue(globalkey)) == NULL) {
+#if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
+    globalval = (xmlGlobalState *)TlsGetValue(globalkey);
+#else
+    p = (xmlGlobalStateCleanupHelperParams*)TlsGetValue(globalkey);
+    globalval = (xmlGlobalState *)(p ? p->memory : NULL);
+#endif
+    if (globalval == NULL) {
 	xmlGlobalState *tsd = xmlNewGlobalState();
-#if defined(LIBXML_STATIC)
-	xmlGlobalStateCleanupHelperParams *p = 
-	    (xmlGlobalStateCleanupHelperParams *) malloc(sizeof(xmlGlobalStateCleanupHelperParams));
+	p = (xmlGlobalStateCleanupHelperParams *) malloc(sizeof(xmlGlobalStateCleanupHelperParams));
 	p->memory = tsd;
+#if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
 	DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), 
 		GetCurrentProcess(), &p->thread, 0, TRUE, DUPLICATE_SAME_ACCESS);
-#endif
 	TlsSetValue(globalkey, tsd);
-#if defined(LIBXML_STATIC)
 	_beginthread(xmlGlobalStateCleanupHelper, 0, p);
+#else
+	EnterCriticalSection(&cleanup_helpers_cs);	
+        if (cleanup_helpers_head != NULL) {
+            cleanup_helpers_head->prev = p;
+        }
+	p->next = cleanup_helpers_head;
+	p->prev = NULL;
+	cleanup_helpers_head = p;
+	TlsSetValue(globalkey, p);
+	LeaveCriticalSection(&cleanup_helpers_cs);	
 #endif
 
 	return (tsd);
@@ -513,6 +541,9 @@
 #ifdef DEBUG_THREADS
     xmlGenericError(xmlGenericErrorContext, "xmlInitThreads()\n");
 #endif
+#if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS)
+    InitializeCriticalSection(&cleanup_helpers_cs);
+#endif
 }
 
 /**
@@ -527,6 +558,24 @@
 #ifdef DEBUG_THREADS
     xmlGenericError(xmlGenericErrorContext, "xmlCleanupThreads()\n");
 #endif
+#if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS)
+    if (globalkey != TLS_OUT_OF_INDEXES) {
+	xmlGlobalStateCleanupHelperParams * p;
+	EnterCriticalSection(&cleanup_helpers_cs);
+	p = cleanup_helpers_head;
+	while (p != NULL) {
+		xmlGlobalStateCleanupHelperParams * temp = p;
+		p = p->next;
+		xmlFreeGlobalState(temp->memory);
+		free(temp);
+	}
+	cleanup_helpers_head = 0;
+	LeaveCriticalSection(&cleanup_helpers_cs);
+	TlsFree(globalkey);
+	globalkey = TLS_OUT_OF_INDEXES;
+    }
+    DeleteCriticalSection(&cleanup_helpers_cs);
+#endif
 }
 
 #ifdef LIBXML_THREAD_ENABLED
@@ -566,27 +615,39 @@
  *
  * Returns TRUE always
  */
-#if defined(HAVE_WIN32_THREADS) && !defined(LIBXML_STATIC)
+#if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
+#if defined(LIBXML_STATIC_FOR_DLL)
+BOOL WINAPI xmlDllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 
+#else
 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 
+#endif
 {
     switch(fdwReason) {
     case DLL_THREAD_DETACH:
 	if (globalkey != TLS_OUT_OF_INDEXES) {
-	    xmlGlobalState *globalval = (xmlGlobalState *)TlsGetValue(globalkey);
-	    if (globalval) {
-		xmlFreeGlobalState(globalval);
-		TlsSetValue(globalkey, NULL);
+	    xmlGlobalState *globalval = NULL;
+	    xmlGlobalStateCleanupHelperParams * p =
+		(xmlGlobalStateCleanupHelperParams*)TlsGetValue(globalkey);
+	    globalval = (xmlGlobalState *)(p ? p->memory : NULL);
+            if (globalval) {
+                xmlFreeGlobalState(globalval);
+                TlsSetValue(globalkey,NULL);
+            }
+	    if (p)
+	    {
+		EnterCriticalSection(&cleanup_helpers_cs);
+                if (p == cleanup_helpers_head)
+		    cleanup_helpers_head = p->next;
+                else
+		    p->prev->next = p->next;
+                if (p->next != NULL)
+                    p->next->prev = p->prev;
+		LeaveCriticalSection(&cleanup_helpers_cs);
+		free(p);
 	    }
 	}
 	break;
-    case DLL_PROCESS_DETACH:
-	if (globalkey != TLS_OUT_OF_INDEXES) {
-	    TlsFree(globalkey);
-	    globalkey = TLS_OUT_OF_INDEXES;
-	}
-	break;
     }
     return TRUE;
 }
 #endif
-
diff --git a/xpath.c b/xpath.c
index 65ca180..605b588 100644
--- a/xpath.c
+++ b/xpath.c
@@ -52,6 +52,11 @@
 #include <libxml/threads.h>
 #include <libxml/globals.h>
 
+#define TODO 								\
+    xmlGenericError(xmlGenericErrorContext,				\
+	    "Unimplemented block at %s:%d\n",				\
+            __FILE__, __LINE__);
+
 #if defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_XPATH_ENABLED)
 /************************************************************************
  * 									*
@@ -165,6 +170,161 @@
 #endif
 
 /************************************************************************
+ *									*
+ *			Error handling routines				*
+ *									*
+ ************************************************************************/
+
+
+static const char *xmlXPathErrorMessages[] = {
+    "Ok\n",
+    "Number encoding\n",
+    "Unfinished literal\n",
+    "Start of literal\n",
+    "Expected $ for variable reference\n",
+    "Undefined variable\n",
+    "Invalid predicate\n",
+    "Invalid expression\n",
+    "Missing closing curly brace\n",
+    "Unregistered function\n",
+    "Invalid operand\n",
+    "Invalid type\n",
+    "Invalid number of arguments\n",
+    "Invalid context size\n",
+    "Invalid context position\n",
+    "Memory allocation error\n",
+    "Syntax error\n",
+    "Resource error\n",
+    "Sub resource error\n",
+    "Undefined namespace prefix\n",
+    "Encoding error\n",
+    "Char out of XML range\n"
+};
+
+
+/**
+ * xmlXPathErrMemory:
+ * @ctxt:  an XPath context
+ * @extra:  extra informations
+ *
+ * Handle a redefinition of attribute error
+ */
+static void
+xmlXPathErrMemory(xmlXPathContextPtr ctxt, const char *extra)
+{
+    if (ctxt != NULL) {
+        if (extra) {
+            xmlChar buf[200];
+
+            xmlStrPrintf(buf, 200,
+                         BAD_CAST "Memory allocation failed : %s\n",
+                         extra);
+            ctxt->lastError.message = (char *) xmlStrdup(buf);
+        } else {
+            ctxt->lastError.message = (char *)
+	       xmlStrdup(BAD_CAST "Memory allocation failed\n");
+        }
+        ctxt->lastError.domain = XML_FROM_XPATH;
+        ctxt->lastError.code = XML_ERR_NO_MEMORY;
+	if (ctxt->error != NULL)
+	    ctxt->error(ctxt->userData, &ctxt->lastError);
+    } else {
+        if (extra)
+            __xmlRaiseError(NULL, NULL,
+                            NULL, NULL, XML_FROM_XPATH,
+                            XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0,
+                            extra, NULL, NULL, 0, 0,
+                            "Memory allocation failed : %s\n", extra);
+        else
+            __xmlRaiseError(NULL, NULL,
+                            NULL, NULL, XML_FROM_XPATH,
+                            XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0,
+                            NULL, NULL, NULL, 0, 0,
+                            "Memory allocation failed\n");
+    }
+}
+
+/**
+ * xmlXPathErrMemory:
+ * @ctxt:  an XPath parser context
+ * @extra:  extra informations
+ *
+ * Handle a redefinition of attribute error
+ */
+static void
+xmlXPathPErrMemory(xmlXPathParserContextPtr ctxt, const char *extra)
+{
+    ctxt->error = XPATH_MEMORY_ERROR;
+    if (ctxt == NULL)
+	xmlXPathErrMemory(NULL, extra);
+    else
+	xmlXPathErrMemory(ctxt->context, extra);
+}
+
+/**
+ * xmlXPathErr:
+ * @ctxt:  a XPath parser context
+ * @node:  the node raising the error
+ * @error:  the error code
+ * @msg:  message
+ * @str1:  extra info
+ * @str2:  extra info
+ *
+ * Handle a Relax NG Parsing error
+ */
+void
+xmlXPathErr(xmlXPathParserContextPtr ctxt, int error)
+{
+    if (ctxt != NULL)
+        ctxt->error = error;
+    if ((ctxt == NULL) || (ctxt->context == NULL)) {
+	__xmlRaiseError(NULL, NULL,
+			NULL, NULL, XML_FROM_XPATH,
+			error + XML_XPATH_EXPRESSION_OK - XPATH_EXPRESSION_OK,
+			XML_ERR_ERROR, NULL, 0,
+			NULL, NULL, NULL, 0, 0,
+			xmlXPathErrorMessages[error]);
+	return;
+    }
+    ctxt->context->lastError.domain = XML_FROM_XPATH;
+    ctxt->context->lastError.code = error + XML_XPATH_EXPRESSION_OK -
+                           XPATH_EXPRESSION_OK;
+    ctxt->context->lastError.level = XML_ERR_FATAL;
+    ctxt->context->lastError.str1 = (char *) xmlStrdup(ctxt->base);
+    ctxt->context->lastError.int1 = ctxt->cur - ctxt->base;
+    ctxt->context->lastError.node = ctxt->context->debugNode;
+    if (ctxt->context->error != NULL) {
+	ctxt->context->error(ctxt->context->userData,
+	                     &ctxt->context->lastError);
+    } else {
+	__xmlRaiseError(NULL, NULL,
+			NULL, ctxt->context->debugNode, XML_FROM_XPATH,
+			error + XML_XPATH_EXPRESSION_OK - XPATH_EXPRESSION_OK,
+			XML_ERR_ERROR, NULL, 0,
+			(const char *) ctxt->base, NULL, NULL,
+			ctxt->cur - ctxt->base, 0,
+			xmlXPathErrorMessages[error]);
+    }
+
+}
+
+/**
+ * xmlXPatherror:
+ * @ctxt:  the XPath Parser context
+ * @file:  the file name
+ * @line:  the line number
+ * @no:  the error number
+ *
+ * Formats an error message.
+ */
+void
+xmlXPatherror(xmlXPathParserContextPtr ctxt, const char *file ATTRIBUTE_UNUSED,
+              int line ATTRIBUTE_UNUSED, int no) {
+    xmlXPathErr(ctxt, no);
+}
+
+
+/************************************************************************
  * 									*
  * 			Parser Types					*
  * 									*
@@ -278,8 +438,7 @@
 
     cur = (xmlXPathCompExprPtr) xmlMalloc(sizeof(xmlXPathCompExpr));
     if (cur == NULL) {
-        xmlGenericError(xmlGenericErrorContext,
-		"xmlXPathNewCompExpr : malloc failed\n");
+        xmlXPathErrMemory(NULL, "allocating component\n");
 	return(NULL);
     }
     memset(cur, 0, sizeof(xmlXPathCompExpr));
@@ -288,8 +447,7 @@
     cur->steps = (xmlXPathStepOp *) xmlMalloc(cur->maxStep *
 	                                   sizeof(xmlXPathStepOp));
     if (cur->steps == NULL) {
-        xmlGenericError(xmlGenericErrorContext,
-		"xmlXPathNewCompExpr : malloc failed\n");
+        xmlXPathErrMemory(NULL, "allocating steps\n");
 	xmlFree(cur);
 	return(NULL);
     }
@@ -369,8 +527,7 @@
 		                      comp->maxStep * sizeof(xmlXPathStepOp));
 	if (real == NULL) {
 	    comp->maxStep /= 2;
-	    xmlGenericError(xmlGenericErrorContext,
-		    "xmlXPathCompExprAdd : realloc failed\n");
+	    xmlXPathErrMemory(NULL, "adding step\n");
 	    return(-1);
 	}
 	comp->steps = real;
@@ -436,11 +593,6 @@
  *									*
  ************************************************************************/
 
-#define TODO 								\
-    xmlGenericError(xmlGenericErrorContext,				\
-	    "Unimplemented block at %s:%d\n",				\
-            __FILE__, __LINE__);
-
 #define STRANGE 							\
     xmlGenericError(xmlGenericErrorContext,				\
 	    "Internal error at %s:%d\n",				\
@@ -1247,96 +1399,6 @@
     }
 }
 
-/************************************************************************
- *									*
- *			Error handling routines				*
- *									*
- ************************************************************************/
-
-
-static const char *xmlXPathErrorMessages[] = {
-    "Ok",
-    "Number encoding",
-    "Unfinished literal",
-    "Start of literal",
-    "Expected $ for variable reference",
-    "Undefined variable",
-    "Invalid predicate",
-    "Invalid expression",
-    "Missing closing curly brace",
-    "Unregistered function",
-    "Invalid operand",
-    "Invalid type",
-    "Invalid number of arguments",
-    "Invalid context size",
-    "Invalid context position",
-    "Memory allocation error",
-    "Syntax error",
-    "Resource error",
-    "Sub resource error",
-    "Undefined namespace prefix",
-    "Encoding error",
-    "Char out of XML range"
-};
-
-/**
- * xmlXPatherror:
- * @ctxt:  the XPath Parser context
- * @file:  the file name
- * @line:  the line number
- * @no:  the error number
- *
- * Formats an error message.
- */
-void
-xmlXPatherror(xmlXPathParserContextPtr ctxt, const char *file ATTRIBUTE_UNUSED,
-              int line ATTRIBUTE_UNUSED, int no) {
-    int n;
-    const xmlChar *cur;
-    const xmlChar *base;
-
-    cur = ctxt->cur;
-    base = ctxt->base;
-    if ((cur == NULL) || (base == NULL)) {
-	if ((ctxt->comp != NULL) && (ctxt->comp->expr != NULL)) {
-	    xmlGenericError(xmlGenericErrorContext,
-		    "XPath error %s in %s\n", xmlXPathErrorMessages[no],
-			    ctxt->comp->expr);
-	} else {
-	    xmlGenericError(xmlGenericErrorContext,
-		    "XPath error %s\n", xmlXPathErrorMessages[no]);
-	}
-
-	return;
-    }
-    xmlGenericError(xmlGenericErrorContext,
-	    "XPath error %s\n", xmlXPathErrorMessages[no]);
-
-    while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
-	cur--;
-    }
-    n = 0;
-    while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
-        cur--;
-    if ((*cur == '\n') || (*cur == '\r')) cur++;
-    base = cur;
-    n = 0;
-    while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
-        xmlGenericError(xmlGenericErrorContext, "%c", (unsigned char) *cur++);
-	n++;
-    }
-    xmlGenericError(xmlGenericErrorContext, "\n");
-    cur = ctxt->cur;
-    while ((*cur == '\n') || (*cur == '\r'))
-	cur--;
-    n = 0;
-    while ((cur != base) && (n++ < 80)) {
-        xmlGenericError(xmlGenericErrorContext, " ");
-        base++;
-    }
-    xmlGenericError(xmlGenericErrorContext,"^\n");
-}
-
 
 /************************************************************************
  *									*
@@ -1564,8 +1626,7 @@
      */
     cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
     if (cur == NULL) {
-        xmlGenericError(xmlGenericErrorContext,
-		"xmlXPathNodeSetDupNs : malloc failed\n");
+        xmlXPathErrMemory(NULL, "duplicating namespace\n");
 	return(NULL);
     }
     memset(cur, 0, sizeof(xmlNs));
@@ -1614,8 +1675,7 @@
 
     ret = (xmlNodeSetPtr) xmlMalloc(sizeof(xmlNodeSet));
     if (ret == NULL) {
-        xmlGenericError(xmlGenericErrorContext,
-		"xmlXPathNodeSetCreate: out of memory\n");
+        xmlXPathErrMemory(NULL, "creating nodeset\n");
 	return(NULL);
     }
     memset(ret, 0 , (size_t) sizeof(xmlNodeSet));
@@ -1623,8 +1683,8 @@
         ret->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
 					     sizeof(xmlNodePtr));
 	if (ret->nodeTab == NULL) {
-	    xmlGenericError(xmlGenericErrorContext,
-		    "xmlXPathNodeSetCreate: out of memory\n");
+	    xmlXPathErrMemory(NULL, "creating nodeset\n");
+	    xmlFree(ret);
 	    return(NULL);
 	}
 	memset(ret->nodeTab, 0 ,
@@ -1712,8 +1772,7 @@
         cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
 					     sizeof(xmlNodePtr));
 	if (cur->nodeTab == NULL) {
-	    xmlGenericError(xmlGenericErrorContext,
-		    "xmlXPathNodeSetAdd: out of memory\n");
+	    xmlXPathErrMemory(NULL, "growing nodeset\n");
 	    return;
 	}
 	memset(cur->nodeTab, 0 ,
@@ -1726,8 +1785,7 @@
 	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
 				      sizeof(xmlNodePtr));
 	if (temp == NULL) {
-	    xmlGenericError(xmlGenericErrorContext,
-		    "xmlXPathNodeSetAdd: out of memory\n");
+	    xmlXPathErrMemory(NULL, "growing nodeset\n");
 	    return;
 	}
 	cur->nodeTab = temp;
@@ -1767,8 +1825,7 @@
         cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
 					     sizeof(xmlNodePtr));
 	if (cur->nodeTab == NULL) {
-	    xmlGenericError(xmlGenericErrorContext,
-		    "xmlXPathNodeSetAdd: out of memory\n");
+	    xmlXPathErrMemory(NULL, "growing nodeset\n");
 	    return;
 	}
 	memset(cur->nodeTab, 0 ,
@@ -1781,8 +1838,7 @@
 	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
 				      sizeof(xmlNodePtr));
 	if (temp == NULL) {
-	    xmlGenericError(xmlGenericErrorContext,
-		    "xmlXPathNodeSetAdd: out of memory\n");
+	    xmlXPathErrMemory(NULL, "growing nodeset\n");
 	    return;
 	}
 	cur->nodeTab = temp;
@@ -1821,8 +1877,7 @@
         cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
 					     sizeof(xmlNodePtr));
 	if (cur->nodeTab == NULL) {
-	    xmlGenericError(xmlGenericErrorContext,
-		    "xmlXPathNodeSetAddUnique: out of memory\n");
+	    xmlXPathErrMemory(NULL, "growing nodeset\n");
 	    return;
 	}
 	memset(cur->nodeTab, 0 ,
@@ -1835,8 +1890,7 @@
 	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
 				      sizeof(xmlNodePtr));
 	if (temp == NULL) {
-	    xmlGenericError(xmlGenericErrorContext,
-		    "xmlXPathNodeSetAddUnique: out of memory\n");
+	    xmlXPathErrMemory(NULL, "growing nodeset\n");
 	    return;
 	}
 	cur->nodeTab = temp;
@@ -1903,8 +1957,7 @@
 	    val1->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
 						    sizeof(xmlNodePtr));
 	    if (val1->nodeTab == NULL) {
-		xmlGenericError(xmlGenericErrorContext,
-				"xmlXPathNodeSetMerge: out of memory\n");
+	        xmlXPathErrMemory(NULL, "merging nodeset\n");
 		return(NULL);
 	    }
 	    memset(val1->nodeTab, 0 ,
@@ -1917,8 +1970,7 @@
 	    temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax *
 					     sizeof(xmlNodePtr));
 	    if (temp == NULL) {
-		xmlGenericError(xmlGenericErrorContext,
-				"xmlXPathNodeSetMerge: out of memory\n");
+	        xmlXPathErrMemory(NULL, "merging nodeset\n");
 		return(NULL);
 	    }
 	    val1->nodeTab = temp;
@@ -1964,8 +2016,7 @@
 	    val1->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
 						    sizeof(xmlNodePtr));
 	    if (val1->nodeTab == NULL) {
-		xmlGenericError(xmlGenericErrorContext,
-				"xmlXPathNodeSetMerge: out of memory\n");
+	        xmlXPathErrMemory(NULL, "merging nodeset\n");
 		return(NULL);
 	    }
 	    memset(val1->nodeTab, 0 ,
@@ -1978,8 +2029,7 @@
 	    temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax *
 					     sizeof(xmlNodePtr));
 	    if (temp == NULL) {
-		xmlGenericError(xmlGenericErrorContext,
-				"xmlXPathNodeSetMerge: out of memory\n");
+	        xmlXPathErrMemory(NULL, "merging nodeset\n");
 		return(NULL);
 	    }
 	    val1->nodeTab = temp;
@@ -2159,8 +2209,7 @@
 
     ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
     if (ret == NULL) {
-        xmlGenericError(xmlGenericErrorContext,
-		"xmlXPathNewNodeSet: out of memory\n");
+        xmlXPathErrMemory(NULL, "creating nodeset\n");
 	return(NULL);
     }
     memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
@@ -2186,8 +2235,7 @@
 
     ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
     if (ret == NULL) {
-        xmlGenericError(xmlGenericErrorContext,
-		"xmlXPathNewNodeSet: out of memory\n");
+        xmlXPathErrMemory(NULL, "creating result value tree\n");
 	return(NULL);
     }
     memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
@@ -2240,8 +2288,7 @@
 
     ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
     if (ret == NULL) {
-        xmlGenericError(xmlGenericErrorContext,
-		"xmlXPathWrapNodeSet: out of memory\n");
+        xmlXPathErrMemory(NULL, "creating node set object\n");
 	return(NULL);
     }
     memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
@@ -3007,8 +3054,7 @@
 
     ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
     if (ret == NULL) {
-        xmlGenericError(xmlGenericErrorContext,
-		"xmlXPathNewFloat: out of memory\n");
+        xmlXPathErrMemory(NULL, "creating float object\n");
 	return(NULL);
     }
     memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
@@ -3031,8 +3077,7 @@
 
     ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
     if (ret == NULL) {
-        xmlGenericError(xmlGenericErrorContext,
-		"xmlXPathNewBoolean: out of memory\n");
+        xmlXPathErrMemory(NULL, "creating boolean object\n");
 	return(NULL);
     }
     memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
@@ -3055,8 +3100,7 @@
 
     ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
     if (ret == NULL) {
-        xmlGenericError(xmlGenericErrorContext,
-		"xmlXPathNewString: out of memory\n");
+        xmlXPathErrMemory(NULL, "creating string object\n");
 	return(NULL);
     }
     memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
@@ -3082,8 +3126,7 @@
 
     ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
     if (ret == NULL) {
-        xmlGenericError(xmlGenericErrorContext,
-		"xmlXPathWrapString: out of memory\n");
+        xmlXPathErrMemory(NULL, "creating string object\n");
 	return(NULL);
     }
     memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
@@ -3106,8 +3149,7 @@
 
     ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
     if (ret == NULL) {
-        xmlGenericError(xmlGenericErrorContext,
-		"xmlXPathNewCString: out of memory\n");
+        xmlXPathErrMemory(NULL, "creating string object\n");
 	return(NULL);
     }
     memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
@@ -3143,8 +3185,7 @@
 
     ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
     if (ret == NULL) {
-        xmlGenericError(xmlGenericErrorContext,
-		"xmlXPathWrapExternal: out of memory\n");
+        xmlXPathErrMemory(NULL, "creating user object\n");
 	return(NULL);
     }
     memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
@@ -3170,8 +3211,7 @@
 
     ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
     if (ret == NULL) {
-        xmlGenericError(xmlGenericErrorContext,
-		"xmlXPathObjectCopy: out of memory\n");
+        xmlXPathErrMemory(NULL, "copying object\n");
 	return(NULL);
     }
     memcpy(ret, val , (size_t) sizeof(xmlXPathObject));
@@ -3722,8 +3762,7 @@
 
     ret = (xmlXPathContextPtr) xmlMalloc(sizeof(xmlXPathContext));
     if (ret == NULL) {
-        xmlGenericError(xmlGenericErrorContext,
-		"xmlXPathNewContext: out of memory\n");
+        xmlXPathErrMemory(NULL, "creating context\n");
 	return(NULL);
     }
     memset(ret, 0 , (size_t) sizeof(xmlXPathContext));
@@ -3814,8 +3853,7 @@
 
     ret = (xmlXPathParserContextPtr) xmlMalloc(sizeof(xmlXPathParserContext));
     if (ret == NULL) {
-        xmlGenericError(xmlGenericErrorContext,
-		"xmlXPathNewParserContext: out of memory\n");
+        xmlXPathErrMemory(ctxt, "creating parser context\n");
 	return(NULL);
     }
     memset(ret, 0 , (size_t) sizeof(xmlXPathParserContext));
@@ -3847,8 +3885,7 @@
 
     ret = (xmlXPathParserContextPtr) xmlMalloc(sizeof(xmlXPathParserContext));
     if (ret == NULL) {
-        xmlGenericError(xmlGenericErrorContext,
-		"xmlXPathCompParserContext: out of memory\n");
+        xmlXPathErrMemory(ctxt, "creating evaluation context\n");
 	return(NULL);
     }
     memset(ret, 0 , (size_t) sizeof(xmlXPathParserContext));
@@ -3858,8 +3895,7 @@
                      xmlMalloc(10 * sizeof(xmlXPathObjectPtr));
     if (ret->valueTab == NULL) {
 	xmlFree(ret);
-        xmlGenericError(xmlGenericErrorContext,
-		"xmlXPathCompParserContext: out of memory\n");
+	xmlXPathErrMemory(ctxt, "creating evaluation context\n");
 	return(NULL);
     }
     ret->valueNr = 0;
@@ -4210,6 +4246,7 @@
 
     values2 = (double *) xmlMalloc(ns2->nodeNr * sizeof(double));
     if (values2 == NULL) {
+        xmlXPathErrMemory(NULL, "comparing nodesets\n");
 	xmlXPathFreeObject(arg1);
 	xmlXPathFreeObject(arg2);
 	return(0);
@@ -4460,22 +4497,27 @@
 		    return(1);
 
     values1 = (xmlChar **) xmlMalloc(ns1->nodeNr * sizeof(xmlChar *));
-    if (values1 == NULL)
+    if (values1 == NULL) {
+        xmlXPathErrMemory(NULL, "comparing nodesets\n");
 	return(0);
+    }
     hashs1 = (unsigned int *) xmlMalloc(ns1->nodeNr * sizeof(unsigned int));
     if (hashs1 == NULL) {
+        xmlXPathErrMemory(NULL, "comparing nodesets\n");
 	xmlFree(values1);
 	return(0);
     }
     memset(values1, 0, ns1->nodeNr * sizeof(xmlChar *));
     values2 = (xmlChar **) xmlMalloc(ns2->nodeNr * sizeof(xmlChar *));
     if (values2 == NULL) {
+        xmlXPathErrMemory(NULL, "comparing nodesets\n");
 	xmlFree(hashs1);
 	xmlFree(values1);
 	return(0);
     }
     hashs2 = (unsigned int *) xmlMalloc(ns2->nodeNr * sizeof(unsigned int));
     if (hashs2 == NULL) {
+        xmlXPathErrMemory(NULL, "comparing nodesets\n");
 	xmlFree(hashs1);
 	xmlFree(values1);
 	xmlFree(values2);
@@ -10608,6 +10650,7 @@
 	ctxt->valueTab = (xmlXPathObjectPtr *) 
 			 xmlMalloc(10 * sizeof(xmlXPathObjectPtr));
 	if (ctxt->valueTab == NULL) {
+	    xmlXPathPErrMemory(ctxt, "creating evaluation context\n");
 	    xmlFree(ctxt);
 	}
 	ctxt->valueNr = 0;