/*
 * extensions.c: Implemetation of the extensions support
 *
 * Reference:
 *   http://www.w3.org/TR/1999/REC-xslt-19991116
 *
 * See Copyright for the status of this software.
 *
 * daniel@veillard.com
 */

#define IN_LIBXSLT
#include "libxslt.h"

#include <string.h>
#include <limits.h>

#include <libxml/xmlmemory.h>
#include <libxml/tree.h>
#include <libxml/hash.h>
#include <libxml/xmlerror.h>
#include <libxml/parserInternals.h>
#include <libxml/xpathInternals.h>
#ifdef WITH_MODULES
#include <libxml/xmlmodule.h>
#endif
#include <libxml/list.h>
#include <libxml/xmlIO.h>
#include "xslt.h"
#include "xsltInternals.h"
#include "xsltutils.h"
#include "imports.h"
#include "extensions.h"

#ifdef _WIN32
#include <stdlib.h>             /* for _MAX_PATH */
#ifndef PATH_MAX
#define PATH_MAX _MAX_PATH
#endif
#endif

#ifdef WITH_XSLT_DEBUG
#define WITH_XSLT_DEBUG_EXTENSIONS
#endif

/************************************************************************
 * 									*
 * 			Private Types and Globals			*
 * 									*
 ************************************************************************/

typedef struct _xsltExtDef xsltExtDef;
typedef xsltExtDef *xsltExtDefPtr;
struct _xsltExtDef {
    struct _xsltExtDef *next;
    xmlChar *prefix;
    xmlChar *URI;
    void *data;
};

typedef struct _xsltExtModule xsltExtModule;
typedef xsltExtModule *xsltExtModulePtr;
struct _xsltExtModule {
    xsltExtInitFunction initFunc;
    xsltExtShutdownFunction shutdownFunc;
    xsltStyleExtInitFunction styleInitFunc;
    xsltStyleExtShutdownFunction styleShutdownFunc;
};

typedef struct _xsltExtData xsltExtData;
typedef xsltExtData *xsltExtDataPtr;
struct _xsltExtData {
    xsltExtModulePtr extModule;
    void *extData;
};

typedef struct _xsltExtElement xsltExtElement;
typedef xsltExtElement *xsltExtElementPtr;
struct _xsltExtElement {
    xsltPreComputeFunction precomp;
    xsltTransformFunction transform;
};

static xmlHashTablePtr xsltExtensionsHash = NULL;
static xmlHashTablePtr xsltFunctionsHash = NULL;
static xmlHashTablePtr xsltElementsHash = NULL;
static xmlHashTablePtr xsltTopLevelsHash = NULL;
static xmlHashTablePtr xsltModuleHash = NULL;
static xmlMutexPtr xsltExtMutex = NULL;

/************************************************************************
 * 									*
 * 			Type functions 					*
 * 									*
 ************************************************************************/

/**
 * xsltNewExtDef:
 * @prefix:  the extension prefix
 * @URI:  the namespace URI
 *
 * Create a new XSLT ExtDef
 *
 * Returns the newly allocated xsltExtDefPtr or NULL in case of error
 */
static xsltExtDefPtr
xsltNewExtDef(const xmlChar * prefix, const xmlChar * URI)
{
    xsltExtDefPtr cur;

    cur = (xsltExtDefPtr) xmlMalloc(sizeof(xsltExtDef));
    if (cur == NULL) {
        xsltTransformError(NULL, NULL, NULL,
                           "xsltNewExtDef : malloc failed\n");
        return (NULL);
    }
    memset(cur, 0, sizeof(xsltExtDef));
    if (prefix != NULL)
        cur->prefix = xmlStrdup(prefix);
    if (URI != NULL)
        cur->URI = xmlStrdup(URI);
    return (cur);
}

/**
 * xsltFreeExtDef:
 * @extensiond:  an XSLT extension definition
 *
 * Free up the memory allocated by @extensiond
 */
static void
xsltFreeExtDef(xsltExtDefPtr extensiond)
{
    if (extensiond == NULL)
        return;
    if (extensiond->prefix != NULL)
        xmlFree(extensiond->prefix);
    if (extensiond->URI != NULL)
        xmlFree(extensiond->URI);
    xmlFree(extensiond);
}

/**
 * xsltFreeExtDefList:
 * @extensiond:  an XSLT extension definition list
 *
 * Free up the memory allocated by all the elements of @extensiond
 */
static void
xsltFreeExtDefList(xsltExtDefPtr extensiond)
{
    xsltExtDefPtr cur;

    while (extensiond != NULL) {
        cur = extensiond;
        extensiond = extensiond->next;
        xsltFreeExtDef(cur);
    }
}

/**
 * xsltNewExtModule:
 * @initFunc:  the module initialization function
 * @shutdownFunc:  the module shutdown function
 * @styleInitFunc:  the stylesheet module data allocator function
 * @styleShutdownFunc:  the stylesheet module data free function
 *
 * Create a new XSLT extension module
 *
 * Returns the newly allocated xsltExtModulePtr or NULL in case of error
 */
static xsltExtModulePtr
xsltNewExtModule(xsltExtInitFunction initFunc,
                 xsltExtShutdownFunction shutdownFunc,
                 xsltStyleExtInitFunction styleInitFunc,
                 xsltStyleExtShutdownFunction styleShutdownFunc)
{
    xsltExtModulePtr cur;

    cur = (xsltExtModulePtr) xmlMalloc(sizeof(xsltExtModule));
    if (cur == NULL) {
        xsltTransformError(NULL, NULL, NULL,
                           "xsltNewExtModule : malloc failed\n");
        return (NULL);
    }
    cur->initFunc = initFunc;
    cur->shutdownFunc = shutdownFunc;
    cur->styleInitFunc = styleInitFunc;
    cur->styleShutdownFunc = styleShutdownFunc;
    return (cur);
}

/**
 * xsltFreeExtModule:
 * @ext:  an XSLT extension module
 *
 * Free up the memory allocated by @ext
 */
static void
xsltFreeExtModule(xsltExtModulePtr ext)
{
    if (ext == NULL)
        return;
    xmlFree(ext);
}

/**
 * xsltNewExtData:
 * @extModule:  the module
 * @extData:  the associated data
 *
 * Create a new XSLT extension module data wrapper
 *
 * Returns the newly allocated xsltExtDataPtr or NULL in case of error
 */
static xsltExtDataPtr
xsltNewExtData(xsltExtModulePtr extModule, void *extData)
{
    xsltExtDataPtr cur;

    if (extModule == NULL)
        return (NULL);
    cur = (xsltExtDataPtr) xmlMalloc(sizeof(xsltExtData));
    if (cur == NULL) {
        xsltTransformError(NULL, NULL, NULL,
                           "xsltNewExtData : malloc failed\n");
        return (NULL);
    }
    cur->extModule = extModule;
    cur->extData = extData;
    return (cur);
}

/**
 * xsltFreeExtData:
 * @ext:  an XSLT extension module data wrapper
 *
 * Free up the memory allocated by @ext
 */
static void
xsltFreeExtData(xsltExtDataPtr ext)
{
    if (ext == NULL)
        return;
    xmlFree(ext);
}

/**
 * xsltNewExtElement:
 * @precomp:  the pre-computation function
 * @transform:  the transformation function
 *
 * Create a new XSLT extension element
 *
 * Returns the newly allocated xsltExtElementPtr or NULL in case of
 * error
 */
static xsltExtElementPtr
xsltNewExtElement(xsltPreComputeFunction precomp,
                  xsltTransformFunction transform)
{
    xsltExtElementPtr cur;

    if (transform == NULL)
        return (NULL);

    cur = (xsltExtElementPtr) xmlMalloc(sizeof(xsltExtElement));
    if (cur == NULL) {
        xsltTransformError(NULL, NULL, NULL,
                           "xsltNewExtElement : malloc failed\n");
        return (NULL);
    }
    cur->precomp = precomp;
    cur->transform = transform;
    return (cur);
}

/**
 * xsltFreeExtElement:
 * @ext: an XSLT extension element
 *
 * Frees up the memory allocated by @ext
 */
static void
xsltFreeExtElement(xsltExtElementPtr ext)
{
    if (ext == NULL)
        return;
    xmlFree(ext);
}


#ifdef WITH_MODULES
typedef void (*exsltRegisterFunction) (void);

#ifndef PATH_MAX
#define PATH_MAX 4096
#endif

/**
 * xsltExtModuleRegisterDynamic:
 * @URI:  the function or element namespace URI
 *
 * Dynamically loads an extension plugin when available.
 * 
 * The plugin name is derived from the URI by removing the 
 * initial protocol designation, e.g. "http://", then converting
 * the characters ".", "-", "/", and "\" into "_", the removing
 * any trailing "/", then concatenating LIBXML_MODULE_EXTENSION.
 * 
 * Plugins are loaded from the directory specified by the 
 * environment variable LIBXSLT_PLUGINS_PATH, or if NULL, 
 * by LIBXSLT_DEFAULT_PLUGINS_PATH() which is determined at
 * compile time.
 *
 * Returns 0 if successful, -1 in case of error. 
 */

