/*
 * 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 <Gary.Pennington@uk.sun.com>
 * daniel@veillard.com
 */
#define IN_LIBXML
#include "XmlEnglibxml.h"

#include <assert.h>

//#ifdef HAVE_STDLIB_H
#include <stdlib.h>
//#endif

#include <string.h>

#include "Libxml2_globals.h"
//#include "Libxml2_xmlmemory.h"
//#include "Libxml2_threads.h"

// TODO: provide optimized alternative that receives xmlDocPtr for use of cached xmlGlobalStatePtr
int xmlOOMFlag()
    {
#ifdef _DEBUG
    int f = OOM_FLAG;
    if(f)
        {
        f |= 0; // SET BREAKPOINT HERE
        }
    return f;
#else
    return OOM_FLAG;
#endif
    }

void xmlSetOOM()
    {
    OOM_FLAG = 1;
    }

void xmlResetOOM()
    {
    // We need this in case OOM happened during initialization of global state
    if (!xeGetTLS())
        return;
    OOM_FLAG = 0;
    }


#define __lookup_ALLOC_ADDRES_ 0x23561e8

/*
 NOTE: XMLENGINE_MEM_DEBUG option is defined only in debug builds
*/
void* malloc_impl(size_t size)
{
    xmlGlobalStatePtr gs; // is needed only during OOM

    void* mem = malloc(size);
#ifdef XMLENGINE_MEM_DEBUG
    if((int)mem == __lookup_ALLOC_ADDRES_) {
        size &= -1; // Set breakpoint here
    }
#endif
    if(!mem)
        {
        gs = xeGetTLS();
        if(gs)
            xmlOOM = 1;
        }
#ifdef XMLENGINE_MEM_DEBUG
    else
        {
        gs = xeGetTLS();
        if(gs && !xmlOOM) // do not count "after allocations" during error-handling
            gs->allocCount++;
        }
#endif

    return mem;
}

#ifdef XMLENGINE_MEM_DEBUG
void free_debug(void* mem)
{
	if(mem)
		{
	    if((int)mem == __lookup_ALLOC_ADDRES_) 
	    	{
	        *(int*)mem &= -1; // Set breakpoint here
	    	}
	    free(mem);
		}
}
#endif

#ifdef XMLENGINE_EXCLUDE_EMBED_MSG
const char* const __embedded_errtxt_replacement = "DISABLED ERROR STRING\n";
#endif

void xeCleanupDOMStringConverter()
{
#if defined (XMLENGINE_USE_DOMSTRINGARGUMENT)
    DOMStringConverterData* data = &xmlGetGlobalState()->xeStringArgs;
    char** buf;
    int i;
    for(i=0; i<4; i++){
        buf = &data->cleanupItem[i];
        if(*buf){
            xmlFree(*buf);
            *buf = 0;
        }
    }
#endif /* XMLENGINE_USE_DOMSTRINGARGUMENT*/
}
//static
//inline
int symbian_vsnprintf(char *str, size_t size, const char *format, va_list ap)
{
    int ret = 0;

    ret = vsprintf(str, format, ap);

    assert((size_t)ret < size);
    return ret;
}

//static
//inline
int symbian_snprintf(char *str, size_t size, const char *format, ...)
{
    int ret = 0;
    va_list args;
    va_start(args, format);
    symbian_vsnprintf(str, size, format, args);
    va_end(args);

    assert((size_t)ret < size);

    return ret;
}

#include "Libxml2_SAX.h"

/**
 * xmlTreeIndentString:
 *
 * The string used to do one-level indent. By default is equal to "  " (two spaces)
 */
const char* const xmlTreeIndentString = "  ";
static const char* const xmlTreeIndentStringThrDef = "  ";


/**
 * xmlParserVersion:
 *
 * Constant string describing the internal version of the library
 */
const char* const xmlParserVersion = LIBXML_VERSION_STRING;


xmlRegisterNodeFunc
xmlRegisterNodeDefault(xmlRegisterNodeFunc func)
{
    xmlRegisterNodeFunc old = xmlRegisterNodeDefaultValue;

    __xmlRegisterCallbacks = 1;
    xmlRegisterNodeDefaultValue = func;
    return(old);
}

