patch from Stéphane Bidoul for setting up threads global defaults. this

* build_glob.py global.data globals.c parser.c
  include/libxml/globals.h: patch from Stéphane Bidoul for setting
  up threads global defaults.
* doc/libxml2-api.xml: this extends the API with new functions
* python/tests/Makefile.am python/tests/reader2.py
  python/tests/thread2.py: integrated the associated testcase and
  fixed the error string used in reader2
Daniel
diff --git a/globals.c b/globals.c
index 0fc54e2..ee6417b 100644
--- a/globals.c
+++ b/globals.c
@@ -21,6 +21,7 @@
 
 #include <libxml/globals.h>
 #include <libxml/xmlmemory.h>
+#include <libxml/threads.h>
 
 /* #define DEBUG_GLOBALS */
 
@@ -33,6 +34,21 @@
 #define IS_MAIN_THREAD 1
 #endif
 
+/*
+ * Mutex to protect "ForNewThreads" variables
+ */
+static xmlMutexPtr xmlThrDefMutex = NULL;
+
+void xmlInitGlobals()
+{
+    xmlThrDefMutex = xmlNewMutex();
+}
+
+void xmlCleanupGlobals()
+{
+    xmlFreeMutex(xmlThrDefMutex);
+}
+
 /************************************************************************
  * 									*
  *	All the user accessible global variables of the library		*
@@ -150,12 +166,14 @@
  * XML_BUFFER_ALLOC_EXACT
  */
 xmlBufferAllocationScheme xmlBufferAllocScheme = XML_BUFFER_ALLOC_EXACT;
+static xmlBufferAllocationScheme xmlBufferAllocSchemeThrDef = XML_BUFFER_ALLOC_EXACT;
 /**
  * xmlDefaultBufferSize:
  *
  * Global setting, default buffer size. Default value is BASE_BUFFER_SIZE
  */
 int xmlDefaultBufferSize = BASE_BUFFER_SIZE;
+static int xmlDefaultBufferSizeThrDef = BASE_BUFFER_SIZE;
 
 /*
  * Parser defaults
@@ -175,6 +193,7 @@
  * Disabled by default
  */
 int xmlParserDebugEntities = 0;
+static int xmlParserDebugEntitiesThrDef = 0;
 /**
  * xmlDoValidityCheckingDefaultValue:
  *
@@ -182,6 +201,7 @@
  * Disabled by default.
  */
 int xmlDoValidityCheckingDefaultValue = 0;
+static int xmlDoValidityCheckingDefaultValueThrDef = 0;
 /**
  * xmlGetWarningsDefaultValue:
  *
@@ -189,6 +209,7 @@
  * Activated by default.
  */
 int xmlGetWarningsDefaultValue = 1;
+static int xmlGetWarningsDefaultValueThrDef = 1;
 /**
  * xmlLoadExtDtdDefaultValue:
  *
@@ -197,6 +218,7 @@
  * Disabled by default.
  */
 int xmlLoadExtDtdDefaultValue = 0;
+static int xmlLoadExtDtdDefaultValueThrDef = 0;
 /**
  * xmlPedanticParserDefaultValue:
  *
@@ -204,6 +226,7 @@
  * Disabled by default.
  */
 int xmlPedanticParserDefaultValue = 0;
+static int xmlPedanticParserDefaultValueThrDef = 0;
 /**
  * xmlLineNumbersDefaultValue:
  *
@@ -213,6 +236,7 @@
  * applicaton.
  */
 int xmlLineNumbersDefaultValue = 0;
+static int xmlLineNumbersDefaultValueThrDef = 0;
 /**
  * xmlKeepBlanksDefaultValue:
  *
@@ -223,6 +247,7 @@
  * for some applications since this was libxml1 default behaviour.
  */
 int xmlKeepBlanksDefaultValue = 1;