static int
xsltExtModuleRegisterDynamic(const xmlChar * URI)
{

    xmlModulePtr m;
    exsltRegisterFunction regfunc;
    xmlChar *ext_name;
    char module_filename[PATH_MAX];
    const xmlChar *ext_directory = NULL;
    const xmlChar *protocol = NULL;
    xmlChar *i, *regfunc_name;
    void *vregfunc;
    int rc;

    /* check for bad inputs */
    if (URI == NULL)
        return (-1);

    if (NULL == xsltModuleHash) {
        xsltModuleHash = xmlHashCreate(5);
        if (xsltModuleHash == NULL)
            return (-1);
    }

    xmlMutexLock(xsltExtMutex);

    /* have we attempted to register this module already? */
    if (xmlHashLookup(xsltModuleHash, URI) != NULL) {
        xmlMutexUnlock(xsltExtMutex);
        return (-1);
    }
    xmlMutexUnlock(xsltExtMutex);

    /* transform extension namespace into a module name */
    protocol = xmlStrstr(URI, BAD_CAST "://");
    if (protocol == NULL) {
        ext_name = xmlStrdup(URI);
    } else {
        ext_name = xmlStrdup(protocol + 3);
    }
    if (ext_name == NULL) {
        return (-1);
    }

    i = ext_name;
    while ('\0' != *i) {
        if (('/' == *i) || ('\\' == *i) || ('.' == *i) || ('-' == *i))
            *i = '_';
        i++;
    }

    if (*(i - 1) == '_')
        *i = '\0';

    /* determine module directory */
    ext_directory = (xmlChar *) getenv("LIBXSLT_PLUGINS_PATH");

    if (NULL == ext_directory) {
        ext_directory = BAD_CAST LIBXSLT_DEFAULT_PLUGINS_PATH();
	if (NULL == ext_directory)
	  return (-1);
    }
#ifdef WITH_XSLT_DEBUG_EXTENSIONS
    else
      xsltGenericDebug(xsltGenericDebugContext,
		       "LIBXSLT_PLUGINS_PATH is %s\n", ext_directory);
#endif

    /* build the module filename, and confirm the module exists */
    xmlStrPrintf((xmlChar *) module_filename, sizeof(module_filename),
                 BAD_CAST "%s/%s%s",
                 ext_directory, ext_name, LIBXML_MODULE_EXTENSION);

#ifdef WITH_XSLT_DEBUG_EXTENSIONS
    xsltGenericDebug(xsltGenericDebugContext,
                     "Attempting to load plugin: %s for URI: %s\n", 
                     module_filename, URI);
#endif

    if (1 != xmlCheckFilename(module_filename)) {

#ifdef WITH_XSLT_DEBUG_EXTENSIONS
	xsltGenericDebug(xsltGenericDebugContext,
                     "xmlCheckFilename failed for plugin: %s\n", module_filename);
#endif

        xmlFree(ext_name);
        return (-1);
    }

    /* attempt to open the module */
    m = xmlModuleOpen(module_filename, 0);
    if (NULL == m) {

#ifdef WITH_XSLT_DEBUG_EXTENSIONS
	xsltGenericDebug(xsltGenericDebugContext,
                     "xmlModuleOpen failed for plugin: %s\n", module_filename);
#endif

        xmlFree(ext_name);
        return (-1);
    }

    /* construct initialization func name */
    regfunc_name = xmlStrdup(ext_name);
    regfunc_name = xmlStrcat(regfunc_name, BAD_CAST "_init");

    vregfunc = NULL;
    rc = xmlModuleSymbol(m, (const char *) regfunc_name, &vregfunc);
    regfunc = vregfunc;
    if (0 == rc) {
        /*
	 * Call the module's init function.  Note that this function
	 * calls xsltRegisterExtModuleFull which will add the module
	 * to xsltExtensionsHash (together with it's entry points).
	 */
        (*regfunc) ();

        /* register this module in our hash */
        xmlMutexLock(xsltExtMutex);
        xmlHashAddEntry(xsltModuleHash, URI, (void *) m);
        xmlMutexUnlock(xsltExtMutex);
    } else {

#ifdef WITH_XSLT_DEBUG_EXTENSIONS
	xsltGenericDebug(xsltGenericDebugContext,
                     "xmlModuleSymbol failed for plugin: %s, regfunc: %s\n", 
                     module_filename, regfunc_name);
#endif

        /* if regfunc not found unload the module immediately */
        xmlModuleClose(m);
    }

    xmlFree(ext_name);
    xmlFree(regfunc_name);
    return (NULL == regfunc) ? -1 : 0;
}
#else
static int
xsltExtModuleRegisterDynamic(const xmlChar * URI ATTRIBUTE_UNUSED)
{
  return -1;
}
#endif

/************************************************************************
 * 									*
 * 		The stylesheet extension prefixes handling		*
 * 									*
 ************************************************************************/


/**
 * xsltFreeExts:
 * @style: an XSLT stylesheet
 *
 * Free up the memory used by XSLT extensions in a stylesheet
 */
void
xsltFreeExts(xsltStylesheetPtr style)
{
    if (style->nsDefs != NULL)
        xsltFreeExtDefList((xsltExtDefPtr) style->nsDefs);
}

/**
 * xsltRegisterExtPrefix:
 * @style: an XSLT stylesheet
 * @prefix: the prefix used (optional)
 * @URI: the URI associated to the extension
 * 
 * Registers an extension namespace
 * This is called from xslt.c during compile-time.
 * The given prefix is not needed.
 * Called by:
 *   xsltParseExtElemPrefixes() (new function)
 *   xsltRegisterExtPrefix() (old function)
 *
 * Returns 0 in case of success, 1 if the @URI was already
 *         registered as an extension namespace and
 *         -1 in case of failure
 */
int
xsltRegisterExtPrefix(xsltStylesheetPtr style,
                      const xmlChar * prefix, const xmlChar * URI)
{
    xsltExtDefPtr def, ret;

    if ((style == NULL) || (URI == NULL))
        return (-1);

#ifdef WITH_XSLT_DEBUG_EXTENSIONS
    xsltGenericDebug(xsltGenericDebugContext,
	"Registering extension namespace '%s'.\n", URI);
#endif
    def = (xsltExtDefPtr) style->nsDefs;
#ifdef XSLT_REFACTORED
    /*
    * The extension is associated with a namespace name.
    */
    while (def != NULL) {
        if (xmlStrEqual(URI, def->URI))
            return (1);
        def = def->next;
    }
#else
    while (def != NULL) {
        if (xmlStrEqual(prefix, def->prefix))
            return (-1);
        def = def->next;
    }
#endif
    ret = xsltNewExtDef(prefix, URI);
    if (ret == NULL)
        return (-1);
    ret->next = (xsltExtDefPtr) style->nsDefs;
    style->nsDefs = ret;

    /*
     * check whether there is an extension module with a stylesheet
     * initialization function.
     */
#ifdef XSLT_REFACTORED
    /*
    * Don't initialize modules based on specified namespaces via
    * the attribute "[xsl:]extension-element-prefixes".
    */
#else
    if (xsltExtensionsHash != NULL) {
        xsltExtModulePtr module;

        xmlMutexLock(xsltExtMutex);
        module = xmlHashLookup(xsltExtensionsHash, URI);
        xmlMutexUnlock(xsltExtMutex);
        if (NULL == module) {
            if (!xsltExtModuleRegisterDynamic(URI)) {
                xmlMutexLock(xsltExtMutex);
                module = xmlHashLookup(xsltExtensionsHash, URI);
                xmlMutexUnlock(xsltExtMutex);
            }
        }
        if (module != NULL) {
            xsltStyleGetExtData(style, URI);
        }
    }
#endif
    return (0);
}

/************************************************************************
 * 									*
 * 		The extensions modules interfaces			*
 * 									*
 ************************************************************************/

/**
 * xsltRegisterExtFunction:
 * @ctxt: an XSLT transformation context
 * @name: the name of the element
 * @URI: the URI associated to the element
 * @function: the actual implementation which should be called 
 *
 * Registers an extension function
 *
 * Returns 0 in case of success, -1 in case of failure
 */
int
xsltRegisterExtFunction(xsltTransformContextPtr ctxt, const xmlChar * name,
                        const xmlChar * URI, xmlXPathFunction function)
{
    int ret;

    if ((ctxt == NULL) || (name == NULL) ||
        (URI == NULL) || (function == NULL))
        return (-1);
    if (ctxt->xpathCtxt != NULL) {
        xmlXPathRegisterFuncNS(ctxt->xpathCtxt, name, URI, function);
    }
    if (ctxt->extFunctions == NULL)
        ctxt->extFunctions = xmlHashCreate(10);
    if (ctxt->extFunctions == NULL)
        return (-1);

    ret = xmlHashAddEntry2(ctxt->extFunctions, name, URI,
                           XML_CAST_FPTR(function));

    return(ret);
}