xmlDeregisterNodeFunc
xmlDeregisterNodeDefault(xmlDeregisterNodeFunc func)
{
    xmlDeregisterNodeFunc old = xmlDeregisterNodeDefaultValue;

    __xmlRegisterCallbacks = 1;
    xmlDeregisterNodeDefaultValue = func;
    return(old);
}

//TODO: make "features" of XML Engine from all these settings
#define xmlBufferAllocSchemeThrDef XML_BUFFER_ALLOC_EXACT
#define xmlDefaultBufferSizeThrDef BASE_BUFFER_SIZE
#define xmlParserDebugEntitiesThrDef 0
#define xmlDoValidityCheckingDefaultValueThrDef 0
#define xmlGetWarningsDefaultValueThrDef 1
#define xmlLoadExtDtdDefaultValueThrDef 0
#define xmlPedanticParserDefaultValueThrDef 0
#define xmlLineNumbersDefaultValueThrDef 0
#define xmlKeepBlanksDefaultValueThrDef 1
#define xmlSubstituteEntitiesDefaultValueThrDef 0
#define xmlRegisterNodeDefaultValueThrDef NULL
#define xmlDeregisterNodeDefaultValueThrDef NULL


void xmlGenericErrorDefaultFunc (void *ctx ATTRIBUTE_UNUSED, const char *msg, ...);

#define xmlGenericErrorThrDef  xmlGenericErrorDefaultFunc
#define xmlStructuredErrorThrDef  NULL
#define xmlGenericErrorContextThrDef NULL
#define xmlIndentTreeOutputThrDef 1
#define xmlTreeIndentStringThrDef "  "
#define xmlSaveNoEmptyTagsThrDef 0

#undef  docbDefaultSAXHandler
#undef  htmlDefaultSAXHandler
#undef  xmlBufferAllocScheme
#undef  xmlDefaultBufferSize
#undef  xmlDefaultSAXHandler
#undef  xmlDefaultSAXLocator
#undef  xmlDoValidityCheckingDefaultValue
#undef  xmlGenericError
#undef  xmlStructuredError
#undef  xmlGenericErrorContext
#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  xmlFree
#undef  xmlMalloc
#undef  xmlMallocAtomic
#undef  xmlMemStrdup
#undef  xmlRealloc

// merge:agathe  have to check that this is useful
#undef  htmlStartCloseIndex
#undef  htmlStartCloseIndexinitialized

/* tree */
#undef __xmlRegisterCallbacks
#undef xmlCompressMode
#undef xmlCheckDTD

/* xmlmemory */
#undef xmlMemInitialized
#undef debugMemSize
#undef debugMaxMemSize
#undef xmlMemMutex
#undef block
#undef xmlMemStopAtBlock
#undef xmlMemTraceBlockAt


/* catalog */
#undef  xmlDebugCatalogs
#undef  xmlCatalogDefaultAllow
#undef  xmlCatalogDefaultPrefer
#undef  xmlCatalogXMLFiles
#undef  xmlDefaultCatalog
#undef  xmlCatalogMutex
#undef  xmlCatalogInitialized

#undef  xmlInputCallbackTable
#undef  xmlInputCallbackNr
#undef  xmlInputCallbackInitialized
#undef  xmlOutputCallbackTable
#undef  xmlOutputCallbackNr
#undef  xmlOutputCallbackInitialized
//#undef  IOerr
#undef xmlCurrentExternalEntityLoader

#undef xmlSAX2DefaultVersionValue

#undef xmlParserMaxDepth
#undef xmlW3CPIs
#undef xmlParserInitialized

#undef xeStackLimit

//#undef xmlEntityLt
//#undef xmlEntityGt
//#undef xmlEntityAmp
//#undef xmlEntityQuot
//#undef xmlEntityApos

#undef xmlUTF16LEHandler
#undef xmlUTF16BEHandler
#undef xmlCharEncodingAliases
#undef xmlCharEncodingAliasesNb
#undef xmlCharEncodingAliasesMax
#undef xmlLittleEndian
#undef handlers
#undef nbCharEncodingHandler
#undef xmlDefaultCharEncodingHandler

#undef xmlXPathNAN
#undef xmlXPathPINF
#undef xmlXPathNINF
#undef xmlXPathNZERO
#undef xmlXPathInitialized