+static int xmlKeepBlanksDefaultValueThrDef = 1;
 /**
  * xmlSubstituteEntitiesDefaultValue:
  *
@@ -233,9 +258,12 @@
  * engine does not handle entities references transparently.
  */
 int xmlSubstituteEntitiesDefaultValue = 0;
+static int xmlSubstituteEntitiesDefaultValueThrDef = 0;
 
 xmlRegisterNodeFunc xmlRegisterNodeDefaultValue = NULL;
+static xmlRegisterNodeFunc xmlRegisterNodeDefaultValueThrDef = NULL;
 xmlDeregisterNodeFunc xmlDeregisterNodeDefaultValue = NULL;
+static xmlDeregisterNodeFunc xmlDeregisterNodeDefaultValueThrDef = NULL;
 
 /*
  * Error handling
@@ -252,12 +280,14 @@
  * Global setting: function used for generic error callbacks
  */
 xmlGenericErrorFunc xmlGenericError = xmlGenericErrorDefaultFunc;
+static xmlGenericErrorFunc xmlGenericErrorThrDef = xmlGenericErrorDefaultFunc;
 /**
  * xmlGenericErrorContext:
  *
  * Global setting passed to generic error callbacks
  */
 void *xmlGenericErrorContext = NULL;
+static void *xmlGenericErrorContextThrDef = NULL;
 
 /*
  * output defaults
@@ -269,6 +299,7 @@
  * Enabled by default
  */
 int xmlIndentTreeOutput = 1;
+static int xmlIndentTreeOutputThrDef = 1;
 
 /**
  * xmlTreeIndentString:
@@ -276,6 +307,7 @@
  * The string used to do one-level indent. By default is equal to "  " (two spaces)
  */
 const char *xmlTreeIndentString = "  ";
+static const char *xmlTreeIndentStringThrDef = "  ";
 
 /**
  * xmlSaveNoEmptyTags:
@@ -286,6 +318,7 @@
  * Disabled by default
  */
 int xmlSaveNoEmptyTags = 0;
+int xmlSaveNoEmptyTagsThrDef = 0;
 
 /**
  * xmlDefaultSAXHandler:
@@ -427,6 +460,7 @@
     /*
      * Perform initialization as required by libxml
      */
+    xmlMutexLock(xmlThrDefMutex);
 
 #ifdef LIBXML_DOCB_ENABLED
     initdocbDefaultSAXHandler(&gs->docbDefaultSAXHandler);
@@ -434,17 +468,17 @@
 #ifdef LIBXML_HTML_ENABLED
     inithtmlDefaultSAXHandler(&gs->htmlDefaultSAXHandler);
 #endif
-    initGenericErrorDefaultFunc(&gs->xmlGenericError);
 
     gs->oldXMLWDcompatibility = 0;
-    gs->xmlBufferAllocScheme = XML_BUFFER_ALLOC_EXACT;
-    gs->xmlDefaultBufferSize = BASE_BUFFER_SIZE;
+    gs->xmlBufferAllocScheme = xmlBufferAllocSchemeThrDef;
+    gs->xmlDefaultBufferSize = xmlDefaultBufferSizeThrDef;
     initxmlDefaultSAXHandler(&gs->xmlDefaultSAXHandler, 1);
     gs->xmlDefaultSAXLocator.getPublicId = getPublicId;
     gs->xmlDefaultSAXLocator.getSystemId = getSystemId;
     gs->xmlDefaultSAXLocator.getLineNumber = getLineNumber;
     gs->xmlDefaultSAXLocator.getColumnNumber = getColumnNumber;
-    gs->xmlDoValidityCheckingDefaultValue = 0;
+    gs->xmlDoValidityCheckingDefaultValue = 
+         xmlDoValidityCheckingDefaultValueThrDef;
 #if defined(DEBUG_MEMORY_LOCATION) | defined(DEBUG_MEMORY)
     gs->xmlFree = (xmlFreeFunc) xmlMemFree;
     gs->xmlMalloc = (xmlMallocFunc) xmlMemMalloc;