/**
 * xsltRegisterExtElement:
 * @ctxt: an XSLT transformation context
 * @name: the name of the element
 * @URI: the URI associated to the element
 * @function: the actual implementation which should be called 
 *
 * Registers an extension element
 *
 * Returns 0 in case of success, -1 in case of failure
 */
int
xsltRegisterExtElement(xsltTransformContextPtr ctxt, const xmlChar * name,
                       const xmlChar * URI, xsltTransformFunction function)
{
    if ((ctxt == NULL) || (name == NULL) ||
        (URI == NULL) || (function == NULL))
        return (-1);
    if (ctxt->extElements == NULL)
        ctxt->extElements = xmlHashCreate(10);
    if (ctxt->extElements == NULL)
        return (-1);
    return (xmlHashAddEntry2
            (ctxt->extElements, name, URI, XML_CAST_FPTR(function)));
}

/**
 * xsltFreeCtxtExts:
 * @ctxt: an XSLT transformation context
 *
 * Free the XSLT extension data
 */
void
xsltFreeCtxtExts(xsltTransformContextPtr ctxt)
{
    if (ctxt->extElements != NULL)
        xmlHashFree(ctxt->extElements, NULL);
    if (ctxt->extFunctions != NULL)
        xmlHashFree(ctxt->extFunctions, NULL);
}

/**
 * xsltStyleGetStylesheetExtData:
 * @style: an XSLT stylesheet
 * @URI:  the URI associated to the exension module
 *
 * Fires the compile-time initialization callback
 * of an extension module and returns a container
 * holding the user-data (retrieved via the callback).
 *
 * Returns the create module-data container
 *         or NULL if such a module was not registered.
 */
static xsltExtDataPtr
xsltStyleInitializeStylesheetModule(xsltStylesheetPtr style,
				     const xmlChar * URI)
{
    xsltExtDataPtr dataContainer;
    void *userData = NULL;
    xsltExtModulePtr module;
    
    if ((style == NULL) || (URI == NULL))	
	return(NULL);

    if (xsltExtensionsHash == NULL) {
#ifdef WITH_XSLT_DEBUG_EXTENSIONS
	xsltGenericDebug(xsltGenericDebugContext,
	    "Not registered extension module: %s\n", URI);
#endif
	return(NULL);
    }

    xmlMutexLock(xsltExtMutex);

    module = xmlHashLookup(xsltExtensionsHash, URI);

    xmlMutexUnlock(xsltExtMutex);

    if (module == NULL) {
#ifdef WITH_XSLT_DEBUG_EXTENSIONS
	xsltGenericDebug(xsltGenericDebugContext,
	    "Not registered extension module: %s\n", URI);
#endif
	return (NULL);
    }
    /*
    * The specified module was registered so initialize it.
    */
    if (style->extInfos == NULL) {
	style->extInfos = xmlHashCreate(10);
	if (style->extInfos == NULL)
	    return (NULL);
    }
    /*
    * Fire the initialization callback if available.
    */
    if (module->styleInitFunc == NULL) {
#ifdef WITH_XSLT_DEBUG_EXTENSIONS
	xsltGenericDebug(xsltGenericDebugContext,
	    "Initializing module with *no* callback: %s\n", URI);
#endif
    } else {
#ifdef WITH_XSLT_DEBUG_EXTENSIONS
	xsltGenericDebug(xsltGenericDebugContext,
	    "Initializing module with callback: %s\n", URI);
#endif
	/*
	* Fire the initialization callback.
	*/
	userData = module->styleInitFunc(style, URI);
    }    
    /*
    * Store the user-data in the context of the given stylesheet.
    */
    dataContainer = xsltNewExtData(module, userData);
    if (dataContainer == NULL)
	return (NULL);

    if (xmlHashAddEntry(style->extInfos, URI,
	(void *) dataContainer) < 0)
    {
	xsltTransformError(NULL, style, NULL,	    
	    "Failed to register module '%s'.\n", URI);
	style->errors++;
	if (module->styleShutdownFunc)
	    module->styleShutdownFunc(style, URI, userData);
	xsltFreeExtData(dataContainer);
	return (NULL);
    }

    return(dataContainer);
}

/**
 * xsltStyleGetExtData:
 * @style: an XSLT stylesheet
 * @URI:  the URI associated to the exension module
 *
 * Retrieve the data associated to the extension module
 * in this given stylesheet.
 * Called by:
 *   xsltRegisterExtPrefix(),
 *   ( xsltExtElementPreCompTest(), xsltExtInitTest )
 *
 * Returns the pointer or NULL if not present
 */
void *
xsltStyleGetExtData(xsltStylesheetPtr style, const xmlChar * URI)
{
    xsltExtDataPtr dataContainer = NULL;
    xsltStylesheetPtr tmpStyle;

    if ((style == NULL) || (URI == NULL) ||
	(xsltExtensionsHash == NULL))
	return (NULL);

    
#ifdef XSLT_REFACTORED
    /*
    * This is intended for global storage, so only the main
    * stylesheet will hold the data.
    */
    tmpStyle = style;
    while (tmpStyle->parent != NULL)
	tmpStyle = tmpStyle->parent;
    if (tmpStyle->extInfos != NULL) {
	dataContainer =
	    (xsltExtDataPtr) xmlHashLookup(tmpStyle->extInfos, URI);
	if (dataContainer != NULL) {
	    /*
	    * The module was already initialized in the context
	    * of this stylesheet; just return the user-data that
	    * comes with it.
	    */
	    return(dataContainer->extData);
	}
    }
#else
    /*
    * Old behaviour.
    */
    tmpStyle = style;
    while (tmpStyle != NULL) {
	if (tmpStyle->extInfos != NULL) {
	    dataContainer =
		(xsltExtDataPtr) xmlHashLookup(tmpStyle->extInfos, URI);
	    if (dataContainer != NULL) {
		return(dataContainer->extData);
	    }
	}
	tmpStyle = xsltNextImport(tmpStyle);
    }
    tmpStyle = style;
#endif

    dataContainer =
        xsltStyleInitializeStylesheetModule(tmpStyle, URI);
    if (dataContainer != NULL)
	return (dataContainer->extData);
    return(NULL);
}

#ifdef XSLT_REFACTORED
/**
 * xsltStyleStylesheetLevelGetExtData:
 * @style: an XSLT stylesheet
 * @URI:  the URI associated to the exension module
 *
 * Retrieve the data associated to the extension module in this given
 * stylesheet.
 *
 * Returns the pointer or NULL if not present
 */
void *
xsltStyleStylesheetLevelGetExtData(xsltStylesheetPtr style,
				   const xmlChar * URI)
{
    xsltExtDataPtr dataContainer = NULL;

    if ((style == NULL) || (URI == NULL) ||
	(xsltExtensionsHash == NULL))
	return (NULL);

    if (style->extInfos != NULL) {
	dataContainer = (xsltExtDataPtr) xmlHashLookup(style->extInfos, URI);
	/*
	* The module was already initialized in the context
	* of this stylesheet; just return the user-data that
	* comes with it.
	*/
	if (dataContainer)
	    return(dataContainer->extData);
    }  

    dataContainer =
        xsltStyleInitializeStylesheetModule(style, URI);
    if (dataContainer != NULL)
	return (dataContainer->extData);
    return(NULL);
}
#endif

/**
 * xsltGetExtData:
 * @ctxt: an XSLT transformation context
 * @URI:  the URI associated to the exension module
 *
 * Retrieve the data associated to the extension module in this given
 * transformation.
 *
 * Returns the pointer or NULL if not present
 */
void *
xsltGetExtData(xsltTransformContextPtr ctxt, const xmlChar * URI)
{
    xsltExtDataPtr data;

    if ((ctxt == NULL) || (URI == NULL))
        return (NULL);
    if (ctxt->extInfos == NULL) {
        ctxt->extInfos = xmlHashCreate(10);
        if (ctxt->extInfos == NULL)
            return (NULL);
        data = NULL;
    } else {
        data = (xsltExtDataPtr) xmlHashLookup(ctxt->extInfos, URI);
    }
    if (data == NULL) {
        void *extData;
        xsltExtModulePtr module;

        xmlMutexLock(xsltExtMutex);

        module = xmlHashLookup(xsltExtensionsHash, URI);

        xmlMutexUnlock(xsltExtMutex);

        if (module == NULL) {
#ifdef WITH_XSLT_DEBUG_EXTENSIONS
            xsltGenericDebug(xsltGenericDebugContext,
                             "Not registered extension module: %s\n", URI);
#endif
            return (NULL);
        } else {
            if (module->initFunc == NULL)
                return (NULL);

#ifdef WITH_XSLT_DEBUG_EXTENSIONS
            xsltGenericDebug(xsltGenericDebugContext,
                             "Initializing module: %s\n", URI);
#endif

            extData = module->initFunc(ctxt, URI);
            if (extData == NULL)
                return (NULL);

            data = xsltNewExtData(module, extData);
            if (data == NULL)
                return (NULL);
            if (xmlHashAddEntry(ctxt->extInfos, URI, (void *) data) < 0) {
                xsltTransformError(ctxt, NULL, NULL,
                                   "Failed to register module data: %s\n",
                                   URI);
                if (module->shutdownFunc)
                    module->shutdownFunc(ctxt, URI, extData);
                xsltFreeExtData(data);
                return (NULL);
            }
        }
    }
    return (data->extData);
}