#ifndef LIBXML_THREAD_ENABLED
#   undef xmlXPathDisableOptimizer
#endif

#ifdef XMLENGINE_XPATH_FUNC_HASH_OPTIMIZED
#   undef xmlXPathDefineExtensionFunctionsGlobally
#   undef xmlXPathDefaultFunctionsHash
#   undef xmlXPathIntermediaryExtensionFunctionsHash
#endif

#undef xlinkDefaultHandler
#undef xlinkDefaultDetect

#undef had_info
#undef xmlInputStreamId

#undef xeUserCount

/* XMLENGINE_XSLT */
#undef calibration
#undef default_token
#undef xsltExtensionsHash
#undef xsltFunctionsHash
#undef xsltElementsHash
#undef xsltTopLevelsHash
#undef xsltDebuggerCurrentCallbacks

#ifdef LIBXML_SAX1_ENABLED
/**
 * xmlDefaultSAXHandler:
 *
 * Default SAX version1 handler for XML, builds the DOM tree
 */
const 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,
    0,
};
#endif /* LIBXML_SAX1_ENABLED */

/**
 * xmlDefaultSAXLocator:
 *
 * The default SAX Locator
 * { getPublicId, getSystemId, getLineNumber, getColumnNumber}
 */
const xmlSAXLocator xmlDefaultSAXLocator = {
    xmlSAX2GetPublicId,
    xmlSAX2GetSystemId,
    xmlSAX2GetLineNumber,
    xmlSAX2GetColumnNumber
};

#ifdef LIBXML_HTML_ENABLED
/**
 * htmlDefaultSAXHandler:
 *
 * Default old SAX v1 handler for HTML, builds the DOM tree
 */
const xmlSAXHandlerV1 htmlDefaultSAXHandler = {
    xmlSAX2InternalSubset,
    NULL,
    NULL,
    NULL,
    NULL,
    xmlSAX2GetEntity,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    xmlSAX2SetDocumentLocator,
    xmlSAX2StartDocument,
    xmlSAX2EndDocument,
    xmlSAX2StartElement,
    xmlSAX2EndElement,
    NULL,
    xmlSAX2Characters,
    xmlSAX2IgnorableWhitespace,
    NULL,
    xmlSAX2Comment,
    xmlParserWarning,
    xmlParserError,
    xmlParserError,
    xmlSAX2GetParameterEntity,
    xmlSAX2CDataBlock,
    NULL,
    0,
};
#endif /* LIBXML_HTML_ENABLED */

#ifdef LIBXML_DOCB_ENABLED
/**
 * docbDefaultSAXHandler:
 *
 * Default old SAX v1 handler for SGML DocBook, builds the DOM tree
 */
const xmlSAXHandlerV1 docbDefaultSAXHandler = {
    xmlSAX2InternalSubset,
    xmlSAX2IsStandalone,
    xmlSAX2HasInternalSubset,
    xmlSAX2HasExternalSubset,
    xmlSAX2ResolveEntity,
    xmlSAX2GetEntity,
    xmlSAX2EntityDecl,
    NULL,
    NULL,
    NULL,
    NULL,
    xmlSAX2SetDocumentLocator,
    xmlSAX2StartDocument,
    xmlSAX2EndDocument,
    xmlSAX2StartElement,
    xmlSAX2EndElement,
    xmlSAX2Reference,
    xmlSAX2Characters,
    xmlSAX2IgnorableWhitespace,
    NULL,
    xmlSAX2Comment,
    xmlParserWarning,
    xmlParserError,
    xmlParserError,
    xmlSAX2GetParameterEntity,
    NULL,
    NULL,
    0,
};
#endif /* LIBXML_DOCB_ENABLED */



/**
 * xmlInitializeGlobalState:
 * @gs: a pointer to a newly allocated global state
 *
 * xmlInitializeGlobalState() initialize a global state with all the
 * default values of the library.
 */