@@ -458,21 +492,36 @@
     gs->xmlRealloc = (xmlReallocFunc) realloc;
     gs->xmlMemStrdup = (xmlStrdupFunc) xmlStrdup;
 #endif
-    gs->xmlGenericErrorContext = NULL;
-    gs->xmlGetWarningsDefaultValue = 1;
-    gs->xmlIndentTreeOutput = 1;
-    gs->xmlTreeIndentString = "  ";
-    gs->xmlKeepBlanksDefaultValue = 1;
-    gs->xmlLineNumbersDefaultValue = 0;
-    gs->xmlLoadExtDtdDefaultValue = 0;
-    gs->xmlParserDebugEntities = 0;
+    gs->xmlGetWarningsDefaultValue = xmlGetWarningsDefaultValueThrDef;
+    gs->xmlIndentTreeOutput = xmlIndentTreeOutputThrDef;
+    gs->xmlTreeIndentString = xmlTreeIndentStringThrDef;
+    gs->xmlKeepBlanksDefaultValue = xmlKeepBlanksDefaultValueThrDef;
+    gs->xmlLineNumbersDefaultValue = xmlLineNumbersDefaultValueThrDef;
+    gs->xmlLoadExtDtdDefaultValue = xmlLoadExtDtdDefaultValueThrDef;
+    gs->xmlParserDebugEntities = xmlParserDebugEntitiesThrDef;
     gs->xmlParserVersion = LIBXML_VERSION_STRING;
-    gs->xmlPedanticParserDefaultValue = 0;
-    gs->xmlSaveNoEmptyTags = 0;
-    gs->xmlSubstituteEntitiesDefaultValue = 0;
+    gs->xmlPedanticParserDefaultValue = xmlPedanticParserDefaultValueThrDef;
+    gs->xmlSaveNoEmptyTags = xmlSaveNoEmptyTagsThrDef;
+    gs->xmlSubstituteEntitiesDefaultValue = 
+        xmlSubstituteEntitiesDefaultValueThrDef;
 