typedef struct _xsltInitExtCtxt xsltInitExtCtxt;
struct _xsltInitExtCtxt {
    xsltTransformContextPtr ctxt;
    int ret;
};

/**
 * xsltInitCtxtExt:
 * @styleData:  the registered stylesheet data for the module
 * @ctxt:  the XSLT transformation context + the return value
 * @URI:  the extension URI
 *
 * Initializes an extension module
 */
static void
xsltInitCtxtExt(xsltExtDataPtr styleData, xsltInitExtCtxt * ctxt,
                const xmlChar * URI)
{
    xsltExtModulePtr module;
    xsltExtDataPtr ctxtData;
    void *extData;

    if ((styleData == NULL) || (ctxt == NULL) || (URI == NULL) ||
        (ctxt->ret == -1)) {
#ifdef WITH_XSLT_DEBUG_EXTENSIONS
        xsltGenericDebug(xsltGenericDebugContext,
                         "xsltInitCtxtExt: NULL param or error\n");
#endif
        return;
    }
    module = styleData->extModule;
    if ((module == NULL) || (module->initFunc == NULL)) {
#ifdef WITH_XSLT_DEBUG_EXTENSIONS
        xsltGenericDebug(xsltGenericDebugContext,
                         "xsltInitCtxtExt: no module or no initFunc\n");
#endif
        return;
    }

    ctxtData = (xsltExtDataPtr) xmlHashLookup(ctxt->ctxt->extInfos, URI);
    if (ctxtData != NULL) {
#ifdef WITH_XSLT_DEBUG_EXTENSIONS
        xsltGenericDebug(xsltGenericDebugContext,
                         "xsltInitCtxtExt: already initialized\n");
#endif
        return;
    }

    extData = module->initFunc(ctxt->ctxt, URI);
    if (extData == NULL) {
#ifdef WITH_XSLT_DEBUG_EXTENSIONS
        xsltGenericDebug(xsltGenericDebugContext,
                         "xsltInitCtxtExt: no extData\n");
#endif
    }
    ctxtData = xsltNewExtData(module, extData);
    if (ctxtData == NULL) {
        ctxt->ret = -1;
        return;
    }

    if (ctxt->ctxt->extInfos == NULL)
        ctxt->ctxt->extInfos = xmlHashCreate(10);
    if (ctxt->ctxt->extInfos == NULL) {
        ctxt->ret = -1;
        return;
    }

    if (xmlHashAddEntry(ctxt->ctxt->extInfos, URI, ctxtData) < 0) {
        xsltGenericError(xsltGenericErrorContext,
                         "Failed to register module data: %s\n", URI);
        if (module->shutdownFunc)
            module->shutdownFunc(ctxt->ctxt, URI, extData);
        xsltFreeExtData(ctxtData);
        ctxt->ret = -1;
        return;
    }
#ifdef WITH_XSLT_DEBUG_EXTENSIONS
    xsltGenericDebug(xsltGenericDebugContext, "Registered module %s\n",
                     URI);
#endif
    ctxt->ret++;
}

/**
 * xsltInitCtxtExts:
 * @ctxt: an XSLT transformation context
 *
 * Initialize the set of modules with registered stylesheet data
 *
 * Returns the number of modules initialized or -1 in case of error
 */
int
xsltInitCtxtExts(xsltTransformContextPtr ctxt)
{
    xsltStylesheetPtr style;
    xsltInitExtCtxt ctx;

    if (ctxt == NULL)
        return (-1);

    style = ctxt->style;
    if (style == NULL)
        return (-1);

    ctx.ctxt = ctxt;
    ctx.ret = 0;

    while (style != NULL) {
        if (style->extInfos != NULL) {
            xmlHashScan(style->extInfos,
                        (xmlHashScanner) xsltInitCtxtExt, &ctx);
            if (ctx.ret == -1)
                return (-1);
        }
        style = xsltNextImport(style);
    }
#ifdef WITH_XSLT_DEBUG_EXTENSIONS
    xsltGenericDebug(xsltGenericDebugContext, "Registered %d modules\n",
                     ctx.ret);
#endif
    return (ctx.ret);
}

/**
 * xsltShutdownCtxtExt:
 * @data:  the registered data for the module
 * @ctxt:  the XSLT transformation context
 * @URI:  the extension URI
 *
 * Shutdown an extension module loaded
 */
static void
xsltShutdownCtxtExt(xsltExtDataPtr data, xsltTransformContextPtr ctxt,
                    const xmlChar * URI)
{
    xsltExtModulePtr module;

    if ((data == NULL) || (ctxt == NULL) || (URI == NULL))
        return;
    module = data->extModule;
    if ((module == NULL) || (module->shutdownFunc == NULL))
        return;

#ifdef WITH_XSLT_DEBUG_EXTENSIONS
    xsltGenericDebug(xsltGenericDebugContext,
                     "Shutting down module : %s\n", URI);
#endif
    module->shutdownFunc(ctxt, URI, data->extData);
}

/**
 * xsltShutdownCtxtExts:
 * @ctxt: an XSLT transformation context
 *
 * Shutdown the set of modules loaded
 */
void
xsltShutdownCtxtExts(xsltTransformContextPtr ctxt)
{
    if (ctxt == NULL)
        return;
    if (ctxt->extInfos == NULL)
        return;
    xmlHashScan(ctxt->extInfos, (xmlHashScanner) xsltShutdownCtxtExt,
                ctxt);
    xmlHashFree(ctxt->extInfos, (xmlHashDeallocator) xsltFreeExtData);
    ctxt->extInfos = NULL;
}

/**
 * xsltShutdownExt:
 * @data:  the registered data for the module
 * @ctxt:  the XSLT stylesheet
 * @URI:  the extension URI
 *
 * Shutdown an extension module loaded
 */
static void
xsltShutdownExt(xsltExtDataPtr data, xsltStylesheetPtr style,
                const xmlChar * URI)
{
    xsltExtModulePtr module;

    if ((data == NULL) || (style == NULL) || (URI == NULL))
        return;
    module = data->extModule;
    if ((module == NULL) || (module->styleShutdownFunc == NULL))
        return;

#ifdef WITH_XSLT_DEBUG_EXTENSIONS
    xsltGenericDebug(xsltGenericDebugContext,
                     "Shutting down module : %s\n", URI);
#endif
    module->styleShutdownFunc(style, URI, data->extData);
    /*
    * Don't remove the entry from the hash table here, since
    * this will produce segfaults - this fixes bug #340624.
    *
    * xmlHashRemoveEntry(style->extInfos, URI,
    *   (xmlHashDeallocator) xsltFreeExtData);
    */    
}

/**
 * xsltShutdownExts:
 * @style: an XSLT stylesheet
 *
 * Shutdown the set of modules loaded
 */
void
xsltShutdownExts(xsltStylesheetPtr style)
{
    if (style == NULL)
        return;
    if (style->extInfos == NULL)
        return;
    xmlHashScan(style->extInfos, (xmlHashScanner) xsltShutdownExt, style);
    xmlHashFree(style->extInfos, (xmlHashDeallocator) xsltFreeExtData);
    style->extInfos = NULL;
}

/**
 * xsltCheckExtPrefix:
 * @style: the stylesheet
 * @URI: the namespace prefix (possibly NULL)
 *
 * Check if the given prefix is one of the declared extensions.
 * This is intended to be called only at compile-time.
 * Called by:
 *  xsltGetInheritedNsList() (xslt.c)
 *  xsltParseTemplateContent (xslt.c)
 *
 * Returns 1 if this is an extension, 0 otherwise
 */
