/* * globals.c: definition and handling of the set of global variables * of the library * * The bottom of this file is automatically generated by build_glob.py * based on the description file global.data * * See Copyright for the status of this software. * * Gary Pennington * daniel@veillard.com */ #define IN_LIBXML #include "libxml.h" #include #include #include #include #include #include "private/error.h" #include "private/globals.h" #include "private/threads.h" #include "private/tree.h" /* * Helpful Macro */ #ifdef LIBXML_THREAD_ENABLED #define IS_MAIN_THREAD (xmlIsMainThread()) #else #define IS_MAIN_THREAD 1 #endif /* * Mutex to protect "ForNewThreads" variables */ static xmlMutex xmlThrDefMutex; struct _xmlGlobalState { const char *gsParserVersion; xmlSAXLocator gsDefaultSAXLocator; #ifdef LIBXML_SAX1_ENABLED xmlSAXHandlerV1 gsDefaultSAXHandler; #ifdef LIBXML_HTML_ENABLED xmlSAXHandlerV1 gsHtmlDefaultSAXHandler; #endif #endif xmlFreeFunc gsFree; xmlMallocFunc gsMalloc; xmlStrdupFunc gsMemStrdup; xmlReallocFunc gsRealloc; xmlGenericErrorFunc gsGenericError; xmlStructuredErrorFunc gsStructuredError; void *gsGenericErrorContext; int gsOldXMLWDcompatibility; xmlBufferAllocationScheme gsBufferAllocScheme; int gsDefaultBufferSize; int gsSubstituteEntitiesDefaultValue; int gsDoValidityCheckingDefaultValue; int gsGetWarningsDefaultValue; int gsKeepBlanksDefaultValue; int gsLineNumbersDefaultValue; int gsLoadExtDtdDefaultValue; int gsParserDebugEntities; int gsPedanticParserDefaultValue; int gsSaveNoEmptyTags; int gsIndentTreeOutput; const char *gsTreeIndentString; xmlRegisterNodeFunc gsRegisterNodeDefaultValue; xmlDeregisterNodeFunc gsDeregisterNodeDefaultValue; xmlMallocFunc gsMallocAtomic; xmlError gsLastError; xmlParserInputBufferCreateFilenameFunc gsParserInputBufferCreateFilenameValue; xmlOutputBufferCreateFilenameFunc gsOutputBufferCreateFilenameValue; void *gsStructuredErrorContext; }; #ifdef LIBXML_THREAD_ENABLED static void xmlFreeGlobalState(void *state); #endif #ifdef HAVE_POSIX_THREADS /* * Weak symbol hack, see threads.c */ #if defined(__GNUC__) && \ defined(__GLIBC__) && \ __GLIBC__ * 100 + __GLIBC_MINOR__ < 234 #define XML_PTHREAD_WEAK static int libxml_is_threaded = -1; #endif static pthread_key_t globalkey; #elif defined HAVE_WIN32_THREADS #if defined(HAVE_COMPILER_TLS) static __declspec(thread) xmlGlobalState tlstate; static __declspec(thread) int tlstate_inited = 0; #else /* HAVE_COMPILER_TLS */ static DWORD globalkey = TLS_OUT_OF_INDEXES; #if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL) typedef struct _xmlGlobalStateCleanupHelperParams { HANDLE thread; void *memory; } xmlGlobalStateCleanupHelperParams; static void xmlGlobalStateCleanupHelper(void *p) { xmlGlobalStateCleanupHelperParams *params = (xmlGlobalStateCleanupHelperParams *) p; WaitForSingleObject(params->thread, INFINITE); CloseHandle(params->thread); xmlFreeGlobalState(params->memory); free(params); _endthread(); } #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 */ /************************************************************************ * * * All the user accessible global variables of the library * * * ************************************************************************/ /* * Memory allocation routines */ #undef xmlFree #undef xmlMalloc #undef xmlMallocAtomic #undef xmlMemStrdup #undef xmlRealloc #if defined(DEBUG_MEMORY_LOCATION) xmlFreeFunc xmlFree = (xmlFreeFunc) xmlMemFree; xmlMallocFunc xmlMalloc = (xmlMallocFunc) xmlMemMalloc; xmlMallocFunc xmlMallocAtomic = (xmlMallocFunc) xmlMemMalloc; xmlReallocFunc xmlRealloc = (xmlReallocFunc) xmlMemRealloc; xmlStrdupFunc xmlMemStrdup = (xmlStrdupFunc) xmlMemoryStrdup; #else /** * xmlFree: * @mem: an already allocated block of memory * * The variable holding the libxml free() implementation */ xmlFreeFunc xmlFree = free; /** * xmlMalloc: * @size: the size requested in bytes * * The variable holding the libxml malloc() implementation * * Returns a pointer to the newly allocated block or NULL in case of error */ xmlMallocFunc xmlMalloc = malloc; /** * xmlMallocAtomic: * @size: the size requested in bytes * * The variable holding the libxml malloc() implementation for atomic * data (i.e. blocks not containing pointers), useful when using a * garbage collecting allocator. * * Returns a pointer to the newly allocated block or NULL in case of error */ xmlMallocFunc xmlMallocAtomic = malloc; /** * xmlRealloc: * @mem: an already allocated block of memory * @size: the new size requested in bytes * * The variable holding the libxml realloc() implementation * * Returns a pointer to the newly reallocated block or NULL in case of error */ xmlReallocFunc xmlRealloc = realloc; /** * xmlPosixStrdup * @cur: the input char * * * a strdup implementation with a type signature matching POSIX * * Returns a new xmlChar * or NULL */ static char * xmlPosixStrdup(const char *cur) { return((char*) xmlCharStrdup(cur)); } /** * xmlMemStrdup: * @str: a zero terminated string * * The variable holding the libxml strdup() implementation * * Returns the copy of the string or NULL in case of error */ xmlStrdupFunc xmlMemStrdup = xmlPosixStrdup; #endif /* DEBUG_MEMORY_LOCATION */ #include #include #include #undef htmlDefaultSAXHandler #undef oldXMLWDcompatibility #undef xmlBufferAllocScheme #undef xmlDefaultBufferSize #undef xmlDefaultSAXHandler #undef xmlDefaultSAXLocator #undef xmlDoValidityCheckingDefaultValue #undef xmlGenericError #undef xmlStructuredError #undef xmlGenericErrorContext #undef xmlStructuredErrorContext #undef xmlGetWarningsDefaultValue #undef xmlIndentTreeOutput #undef xmlTreeIndentString #undef xmlKeepBlanksDefaultValue #undef xmlLineNumbersDefaultValue #undef xmlLoadExtDtdDefaultValue #undef xmlParserDebugEntities #undef xmlParserVersion #undef xmlPedanticParserDefaultValue #undef xmlSaveNoEmptyTags #undef xmlSubstituteEntitiesDefaultValue #undef xmlRegisterNodeDefaultValue #undef xmlDeregisterNodeDefaultValue #undef xmlLastError #undef xmlParserInputBufferCreateFilenameValue #undef xmlOutputBufferCreateFilenameValue /** * xmlParserVersion: * * Constant string describing the internal version of the library */ const char *xmlParserVersion = LIBXML_VERSION_STRING LIBXML_VERSION_EXTRA; /** * xmlBufferAllocScheme: * * DEPRECATED: Don't use. * * Global setting, default allocation policy for buffers, default is * XML_BUFFER_ALLOC_EXACT */ xmlBufferAllocationScheme xmlBufferAllocScheme = XML_BUFFER_ALLOC_EXACT; static xmlBufferAllocationScheme xmlBufferAllocSchemeThrDef = XML_BUFFER_ALLOC_EXACT; /** * xmlDefaultBufferSize: * * DEPRECATED: Don't use. * * Global setting, default buffer size. Default value is BASE_BUFFER_SIZE */ int xmlDefaultBufferSize = BASE_BUFFER_SIZE; static int xmlDefaultBufferSizeThrDef = BASE_BUFFER_SIZE; /* * Parser defaults */ /** * oldXMLWDcompatibility: * * Global setting, DEPRECATED. */ int oldXMLWDcompatibility = 0; /* DEPRECATED */ /** * xmlParserDebugEntities: * * DEPRECATED: Don't use * * Global setting, asking the parser to print out debugging information. * while handling entities. * Disabled by default */ int xmlParserDebugEntities = 0; static int xmlParserDebugEntitiesThrDef = 0; /** * xmlDoValidityCheckingDefaultValue: * * DEPRECATED: Use the modern options API with XML_PARSE_DTDVALID. * * Global setting, indicate that the parser should work in validating mode. * Disabled by default. */ int xmlDoValidityCheckingDefaultValue = 0; static int xmlDoValidityCheckingDefaultValueThrDef = 0; /** * xmlGetWarningsDefaultValue: * * DEPRECATED: Don't use * * Global setting, indicate that the DTD validation should provide warnings. * Activated by default. */ int xmlGetWarningsDefaultValue = 1; static int xmlGetWarningsDefaultValueThrDef = 1; /** * xmlLoadExtDtdDefaultValue: * * DEPRECATED: Use the modern options API with XML_PARSE_DTDLOAD. * * Global setting, indicate that the parser should load DTD while not * validating. * Disabled by default. */ int xmlLoadExtDtdDefaultValue = 0; static int xmlLoadExtDtdDefaultValueThrDef = 0; /** * xmlPedanticParserDefaultValue: * * DEPRECATED: Use the modern options API with XML_PARSE_PEDANTIC. * * Global setting, indicate that the parser be pedantic * Disabled by default. */ int xmlPedanticParserDefaultValue = 0; static int xmlPedanticParserDefaultValueThrDef = 0; /** * xmlLineNumbersDefaultValue: * * DEPRECATED: The modern options API always enables line numbers. * * Global setting, indicate that the parser should store the line number * in the content field of elements in the DOM tree. * Disabled by default since this may not be safe for old classes of * application. */ int xmlLineNumbersDefaultValue = 0; static int xmlLineNumbersDefaultValueThrDef = 0; /** * xmlKeepBlanksDefaultValue: * * DEPRECATED: Use the modern options API with XML_PARSE_NOBLANKS. * * Global setting, indicate that the parser should keep all blanks * nodes found in the content * Activated by default, this is actually needed to have the parser * conformant to the XML Recommendation, however the option is kept * for some applications since this was libxml1 default behaviour. */ int xmlKeepBlanksDefaultValue = 1; static int xmlKeepBlanksDefaultValueThrDef = 1; /** * xmlSubstituteEntitiesDefaultValue: * * DEPRECATED: Use the modern options API with XML_PARSE_NOENT. * * Global setting, indicate that the parser should not generate entity * references but replace them with the actual content of the entity * Disabled by default, this should be activated when using XPath since * the XPath data model requires entities replacement and the XPath * engine does not handle entities references transparently. */ int xmlSubstituteEntitiesDefaultValue = 0; static int xmlSubstituteEntitiesDefaultValueThrDef = 0; /** * xmlRegisterNodeDefaultValue: * * DEPRECATED: Don't use */ xmlRegisterNodeFunc xmlRegisterNodeDefaultValue = NULL; static xmlRegisterNodeFunc xmlRegisterNodeDefaultValueThrDef = NULL; /** * xmlDeregisterNodeDefaultValue: * * DEPRECATED: Don't use */ xmlDeregisterNodeFunc xmlDeregisterNodeDefaultValue = NULL; static xmlDeregisterNodeFunc xmlDeregisterNodeDefaultValueThrDef = NULL; /** * xmlParserInputBufferCreateFilenameValue: * * DEPRECATED: Don't use */ xmlParserInputBufferCreateFilenameFunc xmlParserInputBufferCreateFilenameValue = NULL; static xmlParserInputBufferCreateFilenameFunc xmlParserInputBufferCreateFilenameValueThrDef = NULL; /** * xmlOutputBufferCreateFilenameValue: * * DEPRECATED: Don't use */ xmlOutputBufferCreateFilenameFunc xmlOutputBufferCreateFilenameValue = NULL; static xmlOutputBufferCreateFilenameFunc xmlOutputBufferCreateFilenameValueThrDef = NULL; /** * xmlGenericError: * * Global setting: function used for generic error callbacks */ xmlGenericErrorFunc xmlGenericError = xmlGenericErrorDefaultFunc; static xmlGenericErrorFunc xmlGenericErrorThrDef = xmlGenericErrorDefaultFunc; /** * xmlStructuredError: * * Global setting: function used for structured error callbacks */ xmlStructuredErrorFunc xmlStructuredError = NULL; static xmlStructuredErrorFunc xmlStructuredErrorThrDef = NULL; /** * xmlGenericErrorContext: * * Global setting passed to generic error callbacks */ void *xmlGenericErrorContext = NULL; static void *xmlGenericErrorContextThrDef = NULL; /** * xmlStructuredErrorContext: * * Global setting passed to structured error callbacks */ void *xmlStructuredErrorContext = NULL; static void *xmlStructuredErrorContextThrDef = NULL; xmlError xmlLastError; /* * output defaults */ /** * xmlIndentTreeOutput: * * Global setting, asking the serializer to indent the output tree by default * Enabled by default */ int xmlIndentTreeOutput = 1; static int xmlIndentTreeOutputThrDef = 1; /** * xmlTreeIndentString: * * The string used to do one-level indent. By default is equal to " " (two spaces) */ const char *xmlTreeIndentString = " "; static const char *xmlTreeIndentStringThrDef = " "; /** * xmlSaveNoEmptyTags: * * Global setting, asking the serializer to not output empty tags * as but . those two forms are indistinguishable * once parsed. * Disabled by default */ int xmlSaveNoEmptyTags = 0; static int xmlSaveNoEmptyTagsThrDef = 0; #ifdef LIBXML_SAX1_ENABLED /** * xmlDefaultSAXHandler: * * DEPRECATED: This handler is unused and will be removed from future * versions. * * Default SAX version1 handler for XML, builds the DOM tree */ xmlSAXHandlerV1 xmlDefaultSAXHandler = { xmlSAX2InternalSubset, xmlSAX2IsStandalone, xmlSAX2HasInternalSubset, xmlSAX2HasExternalSubset, xmlSAX2ResolveEntity, xmlSAX2GetEntity, xmlSAX2EntityDecl, xmlSAX2NotationDecl, xmlSAX2AttributeDecl, xmlSAX2ElementDecl, xmlSAX2UnparsedEntityDecl, xmlSAX2SetDocumentLocator, xmlSAX2StartDocument, xmlSAX2EndDocument, xmlSAX2StartElement, xmlSAX2EndElement, xmlSAX2Reference, xmlSAX2Characters, xmlSAX2Characters, xmlSAX2ProcessingInstruction, xmlSAX2Comment, xmlParserWarning, xmlParserError, xmlParserError, xmlSAX2GetParameterEntity, xmlSAX2CDataBlock, xmlSAX2ExternalSubset, 1, }; #endif /* LIBXML_SAX1_ENABLED */ /** * xmlDefaultSAXLocator: * * DEPRECATED: Don't use * * The default SAX Locator * { getPublicId, getSystemId, getLineNumber, getColumnNumber} */ xmlSAXLocator xmlDefaultSAXLocator = { xmlSAX2GetPublicId, xmlSAX2GetSystemId, xmlSAX2GetLineNumber, xmlSAX2GetColumnNumber }; #if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_SAX1_ENABLED) /** * htmlDefaultSAXHandler: * * DEPRECATED: This handler is unused and will be removed from future * versions. * * Default old SAX v1 handler for HTML, builds the DOM tree */ xmlSAXHandlerV1 htmlDefaultSAXHandler = { xmlSAX2InternalSubset, NULL, NULL, NULL, NULL, xmlSAX2GetEntity, NULL, NULL, NULL, NULL, NULL, xmlSAX2SetDocumentLocator, xmlSAX2StartDocument, xmlSAX2EndDocument, xmlSAX2StartElement, xmlSAX2EndElement, NULL, xmlSAX2Characters, xmlSAX2IgnorableWhitespace, xmlSAX2ProcessingInstruction, xmlSAX2Comment, xmlParserWarning, xmlParserError, xmlParserError, NULL, xmlSAX2CDataBlock, NULL, 1, }; #endif /* LIBXML_HTML_ENABLED */ /************************************************************************ * * * Per thread global state handling * * * ************************************************************************/ /** * xmlInitGlobals: * * DEPRECATED: Alias for xmlInitParser. */ void xmlInitGlobals(void) { xmlInitParser(); } /** * xmlInitGlobalsInternal: * * Additional initialisation for multi-threading */ void xmlInitGlobalsInternal(void) { xmlInitMutex(&xmlThrDefMutex); #ifdef HAVE_POSIX_THREADS #ifdef XML_PTHREAD_WEAK if (libxml_is_threaded == -1) libxml_is_threaded = (pthread_getspecific != NULL) && (pthread_setspecific != NULL) && (pthread_key_create != NULL) && (pthread_key_delete != NULL); if (libxml_is_threaded == 0) return; #endif /* XML_PTHREAD_WEAK */ pthread_key_create(&globalkey, xmlFreeGlobalState); #elif defined(HAVE_WIN32_THREADS) #if !defined(HAVE_COMPILER_TLS) #if !defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL) InitializeCriticalSection(&cleanup_helpers_cs); #endif globalkey = TlsAlloc(); #endif #endif } /** * xmlCleanupGlobals: * * DEPRECATED: This function is a no-op. Call xmlCleanupParser * to free global state but see the warnings there. xmlCleanupParser * should be only called once at program exit. In most cases, you don't * have call cleanup functions at all. */ void xmlCleanupGlobals(void) { } /** * xmlCleanupGlobalsInternal: * * Additional cleanup for multi-threading */ void xmlCleanupGlobalsInternal(void) { xmlResetError(&xmlLastError); xmlCleanupMutex(&xmlThrDefMutex); #ifdef HAVE_POSIX_THREADS #ifdef XML_PTHREAD_WEAK if (libxml_is_threaded == 0) return; #endif /* XML_PTHREAD_WEAK */ pthread_key_delete(globalkey); #elif defined(HAVE_WIN32_THREADS) #if !defined(HAVE_COMPILER_TLS) if (globalkey != TLS_OUT_OF_INDEXES) { #if !defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL) 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); #endif TlsFree(globalkey); globalkey = TLS_OUT_OF_INDEXES; } #if !defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL) DeleteCriticalSection(&cleanup_helpers_cs); #endif #endif #endif } /** * xmlInitializeGlobalState: * @gs: a pointer to a newly allocated global state * * DEPRECATED: Internal function, do not use. * * xmlInitializeGlobalState() initialize a global state with all the * default values of the library. */ void xmlInitializeGlobalState(xmlGlobalStatePtr gs) { xmlMutexLock(&xmlThrDefMutex); #if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_LEGACY_ENABLED) && defined(LIBXML_SAX1_ENABLED) inithtmlDefaultSAXHandler(&gs->gsHtmlDefaultSAXHandler); #endif gs->gsOldXMLWDcompatibility = 0; gs->gsBufferAllocScheme = xmlBufferAllocSchemeThrDef; gs->gsDefaultBufferSize = xmlDefaultBufferSizeThrDef; #if defined(LIBXML_SAX1_ENABLED) && defined(LIBXML_LEGACY_ENABLED) initxmlDefaultSAXHandler(&gs->gsDefaultSAXHandler, 1); #endif /* LIBXML_SAX1_ENABLED */ gs->gsDefaultSAXLocator.getPublicId = xmlSAX2GetPublicId; gs->gsDefaultSAXLocator.getSystemId = xmlSAX2GetSystemId; gs->gsDefaultSAXLocator.getLineNumber = xmlSAX2GetLineNumber; gs->gsDefaultSAXLocator.getColumnNumber = xmlSAX2GetColumnNumber; gs->gsDoValidityCheckingDefaultValue = xmlDoValidityCheckingDefaultValueThrDef; #if defined(DEBUG_MEMORY_LOCATION) gs->gsFree = (xmlFreeFunc) xmlMemFree; gs->gsMalloc = (xmlMallocFunc) xmlMemMalloc; gs->gsMallocAtomic = (xmlMallocFunc) xmlMemMalloc; gs->gsRealloc = (xmlReallocFunc) xmlMemRealloc; gs->gsMemStrdup = (xmlStrdupFunc) xmlMemoryStrdup; #else gs->gsFree = (xmlFreeFunc) free; gs->gsMalloc = (xmlMallocFunc) malloc; gs->gsMallocAtomic = (xmlMallocFunc) malloc; gs->gsRealloc = (xmlReallocFunc) realloc; gs->gsMemStrdup = (xmlStrdupFunc) xmlStrdup; #endif gs->gsGetWarningsDefaultValue = xmlGetWarningsDefaultValueThrDef; gs->gsIndentTreeOutput = xmlIndentTreeOutputThrDef; gs->gsTreeIndentString = xmlTreeIndentStringThrDef; gs->gsKeepBlanksDefaultValue = xmlKeepBlanksDefaultValueThrDef; gs->gsLineNumbersDefaultValue = xmlLineNumbersDefaultValueThrDef; gs->gsLoadExtDtdDefaultValue = xmlLoadExtDtdDefaultValueThrDef; gs->gsParserDebugEntities = xmlParserDebugEntitiesThrDef; gs->gsParserVersion = LIBXML_VERSION_STRING; gs->gsPedanticParserDefaultValue = xmlPedanticParserDefaultValueThrDef; gs->gsSaveNoEmptyTags = xmlSaveNoEmptyTagsThrDef; gs->gsSubstituteEntitiesDefaultValue = xmlSubstituteEntitiesDefaultValueThrDef; gs->gsGenericError = xmlGenericErrorThrDef; gs->gsStructuredError = xmlStructuredErrorThrDef; gs->gsGenericErrorContext = xmlGenericErrorContextThrDef; gs->gsStructuredErrorContext = xmlStructuredErrorContextThrDef; gs->gsRegisterNodeDefaultValue = xmlRegisterNodeDefaultValueThrDef; gs->gsDeregisterNodeDefaultValue = xmlDeregisterNodeDefaultValueThrDef; gs->gsParserInputBufferCreateFilenameValue = xmlParserInputBufferCreateFilenameValueThrDef; gs->gsOutputBufferCreateFilenameValue = xmlOutputBufferCreateFilenameValueThrDef; memset(&gs->gsLastError, 0, sizeof(xmlError)); xmlMutexUnlock(&xmlThrDefMutex); } #ifdef LIBXML_THREAD_ENABLED /** * xmlFreeGlobalState: * @state: a thread global state * * xmlFreeGlobalState() is called when a thread terminates with a non-NULL * global state. It is is used here to reclaim memory resources. */ static void xmlFreeGlobalState(void *state) { xmlGlobalState *gs = (xmlGlobalState *) state; /* free any memory allocated in the thread's xmlLastError */ xmlResetError(&(gs->gsLastError)); free(state); } /** * xmlNewGlobalState: * * xmlNewGlobalState() allocates a global state. This structure is used to * hold all data for use by a thread when supporting backwards compatibility * of libxml2 to pre-thread-safe behaviour. * * Returns the newly allocated xmlGlobalStatePtr or NULL in case of error */ static xmlGlobalStatePtr xmlNewGlobalState(void) { xmlGlobalState *gs; gs = malloc(sizeof(xmlGlobalState)); if (gs == NULL) { xmlGenericError(xmlGenericErrorContext, "xmlGetGlobalState: out of memory\n"); return (NULL); } memset(gs, 0, sizeof(xmlGlobalState)); xmlInitializeGlobalState(gs); return (gs); } #endif /* LIBXML_THREAD_ENABLED */ /** * xmlGetGlobalState: * * DEPRECATED: Internal function, do not use. * * xmlGetGlobalState() is called to retrieve the global state for a thread. * * Returns the thread global state or NULL in case of error */ xmlGlobalStatePtr xmlGetGlobalState(void) { #ifdef HAVE_POSIX_THREADS xmlGlobalState *globalval; if ((globalval = (xmlGlobalState *) pthread_getspecific(globalkey)) == NULL) { xmlGlobalState *tsd = xmlNewGlobalState(); if (tsd == NULL) return(NULL); pthread_setspecific(globalkey, tsd); return (tsd); } return (globalval); #elif defined HAVE_WIN32_THREADS #if defined(HAVE_COMPILER_TLS) if (!tlstate_inited) { tlstate_inited = 1; xmlInitializeGlobalState(&tlstate); } return &tlstate; #else /* HAVE_COMPILER_TLS */ xmlGlobalState *globalval; xmlGlobalStateCleanupHelperParams *p; #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 (tsd == NULL) return(NULL); p = (xmlGlobalStateCleanupHelperParams *) malloc(sizeof(xmlGlobalStateCleanupHelperParams)); if (p == NULL) { xmlGenericError(xmlGenericErrorContext, "xmlGetGlobalState: out of memory\n"); xmlFreeGlobalState(tsd); return(NULL); } p->memory = tsd; #if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL) DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &p->thread, 0, TRUE, DUPLICATE_SAME_ACCESS); TlsSetValue(globalkey, tsd); _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); } return (globalval); #endif /* HAVE_COMPILER_TLS */ #else return (NULL); #endif } /** * DllMain: * @hinstDLL: handle to DLL instance * @fdwReason: Reason code for entry * @lpvReserved: generic pointer (depends upon reason code) * * Entry point for Windows library. It is being used to free thread-specific * storage. * * Returns TRUE always */ #ifdef HAVE_POSIX_THREADS #elif defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL)) #if defined(LIBXML_STATIC_FOR_DLL) int xmlDllMain(ATTRIBUTE_UNUSED void *hinstDLL, unsigned long fdwReason, ATTRIBUTE_UNUSED void *lpvReserved) #else /* declare to avoid "no previous prototype for 'DllMain'" warning */ /* Note that we do NOT want to include this function declaration in a public header because it's meant to be called by Windows itself, not a program that uses this library. This also has to be exported. */ XMLPUBFUN BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved); BOOL WINAPI DllMain(ATTRIBUTE_UNUSED HINSTANCE hinstDLL, DWORD fdwReason, ATTRIBUTE_UNUSED LPVOID lpvReserved) #endif { switch (fdwReason) { case DLL_THREAD_DETACH: if (globalkey != TLS_OUT_OF_INDEXES) { 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; } return TRUE; } #endif void xmlThrDefSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc handler) { xmlMutexLock(&xmlThrDefMutex); xmlGenericErrorContextThrDef = ctx; if (handler != NULL) xmlGenericErrorThrDef = handler; else xmlGenericErrorThrDef = xmlGenericErrorDefaultFunc; xmlMutexUnlock(&xmlThrDefMutex); } void xmlThrDefSetStructuredErrorFunc(void *ctx, xmlStructuredErrorFunc handler) { xmlMutexLock(&xmlThrDefMutex); xmlStructuredErrorContextThrDef = ctx; xmlStructuredErrorThrDef = handler; xmlMutexUnlock(&xmlThrDefMutex); } /** * xmlRegisterNodeDefault: * @func: function pointer to the new RegisterNodeFunc * * Registers a callback for node creation * * Returns the old value of the registration function */ xmlRegisterNodeFunc xmlRegisterNodeDefault(xmlRegisterNodeFunc func) { xmlRegisterNodeFunc old = xmlRegisterNodeDefaultValue; __xmlRegisterCallbacks = 1; xmlRegisterNodeDefaultValue = func; 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 * * Registers a callback for node destruction * * Returns the previous value of the deregistration function */ xmlDeregisterNodeFunc xmlDeregisterNodeDefault(xmlDeregisterNodeFunc func) { xmlDeregisterNodeFunc old = xmlDeregisterNodeDefaultValue; __xmlRegisterCallbacks = 1; xmlDeregisterNodeDefaultValue = func; return(old); } xmlDeregisterNodeFunc xmlThrDefDeregisterNodeDefault(xmlDeregisterNodeFunc func) { xmlDeregisterNodeFunc old; xmlMutexLock(&xmlThrDefMutex); old = xmlDeregisterNodeDefaultValueThrDef; __xmlRegisterCallbacks = 1; xmlDeregisterNodeDefaultValueThrDef = func; xmlMutexUnlock(&xmlThrDefMutex); return(old); } xmlParserInputBufferCreateFilenameFunc xmlThrDefParserInputBufferCreateFilenameDefault(xmlParserInputBufferCreateFilenameFunc func) { xmlParserInputBufferCreateFilenameFunc old; xmlMutexLock(&xmlThrDefMutex); old = xmlParserInputBufferCreateFilenameValueThrDef; if (old == NULL) { old = __xmlParserInputBufferCreateFilename; } xmlParserInputBufferCreateFilenameValueThrDef = func; xmlMutexUnlock(&xmlThrDefMutex); return(old); } xmlOutputBufferCreateFilenameFunc xmlThrDefOutputBufferCreateFilenameDefault(xmlOutputBufferCreateFilenameFunc func) { xmlOutputBufferCreateFilenameFunc old; xmlMutexLock(&xmlThrDefMutex); old = xmlOutputBufferCreateFilenameValueThrDef; #ifdef LIBXML_OUTPUT_ENABLED if (old == NULL) { old = __xmlOutputBufferCreateFilename; } #endif xmlOutputBufferCreateFilenameValueThrDef = func; xmlMutexUnlock(&xmlThrDefMutex); return(old); } #if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_SAX1_ENABLED) #undef htmlDefaultSAXHandler xmlSAXHandlerV1 * __htmlDefaultSAXHandler(void) { if (IS_MAIN_THREAD) return (&htmlDefaultSAXHandler); else return (&xmlGetGlobalState()->gsHtmlDefaultSAXHandler); } #endif #undef xmlLastError xmlError * __xmlLastError(void) { if (IS_MAIN_THREAD) return (&xmlLastError); else return (&xmlGetGlobalState()->gsLastError); } /* * The following memory routines were apparently lost at some point, * and were re-inserted at this point on June 10, 2004. Hope it's * the right place for them :-) */ #if defined(LIBXML_THREAD_ALLOC_ENABLED) && defined(LIBXML_THREAD_ENABLED) #undef xmlMalloc xmlMallocFunc * __xmlMalloc(void){ if (IS_MAIN_THREAD) return (&xmlMalloc); else return (&xmlGetGlobalState()->gsMalloc); } #undef xmlMallocAtomic xmlMallocFunc * __xmlMallocAtomic(void){ if (IS_MAIN_THREAD) return (&xmlMallocAtomic); else return (&xmlGetGlobalState()->gsMallocAtomic); } #undef xmlRealloc xmlReallocFunc * __xmlRealloc(void){ if (IS_MAIN_THREAD) return (&xmlRealloc); else return (&xmlGetGlobalState()->gsRealloc); } #undef xmlFree xmlFreeFunc * __xmlFree(void){ if (IS_MAIN_THREAD) return (&xmlFree); else return (&xmlGetGlobalState()->gsFree); } xmlStrdupFunc * __xmlMemStrdup(void){ if (IS_MAIN_THREAD) return (&xmlMemStrdup); else return (&xmlGetGlobalState()->gsMemStrdup); } #endif /* * Everything starting from the line below is * Automatically generated by build_glob.py. * Do not modify the previous line. */ #undef oldXMLWDcompatibility int * __oldXMLWDcompatibility(void) { if (IS_MAIN_THREAD) return (&oldXMLWDcompatibility); else return (&xmlGetGlobalState()->gsOldXMLWDcompatibility); } #undef xmlBufferAllocScheme xmlBufferAllocationScheme * __xmlBufferAllocScheme(void) { if (IS_MAIN_THREAD) return (&xmlBufferAllocScheme); else return (&xmlGetGlobalState()->gsBufferAllocScheme); } xmlBufferAllocationScheme xmlThrDefBufferAllocScheme(xmlBufferAllocationScheme v) { xmlBufferAllocationScheme ret; xmlMutexLock(&xmlThrDefMutex); ret = xmlBufferAllocSchemeThrDef; xmlBufferAllocSchemeThrDef = v; xmlMutexUnlock(&xmlThrDefMutex); return ret; } #undef xmlDefaultBufferSize int * __xmlDefaultBufferSize(void) { if (IS_MAIN_THREAD) return (&xmlDefaultBufferSize); else return (&xmlGetGlobalState()->gsDefaultBufferSize); } int xmlThrDefDefaultBufferSize(int v) { int ret; xmlMutexLock(&xmlThrDefMutex); ret = xmlDefaultBufferSizeThrDef; xmlDefaultBufferSizeThrDef = v; xmlMutexUnlock(&xmlThrDefMutex); return ret; } #ifdef LIBXML_SAX1_ENABLED #undef xmlDefaultSAXHandler xmlSAXHandlerV1 * __xmlDefaultSAXHandler(void) { if (IS_MAIN_THREAD) return (&xmlDefaultSAXHandler); else return (&xmlGetGlobalState()->gsDefaultSAXHandler); } #endif /* LIBXML_SAX1_ENABLED */ #undef xmlDefaultSAXLocator xmlSAXLocator * __xmlDefaultSAXLocator(void) { if (IS_MAIN_THREAD) return (&xmlDefaultSAXLocator); else return (&xmlGetGlobalState()->gsDefaultSAXLocator); } #undef xmlDoValidityCheckingDefaultValue int * __xmlDoValidityCheckingDefaultValue(void) { if (IS_MAIN_THREAD) return (&xmlDoValidityCheckingDefaultValue); else return (&xmlGetGlobalState()->gsDoValidityCheckingDefaultValue); } int xmlThrDefDoValidityCheckingDefaultValue(int v) { int ret; xmlMutexLock(&xmlThrDefMutex); ret = xmlDoValidityCheckingDefaultValueThrDef; xmlDoValidityCheckingDefaultValueThrDef = v; xmlMutexUnlock(&xmlThrDefMutex); return ret; } #undef xmlGenericError xmlGenericErrorFunc * __xmlGenericError(void) { if (IS_MAIN_THREAD) return (&xmlGenericError); else return (&xmlGetGlobalState()->gsGenericError); } #undef xmlStructuredError xmlStructuredErrorFunc * __xmlStructuredError(void) { if (IS_MAIN_THREAD) return (&xmlStructuredError); else return (&xmlGetGlobalState()->gsStructuredError); } #undef xmlGenericErrorContext void * * __xmlGenericErrorContext(void) { if (IS_MAIN_THREAD) return (&xmlGenericErrorContext); else return (&xmlGetGlobalState()->gsGenericErrorContext); } #undef xmlStructuredErrorContext void * * __xmlStructuredErrorContext(void) { if (IS_MAIN_THREAD) return (&xmlStructuredErrorContext); else return (&xmlGetGlobalState()->gsStructuredErrorContext); } #undef xmlGetWarningsDefaultValue int * __xmlGetWarningsDefaultValue(void) { if (IS_MAIN_THREAD) return (&xmlGetWarningsDefaultValue); else return (&xmlGetGlobalState()->gsGetWarningsDefaultValue); } int xmlThrDefGetWarningsDefaultValue(int v) { int ret; xmlMutexLock(&xmlThrDefMutex); ret = xmlGetWarningsDefaultValueThrDef; xmlGetWarningsDefaultValueThrDef = v; xmlMutexUnlock(&xmlThrDefMutex); return ret; } #undef xmlIndentTreeOutput int * __xmlIndentTreeOutput(void) { if (IS_MAIN_THREAD) return (&xmlIndentTreeOutput); else return (&xmlGetGlobalState()->gsIndentTreeOutput); } int xmlThrDefIndentTreeOutput(int v) { int ret; xmlMutexLock(&xmlThrDefMutex); ret = xmlIndentTreeOutputThrDef; xmlIndentTreeOutputThrDef = v; xmlMutexUnlock(&xmlThrDefMutex); return ret; } #undef xmlTreeIndentString const char * * __xmlTreeIndentString(void) { if (IS_MAIN_THREAD) return (&xmlTreeIndentString); else return (&xmlGetGlobalState()->gsTreeIndentString); } const char * xmlThrDefTreeIndentString(const char * v) { const char * ret; xmlMutexLock(&xmlThrDefMutex); ret = xmlTreeIndentStringThrDef; xmlTreeIndentStringThrDef = v; xmlMutexUnlock(&xmlThrDefMutex); return ret; } #undef xmlKeepBlanksDefaultValue int * __xmlKeepBlanksDefaultValue(void) { if (IS_MAIN_THREAD) return (&xmlKeepBlanksDefaultValue); else return (&xmlGetGlobalState()->gsKeepBlanksDefaultValue); } int xmlThrDefKeepBlanksDefaultValue(int v) { int ret; xmlMutexLock(&xmlThrDefMutex); ret = xmlKeepBlanksDefaultValueThrDef; xmlKeepBlanksDefaultValueThrDef = v; xmlMutexUnlock(&xmlThrDefMutex); return ret; } #undef xmlLineNumbersDefaultValue int * __xmlLineNumbersDefaultValue(void) { if (IS_MAIN_THREAD) return (&xmlLineNumbersDefaultValue); else return (&xmlGetGlobalState()->gsLineNumbersDefaultValue); } int xmlThrDefLineNumbersDefaultValue(int v) { int ret; xmlMutexLock(&xmlThrDefMutex); ret = xmlLineNumbersDefaultValueThrDef; xmlLineNumbersDefaultValueThrDef = v; xmlMutexUnlock(&xmlThrDefMutex); return ret; } #undef xmlLoadExtDtdDefaultValue int * __xmlLoadExtDtdDefaultValue(void) { if (IS_MAIN_THREAD) return (&xmlLoadExtDtdDefaultValue); else return (&xmlGetGlobalState()->gsLoadExtDtdDefaultValue); } int xmlThrDefLoadExtDtdDefaultValue(int v) { int ret; xmlMutexLock(&xmlThrDefMutex); ret = xmlLoadExtDtdDefaultValueThrDef; xmlLoadExtDtdDefaultValueThrDef = v; xmlMutexUnlock(&xmlThrDefMutex); return ret; } #undef xmlParserDebugEntities int * __xmlParserDebugEntities(void) { if (IS_MAIN_THREAD) return (&xmlParserDebugEntities); else return (&xmlGetGlobalState()->gsParserDebugEntities); } int xmlThrDefParserDebugEntities(int v) { int ret; xmlMutexLock(&xmlThrDefMutex); ret = xmlParserDebugEntitiesThrDef; xmlParserDebugEntitiesThrDef = v; xmlMutexUnlock(&xmlThrDefMutex); return ret; } #undef xmlParserVersion const char * * __xmlParserVersion(void) { if (IS_MAIN_THREAD) return (&xmlParserVersion); else return (&xmlGetGlobalState()->gsParserVersion); } #undef xmlPedanticParserDefaultValue int * __xmlPedanticParserDefaultValue(void) { if (IS_MAIN_THREAD) return (&xmlPedanticParserDefaultValue); else return (&xmlGetGlobalState()->gsPedanticParserDefaultValue); } int xmlThrDefPedanticParserDefaultValue(int v) { int ret; xmlMutexLock(&xmlThrDefMutex); ret = xmlPedanticParserDefaultValueThrDef; xmlPedanticParserDefaultValueThrDef = v; xmlMutexUnlock(&xmlThrDefMutex); return ret; } #undef xmlSaveNoEmptyTags int * __xmlSaveNoEmptyTags(void) { if (IS_MAIN_THREAD) return (&xmlSaveNoEmptyTags); else return (&xmlGetGlobalState()->gsSaveNoEmptyTags); } int xmlThrDefSaveNoEmptyTags(int v) { int ret; xmlMutexLock(&xmlThrDefMutex); ret = xmlSaveNoEmptyTagsThrDef; xmlSaveNoEmptyTagsThrDef = v; xmlMutexUnlock(&xmlThrDefMutex); return ret; } #undef xmlSubstituteEntitiesDefaultValue int * __xmlSubstituteEntitiesDefaultValue(void) { if (IS_MAIN_THREAD) return (&xmlSubstituteEntitiesDefaultValue); else return (&xmlGetGlobalState()->gsSubstituteEntitiesDefaultValue); } int xmlThrDefSubstituteEntitiesDefaultValue(int v) { int ret; xmlMutexLock(&xmlThrDefMutex); ret = xmlSubstituteEntitiesDefaultValueThrDef; xmlSubstituteEntitiesDefaultValueThrDef = v; xmlMutexUnlock(&xmlThrDefMutex); return ret; } #undef xmlRegisterNodeDefaultValue xmlRegisterNodeFunc * __xmlRegisterNodeDefaultValue(void) { if (IS_MAIN_THREAD) return (&xmlRegisterNodeDefaultValue); else return (&xmlGetGlobalState()->gsRegisterNodeDefaultValue); } #undef xmlDeregisterNodeDefaultValue xmlDeregisterNodeFunc * __xmlDeregisterNodeDefaultValue(void) { if (IS_MAIN_THREAD) return (&xmlDeregisterNodeDefaultValue); else return (&xmlGetGlobalState()->gsDeregisterNodeDefaultValue); } #undef xmlParserInputBufferCreateFilenameValue xmlParserInputBufferCreateFilenameFunc * __xmlParserInputBufferCreateFilenameValue(void) { if (IS_MAIN_THREAD) return (&xmlParserInputBufferCreateFilenameValue); else return (&xmlGetGlobalState()->gsParserInputBufferCreateFilenameValue); } #undef xmlOutputBufferCreateFilenameValue xmlOutputBufferCreateFilenameFunc * __xmlOutputBufferCreateFilenameValue(void) { if (IS_MAIN_THREAD) return (&xmlOutputBufferCreateFilenameValue); else return (&xmlGetGlobalState()->gsOutputBufferCreateFilenameValue); }