-    gs->xmlRegisterNodeDefaultValue = NULL;
-    gs->xmlDeregisterNodeDefaultValue = NULL;
+    gs->xmlGenericError = xmlGenericErrorThrDef;
+    gs->xmlGenericErrorContext = xmlGenericErrorContextThrDef;
+    gs->xmlRegisterNodeDefaultValue = xmlRegisterNodeDefaultValueThrDef;
+    gs->xmlDeregisterNodeDefaultValue = xmlDeregisterNodeDefaultValueThrDef;
+
+    xmlMutexUnlock(xmlThrDefMutex);
+}
+
+void
+xmlThrDefSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc handler) {
+    xmlMutexLock(xmlThrDefMutex);
+    xmlGenericErrorContextThrDef = ctx;
+    if (handler != NULL)
+	xmlGenericErrorThrDef = handler;
+    else
+	xmlGenericErrorThrDef = xmlGenericErrorDefaultFunc;
+    xmlMutexUnlock(xmlThrDefMutex);
 }
 
 /**
@@ -493,6 +542,21 @@
     return(old);
 }
 
+xmlRegisterNodeFunc
+xmlThrDefRegisterNodeDefault(xmlRegisterNodeFunc func)
+{
+    xmlRegisterNodeFunc old;
+    
+    xmlMutexLock(xmlThrDefMutex);
+    old = xmlRegisterNodeDefaultValueThrDef;
+    
+    __xmlRegisterCallbacks = 1;
+    xmlRegisterNodeDefaultValueThrDef = func;
+    xmlMutexUnlock(xmlThrDefMutex);
+
+    return(old);
+}
+
 /**
  * xmlDeregisterNodeDefault:
  * @func: function pointer to the new DeregisterNodeFunc
@@ -511,6 +575,21 @@
     return(old);
 }
 
+xmlDeregisterNodeFunc
+xmlThrDefDeregisterNodeDefault(xmlDeregisterNodeFunc func)
+{
+    xmlDeregisterNodeFunc old;
+
+    xmlMutexLock(xmlThrDefMutex);
+    old = xmlDeregisterNodeDefaultValueThrDef;
+    
+    __xmlRegisterCallbacks = 1;
+    xmlDeregisterNodeDefaultValueThrDef = func;
+    xmlMutexUnlock(xmlThrDefMutex);
+
+    return(old);
+}
+
 
 #ifdef LIBXML_DOCB_ENABLED
 #undef	docbDefaultSAXHandler
@@ -558,6 +637,14 @@
     else
 	return (&xmlGetGlobalState()->xmlBufferAllocScheme);
 }
+xmlBufferAllocationScheme xmlThrDefBufferAllocScheme(xmlBufferAllocationScheme v) {
+    xmlBufferAllocationScheme ret;
+    xmlMutexLock(xmlThrDefMutex);
+    ret = xmlBufferAllocSchemeThrDef;
+    xmlBufferAllocSchemeThrDef = v;
+    xmlMutexUnlock(xmlThrDefMutex);
+    return ret;
+}
 
 #undef	xmlDefaultBufferSize
 int *
@@ -567,6 +654,14 @@
     else
 	return (&xmlGetGlobalState()->xmlDefaultBufferSize);
 }
+int xmlThrDefDefaultBufferSize(int v) {
+    int ret;
+    xmlMutexLock(xmlThrDefMutex);
+    ret = xmlDefaultBufferSizeThrDef;
+    xmlDefaultBufferSizeThrDef = v;
+    xmlMutexUnlock(xmlThrDefMutex);
+    return ret;
+}
 
 #undef	xmlDefaultSAXHandler
 xmlSAXHandler *
@@ -594,6 +689,14 @@
     else
 	return (&xmlGetGlobalState()->xmlDoValidityCheckingDefaultValue);
 }
+int xmlThrDefDoValidityCheckingDefaultValue(int v) {
+    int ret;
+    xmlMutexLock(xmlThrDefMutex);
+    ret = xmlDoValidityCheckingDefaultValueThrDef;
+    xmlDoValidityCheckingDefaultValueThrDef = v;
+    xmlMutexUnlock(xmlThrDefMutex);
+    return ret;
+}
 
 #undef	xmlGenericError
 xmlGenericErrorFunc *
@@ -621,6 +724,14 @@
     else
 	return (&xmlGetGlobalState()->xmlGetWarningsDefaultValue);
 }
+int xmlThrDefGetWarningsDefaultValue(int v) {
+    int ret;
+    xmlMutexLock(xmlThrDefMutex);
+    ret = xmlGetWarningsDefaultValueThrDef;
+    xmlGetWarningsDefaultValueThrDef = v;
+    xmlMutexUnlock(xmlThrDefMutex);
+    return ret;
+}
 
 #undef	xmlIndentTreeOutput
 int *
@@ -630,6 +741,14 @@
     else
 	return (&xmlGetGlobalState()->xmlIndentTreeOutput);
 }
+int xmlThrDefIndentTreeOutput(int v) {
+    int ret;
+    xmlMutexLock(xmlThrDefMutex);
+    ret = xmlIndentTreeOutputThrDef;
+    xmlIndentTreeOutputThrDef = v;
+    xmlMutexUnlock(xmlThrDefMutex);
+    return ret;
+}
 
 #undef xmlTreeIndentString
 const char * *
@@ -639,6 +758,14 @@
     else
 	return (&xmlGetGlobalState()->xmlTreeIndentString);
 }
+const char * xmlThrDefTreeIndentString(const char * v) {
+    const char * ret;
+    xmlMutexLock(xmlThrDefMutex);
+    ret = xmlTreeIndentStringThrDef;
+    xmlTreeIndentStringThrDef = v;
+    xmlMutexUnlock(xmlThrDefMutex);
+    return ret;
+}
 
 #undef	xmlKeepBlanksDefaultValue
 int *
@@ -648,6 +775,14 @@
     else
 	return (&xmlGetGlobalState()->xmlKeepBlanksDefaultValue);
 }
+int xmlThrDefKeepBlanksDefaultValue(int v) {
+    int ret;
+    xmlMutexLock(xmlThrDefMutex);
+    ret = xmlKeepBlanksDefaultValueThrDef;
+    xmlKeepBlanksDefaultValueThrDef = v;
+    xmlMutexUnlock(xmlThrDefMutex);
+    return ret;
+}
 
 #undef	xmlLineNumbersDefaultValue
 int *
@@ -657,6 +792,14 @@
     else
 	return (&xmlGetGlobalState()->xmlLineNumbersDefaultValue);
 }
+int xmlThrDefLineNumbersDefaultValue(int v) {
+    int ret;
+    xmlMutexLock(xmlThrDefMutex);
+    ret = xmlLineNumbersDefaultValueThrDef;
+    xmlLineNumbersDefaultValueThrDef = v;
+    xmlMutexUnlock(xmlThrDefMutex);
+    return ret;
+}
 
 #undef	xmlLoadExtDtdDefaultValue
 int *
@@ -666,6 +809,14 @@
     else
 	return (&xmlGetGlobalState()->xmlLoadExtDtdDefaultValue);
 }
+int xmlThrDefLoadExtDtdDefaultValue(int v) {
+    int ret;
+    xmlMutexLock(xmlThrDefMutex);
+    ret = xmlLoadExtDtdDefaultValueThrDef;
+    xmlLoadExtDtdDefaultValueThrDef = v;
+    xmlMutexUnlock(xmlThrDefMutex);
+    return ret;
+}
 
 #undef	xmlParserDebugEntities
 int *
@@ -675,6 +826,14 @@
     else
 	return (&xmlGetGlobalState()->xmlParserDebugEntities);
 }
+int xmlThrDefParserDebugEntities(int v) {
+    int ret;
+    xmlMutexLock(xmlThrDefMutex);
+    ret = xmlParserDebugEntitiesThrDef;
+    xmlParserDebugEntitiesThrDef = v;
+    xmlMutexUnlock(xmlThrDefMutex);
+    return ret;
+}
 
 #undef	xmlParserVersion
 const char * *
@@ -693,6 +852,14 @@
     else
 	return (&xmlGetGlobalState()->xmlPedanticParserDefaultValue);
 }
+int xmlThrDefPedanticParserDefaultValue(int v) {
+    int ret;
+    xmlMutexLock(xmlThrDefMutex);
+    ret = xmlPedanticParserDefaultValueThrDef;
+    xmlPedanticParserDefaultValueThrDef = v;
+    xmlMutexUnlock(xmlThrDefMutex);
+    return ret;
+}
 
 #undef	xmlSaveNoEmptyTags
 int *
@@ -702,6 +869,14 @@
     else
 	return (&xmlGetGlobalState()->xmlSaveNoEmptyTags);
 }
+int xmlThrDefSaveNoEmptyTags(int v) {
+    int ret;
+    xmlMutexLock(xmlThrDefMutex);
+    ret = xmlSaveNoEmptyTagsThrDef;
+    xmlSaveNoEmptyTagsThrDef = v;
+    xmlMutexUnlock(xmlThrDefMutex);
+    return ret;
+}
 
 #undef	xmlSubstituteEntitiesDefaultValue
 int *
@@ -711,6 +886,14 @@
     else
 	return (&xmlGetGlobalState()->xmlSubstituteEntitiesDefaultValue);
 }
+int xmlThrDefSubstituteEntitiesDefaultValue(int v) {
+    int ret;
+    xmlMutexLock(xmlThrDefMutex);
+    ret = xmlSubstituteEntitiesDefaultValueThrDef;
+    xmlSubstituteEntitiesDefaultValueThrDef = v;
+    xmlMutexUnlock(xmlThrDefMutex);
+    return ret;
+}
 
 #undef	xmlRegisterNodeDefaultValue
 xmlRegisterNodeFunc *