int
xsltCheckExtPrefix(xsltStylesheetPtr style, const xmlChar * URI)
{    
#ifdef XSLT_REFACTORED
    if ((style == NULL) || (style->compCtxt == NULL) ||
	(XSLT_CCTXT(style)->inode == NULL) ||
	(XSLT_CCTXT(style)->inode->extElemNs == NULL))
        return (0);    
    /*
    * Lookup the extension namespaces registered
    * at the current node in the stylesheet's tree.
    */
    if (XSLT_CCTXT(style)->inode->extElemNs != NULL) {
	int i;
	xsltPointerListPtr list = XSLT_CCTXT(style)->inode->extElemNs;

	for (i = 0; i < list->number; i++) {
	    if (xmlStrEqual((const xmlChar *) list->items[i],
		URI))
	    {
		return(1);
	    }	    
	}
    }
#else
    xsltExtDefPtr cur;

    if ((style == NULL) || (style->nsDefs == NULL))
        return (0);
    if (URI == NULL)
        URI = BAD_CAST "#default";
    cur = (xsltExtDefPtr) style->nsDefs;
    while (cur != NULL) {
	/*
	* NOTE: This was change to work on namespace names rather
	* than namespace prefixes. This fixes bug #339583.
	* TODO: Consider renaming the field "prefix" of xsltExtDef
	*  to "href".
	*/
        if (xmlStrEqual(URI, cur->prefix))
            return (1);
        cur = cur->next;
    }
#endif
    return (0);
}

/**
 * xsltCheckExtURI:
 * @style: the stylesheet
 * @URI: the namespace URI (possibly NULL)
 *
 * Check if the given prefix is one of the declared extensions.
 * This is intended to be called only at compile-time.
 * Called by:
 *  xsltPrecomputeStylesheet() (xslt.c)
 *  xsltParseTemplateContent (xslt.c)
 *
 * Returns 1 if this is an extension, 0 otherwise
 */
int
xsltCheckExtURI(xsltStylesheetPtr style, const xmlChar * URI)
{
    xsltExtDefPtr cur;

    if ((style == NULL) || (style->nsDefs == NULL))
        return (0);
    if (URI == NULL)
        return (0);
    cur = (xsltExtDefPtr) style->nsDefs;
    while (cur != NULL) {
        if (xmlStrEqual(URI, cur->URI))
            return (1);
        cur = cur->next;
    }
    return (0);
}

/**
 * xsltRegisterExtModuleFull:
 * @URI:  URI associated to this module
 * @initFunc:  the module initialization function
 * @shutdownFunc:  the module shutdown function
 * @styleInitFunc:  the module initialization function
 * @styleShutdownFunc:  the module shutdown function
 *
 * Register an XSLT extension module to the library.
 *
 * Returns 0 if sucessful, -1 in case of error
 */
int
xsltRegisterExtModuleFull(const xmlChar * URI,
                          xsltExtInitFunction initFunc,
                          xsltExtShutdownFunction shutdownFunc,
                          xsltStyleExtInitFunction styleInitFunc,
                          xsltStyleExtShutdownFunction styleShutdownFunc)
{
    int ret;
    xsltExtModulePtr module;

    if ((URI == NULL) || (initFunc == NULL))
        return (-1);
    if (xsltExtensionsHash == NULL)
        xsltExtensionsHash = xmlHashCreate(10);

    if (xsltExtensionsHash == NULL)
        return (-1);

    xmlMutexLock(xsltExtMutex);

    module = xmlHashLookup(xsltExtensionsHash, URI);
    if (module != NULL) {
        if ((module->initFunc == initFunc) &&
            (module->shutdownFunc == shutdownFunc))
            ret = 0;
        else
            ret = -1;
        goto done;
    }
    module = xsltNewExtModule(initFunc, shutdownFunc,
                              styleInitFunc, styleShutdownFunc);
    if (module == NULL) {
        ret = -1;
        goto done;
    }
    ret = xmlHashAddEntry(xsltExtensionsHash, URI, (void *) module);

done:
    xmlMutexUnlock(xsltExtMutex);
    return (ret);
}

/**
 * xsltRegisterExtModule:
 * @URI:  URI associated to this module
 * @initFunc:  the module initialization function
 * @shutdownFunc:  the module shutdown function
 *
 * Register an XSLT extension module to the library.
 *
 * Returns 0 if sucessful, -1 in case of error
 */
int
xsltRegisterExtModule(const xmlChar * URI,
                      xsltExtInitFunction initFunc,
                      xsltExtShutdownFunction shutdownFunc)
{
    return xsltRegisterExtModuleFull(URI, initFunc, shutdownFunc,
                                     NULL, NULL);
}

/**
 * xsltUnregisterExtModule:
 * @URI:  URI associated to this module
 *
 * Unregister an XSLT extension module from the library.
 *
 * Returns 0 if sucessful, -1 in case of error
 */
int
xsltUnregisterExtModule(const xmlChar * URI)
{
    int ret;

    if (URI == NULL)
        return (-1);
    if (xsltExtensionsHash == NULL)
        return (-1);

    xmlMutexLock(xsltExtMutex);

    ret = xmlHashRemoveEntry(xsltExtensionsHash, URI,
                             (xmlHashDeallocator) xsltFreeExtModule);

    xmlMutexUnlock(xsltExtMutex);

    return (ret);
}

/**
 * xsltUnregisterAllExtModules:
 *
 * Unregister all the XSLT extension module from the library.
 */
static void
xsltUnregisterAllExtModules(void)
{
    if (xsltExtensionsHash == NULL)
        return;

    xmlMutexLock(xsltExtMutex);

    xmlHashFree(xsltExtensionsHash,
                (xmlHashDeallocator) xsltFreeExtModule);
    xsltExtensionsHash = NULL;

    xmlMutexUnlock(xsltExtMutex);
}

/**
 * xsltXPathGetTransformContext:
 * @ctxt:  an XPath transformation context
 *
 * Provides the XSLT transformation context from the XPath transformation
 * context. This is useful when an XPath function in the extension module
 * is called by the XPath interpreter and that the XSLT context is needed
 * for example to retrieve the associated data pertaining to this XSLT
 * transformation.
 *
 * Returns the XSLT transformation context or NULL in case of error.
 */
xsltTransformContextPtr
xsltXPathGetTransformContext(xmlXPathParserContextPtr ctxt)
{
    if ((ctxt == NULL) || (ctxt->context == NULL))
        return (NULL);
    return (ctxt->context->extra);
}

/**
 * xsltRegisterExtModuleFunction:
 * @name:  the function name
 * @URI:  the function namespace URI
 * @function:  the function callback
 *
 * Registers an extension module function.
 *
 * Returns 0 if successful, -1 in case of error.
 */
int
xsltRegisterExtModuleFunction(const xmlChar * name, const xmlChar * URI,
                              xmlXPathFunction function)
{
    if ((name == NULL) || (URI == NULL) || (function == NULL))
        return (-1);

    if (xsltFunctionsHash == NULL)
        xsltFunctionsHash = xmlHashCreate(10);
    if (xsltFunctionsHash == NULL)
        return (-1);

    xmlMutexLock(xsltExtMutex);

    xmlHashUpdateEntry2(xsltFunctionsHash, name, URI,
                        XML_CAST_FPTR(function), NULL);

    xmlMutexUnlock(xsltExtMutex);

    return (0);
}

/**
 * xsltExtModuleFunctionLookup:
 * @name:  the function name
 * @URI:  the function namespace URI
 *
 * Looks up an extension module function
 *
 * Returns the function if found, NULL otherwise.
 */
xmlXPathFunction
xsltExtModuleFunctionLookup(const xmlChar * name, const xmlChar * URI)
{
    xmlXPathFunction ret;

    if ((xsltFunctionsHash == NULL) || (name == NULL) || (URI == NULL))
        return (NULL);

    xmlMutexLock(xsltExtMutex);

    XML_CAST_FPTR(ret) = xmlHashLookup2(xsltFunctionsHash, name, URI);

    xmlMutexUnlock(xsltExtMutex);

    /* if lookup fails, attempt a dynamic load on supported platforms */
    if (NULL == ret) {
        if (!xsltExtModuleRegisterDynamic(URI)) {
            xmlMutexLock(xsltExtMutex);

            XML_CAST_FPTR(ret) =
                xmlHashLookup2(xsltFunctionsHash, name, URI);

            xmlMutexUnlock(xsltExtMutex);
        }
    }

    return ret;
}

/**
 * xsltUnregisterExtModuleFunction:
 * @name:  the function name
 * @URI:  the function namespace URI
 *
 * Unregisters an extension module function
 *
 * Returns 0 if successful, -1 in case of error.
 */
int
xsltUnregisterExtModuleFunction(const xmlChar * name, const xmlChar * URI)
{
    int ret;

    if ((xsltFunctionsHash == NULL) || (name == NULL) || (URI == NULL))
        return (-1);

    xmlMutexLock(xsltExtMutex);

    ret = xmlHashRemoveEntry2(xsltFunctionsHash, name, URI, NULL);

    xmlMutexUnlock(xsltExtMutex);

    return(ret);
}

/**
 * xsltUnregisterAllExtModuleFunction:
 *
 * Unregisters all extension module function
 */
static void
xsltUnregisterAllExtModuleFunction(void)
{
    xmlMutexLock(xsltExtMutex);

    xmlHashFree(xsltFunctionsHash, NULL);
    xsltFunctionsHash = NULL;

    xmlMutexUnlock(xsltExtMutex);
}