void
xmlInitializeGlobalState(xmlGlobalStatePtr gs, xmlLinAddress stackLimit)
{

#ifdef DEBUG_GLOBALS
    fprintf(stderr, "Initializing globals at %lu for thread %d\n",
        (unsigned long) gs, xmlGetThreadId());
#endif

    /*
     * Perform initialization as required by libxml
     */
    if (xmlThrDefMutex == NULL)
        xmlInitGlobals();

    xmlMutexLock(xmlThrDefMutex);

#ifdef LIBXML_DOCB_ENABLED
    xmlSAX2InitDocbDefaultSAXHandler(&gs->docbDefaultSAXHandler);
#endif
#ifdef LIBXML_HTML_ENABLED
    //TODO: Find out do we need this or not
    //xmlSAX2InitHtmlDefaultSAXHandler(&gs->htmlDefaultSAXHandler);
#endif
// merge: agathe: I had removed this code for libxslt...
//#ifdef LIBXML_DOCB_ENABLED
//    initdocbDefaultSAXHandler(&gs->docbDefaultSAXHandler);
//#endif

//#ifdef LIBXML_HTML_ENABLED
    //inithtmlDefaultSAXHandler(&gs->htmlDefaultSAXHandler);
//#endif

    gs->xmlBufferAllocScheme = xmlBufferAllocSchemeThrDef;
    gs->xmlDefaultBufferSize = xmlDefaultBufferSizeThrDef;
#ifdef LIBXML_SAX1_ENABLED
    initxmlDefaultSAXHandler(&gs->xmlDefaultSAXHandler, 1);
#endif /* LIBXML_SAX1_ENABLED */
    gs->xmlDefaultSAXLocator.getPublicId = xmlSAX2GetPublicId;
    gs->xmlDefaultSAXLocator.getSystemId = xmlSAX2GetSystemId;
    gs->xmlDefaultSAXLocator.getLineNumber = xmlSAX2GetLineNumber;
    gs->xmlDefaultSAXLocator.getColumnNumber = xmlSAX2GetColumnNumber;
    gs->xmlDoValidityCheckingDefaultValue = xmlDoValidityCheckingDefaultValueThrDef;

#if defined(DEBUG_MEMORY_LOCATION) || defined(DEBUG_MEMORY)
    gs->xmlFreeFn         = (xmlFreeFunc)    xmlMemFree;
    gs->xmlMallocFn       = (xmlMallocFunc)  xmlMemMalloc;
    gs->xmlMallocAtomicFn = (xmlMallocFunc)  xmlMemMalloc;
    gs->xmlReallocFn      = (xmlReallocFunc) xmlMemRealloc;
    gs->xmlMemStrdupFn    = (xmlStrdupFunc)  xmlMemoryStrdup;
#else

    gs->xmlMallocFn       = (xmlMallocFunc)  malloc_impl;
#ifdef XMLENGINE_MEM_DEBUG
    gs->xmlFreeFn         = (xmlFreeFunc)    free_debug;
#else
    gs->xmlFreeFn         = (xmlFreeFunc)    free;
#endif

    gs->xmlMallocAtomicFn = (xmlMallocFunc)  malloc;
    gs->xmlReallocFn      = (xmlReallocFunc) realloc;
    gs->xmlMemStrdupFn    = (xmlStrdupFunc)  xmlStrdup;
#endif /* DEBUG_MEMORY */

    gs->xmlGetWarningsDefaultValue = xmlGetWarningsDefaultValueThrDef;
    gs->xmlIndentTreeOutput = xmlIndentTreeOutputThrDef;
//    gs->xmlTreeIndentString = xmlTreeIndentStringThrDef;
    gs->xmlKeepBlanksDefaultValue = xmlKeepBlanksDefaultValueThrDef;
#ifdef LIBXML_ENABLE_NODE_LINEINFO
    gs->xmlLineNumbersDefaultValue = xmlLineNumbersDefaultValueThrDef;
#endif
    gs->xmlLoadExtDtdDefaultValue = xmlLoadExtDtdDefaultValueThrDef;
    gs->xmlParserDebugEntities = xmlParserDebugEntitiesThrDef;
//    gs->xmlParserVersion = LIBXML_VERSION_STRING;
    gs->xmlPedanticParserDefaultValue = xmlPedanticParserDefaultValueThrDef;
    gs->xmlSaveNoEmptyTags = xmlSaveNoEmptyTagsThrDef;
    gs->xmlSubstituteEntitiesDefaultValue = xmlSubstituteEntitiesDefaultValueThrDef;

    gs->xmlGenericError = xmlGenericErrorThrDef;
    gs->xmlStructuredError = xmlStructuredErrorThrDef;
    gs->xmlGenericErrorContext = xmlGenericErrorContextThrDef;
    gs->xmlRegisterNodeDefaultValue = xmlRegisterNodeDefaultValueThrDef;
    gs->xmlDeregisterNodeDefaultValue = xmlDeregisterNodeDefaultValueThrDef;
    memset(&gs->xmlLastError, 0, sizeof(xmlError));

// ==================================================
// XMLENEGINE: NOTE: All zero values are commented,
//  since the whole structure is set to zeros prior
//  initialization
// ==================================================

//  gs->had_info = 0;

//  gs->xmlInputStreamId = 0;

//  gs->xmlUTF16LEHandler = NULL;
//  gs->xmlUTF16BEHandler = NULL;
//  gs->xmlCharEncodingAliases = NULL;
//  gs->xmlCharEncodingAliasesNb = 0;
//  gs->xmlCharEncodingAliasesMax = 0;
    gs->xmlLittleEndian = 1;
//  gs->handlers = NULL;
//  gs->nbCharEncodingHandler = 0;
//  gs->xmlDefaultCharEncodingHandler = NULL;

    gs->xmlParserMaxDepth = 1024;
    gs->xmlW3CPIs[0] = "xml-stylesheet";
    gs->xmlW3CPIs[1] = NULL;
//  gs->xmlParserInitialized = 0;

	gs->xeStackLimit = stackLimit;

    gs->xmlSAX2DefaultVersionValue = 2;

//  gs->xmlInputCallbackNr = 0;
//  gs->xmlInputCallbackInitialized = 0;

#ifdef LIBXML_OUTPUT_ENABLED
//  gs->xmlOutputCallbackNr = 0;
//  gs->xmlOutputCallbackInitialized = 0;
#endif /* LIBXML_OUTPUT_ENABLED*/

    gs->xmlCurrentExternalEntityLoader = xmlDefaultExternalEntityLoader;

//  gs->xmlMemInitialized = 0;
//  gs->debugMemSize = 0;
//  gs->debugMaxMemSize = 0;
//  gs->xmlMemMutex = NULL;
//  gs->block = 0;
//  gs->xmlMemStopAtBlock = 0;
//  gs->xmlMemTraceBlockAt = NULL;

//#ifdef LIBXML_TREE_ENABLED
//  gs->__xmlRegisterCallbacks = 0;
//#endif
#ifdef LIBXML_TREE_ENABLED
    // TODO: Are these constants? If yes then move them away from here!
//  gs->xmlCompressMode = 0;
    gs->xmlCheckDTD = 1;
#endif

#ifdef LIBXML_CATALOG_ENABLED
//  gs->xmlDebugCatalogs = 0;
    gs->xmlCatalogDefaultAllow = XML_CATA_ALLOW_ALL;
    gs->xmlCatalogDefaultPrefer = XML_CATA_PREFER_PUBLIC;
//  gs->xmlCatalogXMLFiles = NULL;
//  gs->xmlDefaultCatalog = NULL;
//  xmlCatalogMutex = NULL;
//  gs->xmlCatalogInitialized = 0;
#endif

#ifdef LIBXML_XPATH_ENABLED
//  gs->xmlXPathNAN = 0;
    gs->xmlXPathPINF = 1;
    gs->xmlXPathNINF = -1;
//  gs->xmlXPathNZERO = 0;
//  gs->xmlXPathInitialized = 0;
#ifndef LIBXML_THREAD_ENABLED
//  gs->xmlXPathDisableOptimizer = 0;
#endif
#   ifdef XMLENGINE_XPATH_FUNC_HASH_OPTIMIZED
    gs->xmlXPathDefineExtensionFunctionsGlobally = 1;
//  gs->xmlXPathDefaultFunctionsHash = NULL;
//  gs->xmlXPathIntermediaryExtensionFunctionsHash = NULL;
#   endif
#endif

#ifdef LIBXML_XPTR_ENABLED
//  gs->xlinkDefaultHandler = NULL;
//  gs->xlinkDefaultDetect = NULL;
#endif

    xmlMutexUnlock(xmlThrDefMutex);

    // gs->xmlOOM = gs->xeUserCount = 0; //
}