/**
 * xsltNewElemPreComp:
 * @style:  the XSLT stylesheet
 * @inst:  the element node
 * @function: the transform function
 *
 * Creates and initializes an #xsltElemPreComp
 *
 * Returns the new and initialized #xsltElemPreComp
 */
xsltElemPreCompPtr
xsltNewElemPreComp(xsltStylesheetPtr style, xmlNodePtr inst,
                   xsltTransformFunction function)
{
    xsltElemPreCompPtr cur;

    cur = (xsltElemPreCompPtr) xmlMalloc(sizeof(xsltElemPreComp));
    if (cur == NULL) {
        xsltTransformError(NULL, style, NULL,
                           "xsltNewExtElement : malloc failed\n");
        return (NULL);
    }
    memset(cur, 0, sizeof(xsltElemPreComp));

    xsltInitElemPreComp(cur, style, inst, function,
                        (xsltElemPreCompDeallocator) xmlFree);

    return (cur);
}

/**
 * xsltInitElemPreComp:
 * @comp:  an #xsltElemPreComp (or generally a derived structure)
 * @style:  the XSLT stylesheet
 * @inst:  the element node
 * @function:  the transform function
 * @freeFunc:  the @comp deallocator
 *
 * Initializes an existing #xsltElemPreComp structure. This is usefull
 * when extending an #xsltElemPreComp to store precomputed data.
 * This function MUST be called on any extension element precomputed
 * data struct.
 */
void
xsltInitElemPreComp(xsltElemPreCompPtr comp, xsltStylesheetPtr style,
                    xmlNodePtr inst, xsltTransformFunction function,
                    xsltElemPreCompDeallocator freeFunc)
{
    comp->type = XSLT_FUNC_EXTENSION;
    comp->func = function;
    comp->inst = inst;
    comp->free = freeFunc;

    comp->next = style->preComps;
    style->preComps = comp;
}

/**
 * xsltPreComputeExtModuleElement:
 * @style:  the stylesheet
 * @inst:  the element node
 *
 * Precomputes an extension module element
 *
 * Returns the precomputed data
 */
xsltElemPreCompPtr
xsltPreComputeExtModuleElement(xsltStylesheetPtr style, xmlNodePtr inst)
{
    xsltExtElementPtr ext;
    xsltElemPreCompPtr comp = NULL;

    if ((style == NULL) || (inst == NULL) ||
        (inst->type != XML_ELEMENT_NODE) || (inst->ns == NULL))
        return (NULL);

    xmlMutexLock(xsltExtMutex);

    ext = (xsltExtElementPtr)
        xmlHashLookup2(xsltElementsHash, inst->name, inst->ns->href);

    xmlMutexUnlock(xsltExtMutex);

    /*
    * EXT TODO: Now what?
    */
    if (ext == NULL)
        return (NULL);

    if (ext->precomp != NULL) {
	/*
	* REVISIT TODO: Check if the text below is correct.
	* This will return a xsltElemPreComp structure or NULL.
	* 1) If the the author of the extension needs a
	*  custom structure to hold the specific values of
	*  this extension, he will derive a structure based on
	*  xsltElemPreComp; thus we obviously *cannot* refactor
	*  the xsltElemPreComp structure, since all already derived
	*  user-defined strucures will break.
	*  Example: For the extension xsl:document,
	*   in xsltDocumentComp() (preproc.c), the structure
	*   xsltStyleItemDocument is allocated, filled with
	*   specific values and returned.
	* 2) If the author needs no values to be stored in
	*  this structure, then he'll return NULL;
	*/
        comp = ext->precomp(style, inst, ext->transform);
    }
    if (comp == NULL) {
	/*
	* Default creation of a xsltElemPreComp structure, if
	* the author of this extension did not create a custom
	* structure.
	*/
        comp = xsltNewElemPreComp(style, inst, ext->transform);
    }

    return (comp);
}

/**
 * xsltRegisterExtModuleElement:
 * @name:  the element name
 * @URI:  the element namespace URI
 * @precomp:  the pre-computation callback
 * @transform:  the transformation callback
 *
 * Registers an extension module element.
 *
 * Returns 0 if successful, -1 in case of error.
 */
int
xsltRegisterExtModuleElement(const xmlChar * name, const xmlChar * URI,
                             xsltPreComputeFunction precomp,
                             xsltTransformFunction transform)
{
    int ret;

    xsltExtElementPtr ext;

    if ((name == NULL) || (URI == NULL) || (transform == NULL))
        return (-1);

    if (xsltElementsHash == NULL)
        xsltElementsHash = xmlHashCreate(10);
    if (xsltElementsHash == NULL)
        return (-1);

    xmlMutexLock(xsltExtMutex);

    ext = xsltNewExtElement(precomp, transform);
    if (ext == NULL) {
        ret = -1;
        goto done;
    }

    xmlHashUpdateEntry2(xsltElementsHash, name, URI, (void *) ext,
                        (xmlHashDeallocator) xsltFreeExtElement);

done:
    xmlMutexUnlock(xsltExtMutex);

    return (0);
}

/**
 * xsltExtElementLookup:
 * @ctxt:  an XSLT process context
 * @name:  the element name
 * @URI:  the element namespace URI
 *
 * Looks up an extension element. @ctxt can be NULL to search only in
 * module elements.
 *
 * Returns the element callback or NULL if not found
 */
xsltTransformFunction
xsltExtElementLookup(xsltTransformContextPtr ctxt,
                     const xmlChar * name, const xmlChar * URI)
{
    xsltTransformFunction ret;

    if ((name == NULL) || (URI == NULL))
        return (NULL);

    if ((ctxt != NULL) && (ctxt->extElements != NULL)) {
        XML_CAST_FPTR(ret) = xmlHashLookup2(ctxt->extElements, name, URI);
        if (ret != NULL) {
            return(ret);
        }
    }

    ret = xsltExtModuleElementLookup(name, URI);

    return (ret);
}

/**
 * xsltExtModuleElementLookup:
 * @name:  the element name
 * @URI:  the element namespace URI
 *
 * Looks up an extension module element
 *
 * Returns the callback function if found, NULL otherwise.
 */
xsltTransformFunction
xsltExtModuleElementLookup(const xmlChar * name, const xmlChar * URI)
{
    xsltExtElementPtr ext;

    if ((xsltElementsHash == NULL) || (name == NULL) || (URI == NULL))
        return (NULL);

    xmlMutexLock(xsltExtMutex);

    ext = (xsltExtElementPtr) xmlHashLookup2(xsltElementsHash, name, URI);

    xmlMutexUnlock(xsltExtMutex);

    /*
     * if function lookup fails, attempt a dynamic load on
     * supported platforms
     */
    if (NULL == ext) {
        if (!xsltExtModuleRegisterDynamic(URI)) {
            xmlMutexLock(xsltExtMutex);

            ext = (xsltExtElementPtr)
	          xmlHashLookup2(xsltElementsHash, name, URI);

            xmlMutexUnlock(xsltExtMutex);
        }
    }

    if (ext == NULL)
        return (NULL);
    return (ext->transform);
}

/**
 * xsltExtModuleElementPreComputeLookup:
 * @name:  the element name
 * @URI:  the element namespace URI
 *
 * Looks up an extension module element pre-computation function
 *
 * Returns the callback function if found, NULL otherwise.
 */
xsltPreComputeFunction
xsltExtModuleElementPreComputeLookup(const xmlChar * name,
                                     const xmlChar * URI)
{
    xsltExtElementPtr ext;

    if ((xsltElementsHash == NULL) || (name == NULL) || (URI == NULL))
        return (NULL);

    xmlMutexLock(xsltExtMutex);

    ext = (xsltExtElementPtr) xmlHashLookup2(xsltElementsHash, name, URI);

    xmlMutexUnlock(xsltExtMutex);

    if (ext == NULL) {
        if (!xsltExtModuleRegisterDynamic(URI)) {
            xmlMutexLock(xsltExtMutex);

            ext = (xsltExtElementPtr)
	          xmlHashLookup2(xsltElementsHash, name, URI);

            xmlMutexUnlock(xsltExtMutex);
        }
    }

    if (ext == NULL)
        return (NULL);
    return (ext->precomp);
}

/**
 * xsltUnregisterExtModuleElement:
 * @name:  the element name
 * @URI:  the element namespace URI
 *
 * Unregisters an extension module element
 *
 * Returns 0 if successful, -1 in case of error.
 */
int
xsltUnregisterExtModuleElement(const xmlChar * name, const xmlChar * URI)
{
    int ret;

    if ((xsltElementsHash == NULL) || (name == NULL) || (URI == NULL))
        return (-1);

    xmlMutexLock(xsltExtMutex);

    ret = xmlHashRemoveEntry2(xsltElementsHash, name, URI,
                              (xmlHashDeallocator) xsltFreeExtElement);

    xmlMutexUnlock(xsltExtMutex);

    return(ret);
}

/**
 * xsltUnregisterAllExtModuleElement:
 *
 * Unregisters all extension module element
 */
static void
xsltUnregisterAllExtModuleElement(void)
{
    xmlMutexLock(xsltExtMutex);

    xmlHashFree(xsltElementsHash, (xmlHashDeallocator) xsltFreeExtElement);
    xsltElementsHash = NULL;

    xmlMutexUnlock(xsltExtMutex);
}

/**
 * xsltRegisterExtModuleTopLevel:
 * @name:  the top-level element name
 * @URI:  the top-level element namespace URI
 * @function:  the top-level element callback
 *
 * Registers an extension module top-level element.
 *
 * Returns 0 if successful, -1 in case of error.
 */
int
xsltRegisterExtModuleTopLevel(const xmlChar * name, const xmlChar * URI,
                              xsltTopLevelFunction function)
{
    if ((name == NULL) || (URI == NULL) || (function == NULL))
        return (-1);

    if (xsltTopLevelsHash == NULL)
        xsltTopLevelsHash = xmlHashCreate(10);
    if (xsltTopLevelsHash == NULL)
        return (-1);

    xmlMutexLock(xsltExtMutex);

    xmlHashUpdateEntry2(xsltTopLevelsHash, name, URI,
                        XML_CAST_FPTR(function), NULL);

    xmlMutexUnlock(xsltExtMutex);

    return (0);
}

/**
 * xsltExtModuleTopLevelLookup:
 * @name:  the top-level element name
 * @URI:  the top-level element namespace URI
 *
 * Looks up an extension module top-level element
 *
 * Returns the callback function if found, NULL otherwise.
 */
xsltTopLevelFunction
xsltExtModuleTopLevelLookup(const xmlChar * name, const xmlChar * URI)
{
    xsltTopLevelFunction ret;

    if ((xsltTopLevelsHash == NULL) || (name == NULL) || (URI == NULL))
        return (NULL);

    xmlMutexLock(xsltExtMutex);

    XML_CAST_FPTR(ret) = xmlHashLookup2(xsltTopLevelsHash, name, URI);

    xmlMutexUnlock(xsltExtMutex);

    /* if lookup fails, attempt a dynamic load on supported platforms */
    if (NULL == ret) {
        if (!xsltExtModuleRegisterDynamic(URI)) {
            xmlMutexLock(xsltExtMutex);

            XML_CAST_FPTR(ret) = xmlHashLookup2(xsltTopLevelsHash, name, URI);

            xmlMutexUnlock(xsltExtMutex);
        }
    }

    return (ret);
}

/**
 * xsltUnregisterExtModuleTopLevel:
 * @name:  the top-level element name
 * @URI:  the top-level element namespace URI
 *
 * Unregisters an extension module top-level element
 *
 * Returns 0 if successful, -1 in case of error.
 */
int
xsltUnregisterExtModuleTopLevel(const xmlChar * name, const xmlChar * URI)
{
    int ret;

    if ((xsltTopLevelsHash == NULL) || (name == NULL) || (URI == NULL))
        return (-1);

    xmlMutexLock(xsltExtMutex);

    ret = xmlHashRemoveEntry2(xsltTopLevelsHash, name, URI, NULL);

    xmlMutexUnlock(xsltExtMutex);

    return(ret);
}

/**
 * xsltUnregisterAllExtModuleTopLevel:
 *
 * Unregisters all extension module function
 */
static void
xsltUnregisterAllExtModuleTopLevel(void)
{
    xmlMutexLock(xsltExtMutex);

    xmlHashFree(xsltTopLevelsHash, NULL);
    xsltTopLevelsHash = NULL;

    xmlMutexUnlock(xsltExtMutex);
}

/**
 * xsltGetExtInfo:
 * @style:  pointer to a stylesheet
 * @URI:    the namespace URI desired
 *
 * looks up URI in extInfos of the stylesheet
 *
 * returns a pointer to the hash table if found, else NULL
 */
xmlHashTablePtr
xsltGetExtInfo(xsltStylesheetPtr style, const xmlChar * URI)
{
    xsltExtDataPtr data;

    /*
    * TODO: Why do we have a return type of xmlHashTablePtr?
    *   Is the user-allocated data for extension modules expected
    *   to be a xmlHashTablePtr only? Or is this intended for
    *   the EXSLT module only?
    */

    if (style != NULL && style->extInfos != NULL) {
        data = xmlHashLookup(style->extInfos, URI);
        if (data != NULL && data->extData != NULL)
            return data->extData;
    }
    return NULL;
}

/************************************************************************
 * 									*
 * 		Test module http://xmlsoft.org/XSLT/			*
 * 									*
 ************************************************************************/

/************************************************************************
 * 									*
 * 		Test of the extension module API			*
 * 									*
 ************************************************************************/

static xmlChar *testData = NULL;
static xmlChar *testStyleData = NULL;

/**
 * xsltExtFunctionTest:
 * @ctxt:  the XPath Parser context
 * @nargs:  the number of arguments
 *
 * function libxslt:test() for testing the extensions support.
 */
static void
xsltExtFunctionTest(xmlXPathParserContextPtr ctxt,
                    int nargs ATTRIBUTE_UNUSED)
{
    xsltTransformContextPtr tctxt;
    void *data = NULL;

    tctxt = xsltXPathGetTransformContext(ctxt);

    if (testData == NULL) {
        xsltGenericDebug(xsltGenericDebugContext,
                         "xsltExtFunctionTest: not initialized,"
                         " calling xsltGetExtData\n");
        data = xsltGetExtData(tctxt, (const xmlChar *) XSLT_DEFAULT_URL);
        if (data == NULL) {
            xsltTransformError(tctxt, NULL, NULL,
                               "xsltExtElementTest: not initialized\n");
            return;
        }
    }
    if (tctxt == NULL) {
        xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
                           "xsltExtFunctionTest: failed to get the transformation context\n");
        return;
    }
    if (data == NULL)
        data = xsltGetExtData(tctxt, (const xmlChar *) XSLT_DEFAULT_URL);
    if (data == NULL) {
        xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
                           "xsltExtFunctionTest: failed to get module data\n");
        return;
    }
    if (data != testData) {
        xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
                           "xsltExtFunctionTest: got wrong module data\n");
        return;
    }
#ifdef WITH_XSLT_DEBUG_FUNCTION
    xsltGenericDebug(xsltGenericDebugContext,
                     "libxslt:test() called with %d args\n", nargs);
#endif
}

/**
 * xsltExtElementPreCompTest:
 * @style:  the stylesheet
 * @inst:  the instruction in the stylesheet
 *
 * Process a libxslt:test node
 */
static xsltElemPreCompPtr
xsltExtElementPreCompTest(xsltStylesheetPtr style, xmlNodePtr inst,
                          xsltTransformFunction function)
{
    xsltElemPreCompPtr ret;

    if (style == NULL) {
        xsltTransformError(NULL, NULL, inst,
                           "xsltExtElementTest: no transformation context\n");
        return (NULL);
    }
    if (testStyleData == NULL) {
        xsltGenericDebug(xsltGenericDebugContext,
                         "xsltExtElementPreCompTest: not initialized,"
                         " calling xsltStyleGetExtData\n");
        xsltStyleGetExtData(style, (const xmlChar *) XSLT_DEFAULT_URL);
        if (testStyleData == NULL) {
            xsltTransformError(NULL, style, inst,
                               "xsltExtElementPreCompTest: not initialized\n");
            if (style != NULL)
                style->errors++;
            return (NULL);
        }
    }
    if (inst == NULL) {
        xsltTransformError(NULL, style, inst,
                           "xsltExtElementPreCompTest: no instruction\n");
        if (style != NULL)
            style->errors++;
        return (NULL);
    }
    ret = xsltNewElemPreComp(style, inst, function);
    return (ret);
}

/**
 * xsltExtElementTest:
 * @ctxt:  an XSLT processing context
 * @node:  The current node
 * @inst:  the instruction in the stylesheet
 * @comp:  precomputed informations
 *
 * Process a libxslt:test node
 */
static void
xsltExtElementTest(xsltTransformContextPtr ctxt, xmlNodePtr node,
                   xmlNodePtr inst,
                   xsltElemPreCompPtr comp ATTRIBUTE_UNUSED)
{
    xmlNodePtr commentNode;

    if (testData == NULL) {
        xsltGenericDebug(xsltGenericDebugContext,
                         "xsltExtElementTest: not initialized,"
                         " calling xsltGetExtData\n");
        xsltGetExtData(ctxt, (const xmlChar *) XSLT_DEFAULT_URL);
        if (testData == NULL) {
            xsltTransformError(ctxt, NULL, inst,
                               "xsltExtElementTest: not initialized\n");
            return;
        }
    }
    if (ctxt == NULL) {
        xsltTransformError(ctxt, NULL, inst,
                           "xsltExtElementTest: no transformation context\n");
        return;
    }
    if (node == NULL) {
        xsltTransformError(ctxt, NULL, inst,
                           "xsltExtElementTest: no current node\n");
        return;
    }
    if (inst == NULL) {
        xsltTransformError(ctxt, NULL, inst,
                           "xsltExtElementTest: no instruction\n");
        return;
    }
    if (ctxt->insert == NULL) {
        xsltTransformError(ctxt, NULL, inst,
                           "xsltExtElementTest: no insertion point\n");
        return;
    }
    commentNode = xmlNewComment((const xmlChar *)
                                "libxslt:test element test worked");
    xmlAddChild(ctxt->insert, commentNode);
}

/**
 * xsltExtInitTest:
 * @ctxt:  an XSLT transformation context
 * @URI:  the namespace URI for the extension
 *
 * A function called at initialization time of an XSLT extension module
 *
 * Returns a pointer to the module specific data for this transformation
 */
static void *
xsltExtInitTest(xsltTransformContextPtr ctxt, const xmlChar * URI)
{
    if (testStyleData == NULL) {
        xsltGenericDebug(xsltGenericErrorContext,
                         "xsltExtInitTest: not initialized,"
                         " calling xsltStyleGetExtData\n");
        testStyleData = xsltStyleGetExtData(ctxt->style, URI);
        if (testStyleData == NULL) {
            xsltTransformError(ctxt, NULL, NULL,
                               "xsltExtInitTest: not initialized\n");
            return (NULL);
        }
    }
    if (testData != NULL) {
        xsltTransformError(ctxt, NULL, NULL,
                           "xsltExtInitTest: already initialized\n");
        return (NULL);
    }
    testData = (void *) "test data";
    xsltGenericDebug(xsltGenericDebugContext,
                     "Registered test module : %s\n", URI);
    return (testData);
}


/**
 * xsltExtShutdownTest:
 * @ctxt:  an XSLT transformation context
 * @URI:  the namespace URI for the extension
 * @data:  the data associated to this module
 *
 * A function called at shutdown time of an XSLT extension module
 */
static void
xsltExtShutdownTest(xsltTransformContextPtr ctxt,
                    const xmlChar * URI, void *data)
{
    if (testData == NULL) {
        xsltTransformError(ctxt, NULL, NULL,
                           "xsltExtShutdownTest: not initialized\n");
        return;
    }
    if (data != testData) {
        xsltTransformError(ctxt, NULL, NULL,
                           "xsltExtShutdownTest: wrong data\n");
    }
    testData = NULL;
    xsltGenericDebug(xsltGenericDebugContext,
                     "Unregistered test module : %s\n", URI);
}

/**
 * xsltExtStyleInitTest:
 * @style:  an XSLT stylesheet
 * @URI:  the namespace URI for the extension
 *
 * A function called at initialization time of an XSLT extension module
 *
 * Returns a pointer to the module specific data for this transformation
 */
static void *
xsltExtStyleInitTest(xsltStylesheetPtr style ATTRIBUTE_UNUSED,
                     const xmlChar * URI)
{
    if (testStyleData != NULL) {
        xsltTransformError(NULL, NULL, NULL,
                           "xsltExtInitTest: already initialized\n");
        return (NULL);
    }
    testStyleData = (void *) "test data";
    xsltGenericDebug(xsltGenericDebugContext,
                     "Registered test module : %s\n", URI);
    return (testStyleData);
}


/**
 * xsltExtStyleShutdownTest:
 * @style:  an XSLT stylesheet
 * @URI:  the namespace URI for the extension
 * @data:  the data associated to this module
 *
 * A function called at shutdown time of an XSLT extension module
 */
static void
xsltExtStyleShutdownTest(xsltStylesheetPtr style ATTRIBUTE_UNUSED,
                         const xmlChar * URI, void *data)
{
    if (testStyleData == NULL) {
        xsltGenericError(xsltGenericErrorContext,
                         "xsltExtShutdownTest: not initialized\n");
        return;
    }
    if (data != testStyleData) {
        xsltTransformError(NULL, NULL, NULL,
                           "xsltExtShutdownTest: wrong data\n");
    }
    testStyleData = NULL;
    xsltGenericDebug(xsltGenericDebugContext,
                     "Unregistered test module : %s\n", URI);
}

/**
 * xsltRegisterTestModule:
 *
 * Registers the test module
 */
void
xsltRegisterTestModule(void)
{
    xsltInitGlobals();
    xsltRegisterExtModuleFull((const xmlChar *) XSLT_DEFAULT_URL,
                              xsltExtInitTest, xsltExtShutdownTest,
                              xsltExtStyleInitTest,
                              xsltExtStyleShutdownTest);
    xsltRegisterExtModuleFunction((const xmlChar *) "test",
                                  (const xmlChar *) XSLT_DEFAULT_URL,
                                  xsltExtFunctionTest);
    xsltRegisterExtModuleElement((const xmlChar *) "test",
                                 (const xmlChar *) XSLT_DEFAULT_URL,
                                 xsltExtElementPreCompTest,
                                 xsltExtElementTest);
}

static void
xsltHashScannerModuleFree(void *payload ATTRIBUTE_UNUSED,
                          void *data ATTRIBUTE_UNUSED,
                          xmlChar * name ATTRIBUTE_UNUSED)
{
#ifdef WITH_MODULES
    xmlModuleClose(payload);
#endif
}

/**
 * xsltInitGlobals:
 *
 * Initialize the global variables for extensions
 */
void
xsltInitGlobals(void)
{
    if (xsltExtMutex == NULL) {
        xsltExtMutex = xmlNewMutex();
    }
}

/**
 * xsltCleanupGlobals:
 *
 * Unregister all global variables set up by the XSLT library
 */
void
xsltCleanupGlobals(void)
{
    xsltUnregisterAllExtModules();
    xsltUnregisterAllExtModuleFunction();
    xsltUnregisterAllExtModuleElement();
    xsltUnregisterAllExtModuleTopLevel();

    xmlMutexLock(xsltExtMutex);
    /* cleanup dynamic module hash */
    if (NULL != xsltModuleHash) {
        xmlHashScan(xsltModuleHash, xsltHashScannerModuleFree, 0);
        xmlHashFree(xsltModuleHash, NULL);
        xsltModuleHash = NULL;
    }
    xmlMutexUnlock(xsltExtMutex);

    xmlFreeMutex(xsltExtMutex);
    xsltExtMutex = NULL;
    xsltUninit();
}

static void
xsltDebugDumpExtensionsCallback(void *function ATTRIBUTE_UNUSED,
                                FILE * output, const xmlChar * name,
                                const xmlChar * URI,
                                const xmlChar * not_used ATTRIBUTE_UNUSED)
{
    if (!name || !URI)
        return;
    fprintf(output, "{%s}%s\n", URI, name);
}

static void
xsltDebugDumpExtModulesCallback(void *function ATTRIBUTE_UNUSED,
                                FILE * output, const xmlChar * URI,
                                const xmlChar * not_used ATTRIBUTE_UNUSED,
                                const xmlChar * not_used2 ATTRIBUTE_UNUSED)
{
    if (!URI)
        return;
    fprintf(output, "%s\n", URI);
}

/**
 * xsltDebugDumpExtensions:
 * @output:  the FILE * for the output, if NULL stdout is used
 *
 * Dumps a list of the registered XSLT extension functions and elements
 */
void
xsltDebugDumpExtensions(FILE * output)
{
    if (output == NULL)
        output = stdout;
    fprintf(output,
            "Registered XSLT Extensions\n--------------------------\n");
    if (!xsltFunctionsHash)
        fprintf(output, "No registered extension functions\n");
    else {
        fprintf(output, "Registered Extension Functions:\n");
        xmlMutexLock(xsltExtMutex);
        xmlHashScanFull(xsltFunctionsHash,
                        (xmlHashScannerFull)
                        xsltDebugDumpExtensionsCallback, output);
        xmlMutexUnlock(xsltExtMutex);
    }
    if (!xsltElementsHash)
        fprintf(output, "\nNo registered extension elements\n");
    else {
        fprintf(output, "\nRegistered Extension Elements:\n");
        xmlMutexLock(xsltExtMutex);
        xmlHashScanFull(xsltElementsHash,
                        (xmlHashScannerFull)
                        xsltDebugDumpExtensionsCallback, output);
        xmlMutexUnlock(xsltExtMutex);
    }
    if (!xsltExtensionsHash)
        fprintf(output, "\nNo registered extension modules\n");
    else {
        fprintf(output, "\nRegistered Extension Modules:\n");
        xmlMutexLock(xsltExtMutex);
        xmlHashScanFull(xsltExtensionsHash,
                        (xmlHashScannerFull)
                        xsltDebugDumpExtModulesCallback, output);
        xmlMutexUnlock(xsltExtMutex);
    }

}
