|
|
|
@ -13,6 +13,7 @@
|
|
|
|
|
#include "libxslt.h"
|
|
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <limits.h>
|
|
|
|
|
|
|
|
|
|
#include <libxml/xmlmemory.h>
|
|
|
|
|
#include <libxml/tree.h>
|
|
|
|
@ -20,12 +21,22 @@
|
|
|
|
|
#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 */
|
|
|
|
|
#define PATH_MAX _MAX_PATH
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef WITH_XSLT_DEBUG
|
|
|
|
|
#define WITH_XSLT_DEBUG_EXTENSIONS
|
|
|
|
|
#endif
|
|
|
|
@ -72,6 +83,7 @@ static xmlHashTablePtr xsltExtensionsHash = NULL;
|
|
|
|
|
static xmlHashTablePtr xsltFunctionsHash = NULL;
|
|
|
|
|
static xmlHashTablePtr xsltElementsHash = NULL;
|
|
|
|
|
static xmlHashTablePtr xsltTopLevelsHash = NULL;
|
|
|
|
|
static xmlHashTablePtr xsltModuleHash = NULL;
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
|
* *
|
|
|
|
@ -114,7 +126,8 @@ xsltNewExtDef(const xmlChar * prefix, const xmlChar * URI)
|
|
|
|
|
* Free up the memory allocated by @extensiond
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
xsltFreeExtDef(xsltExtDefPtr extensiond) {
|
|
|
|
|
xsltFreeExtDef(xsltExtDefPtr extensiond)
|
|
|
|
|
{
|
|
|
|
|
if (extensiond == NULL)
|
|
|
|
|
return;
|
|
|
|
|
if (extensiond->prefix != NULL)
|
|
|
|
@ -131,7 +144,8 @@ xsltFreeExtDef(xsltExtDefPtr extensiond) {
|
|
|
|
|
* Free up the memory allocated by all the elements of @extensiond
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
xsltFreeExtDefList(xsltExtDefPtr extensiond) {
|
|
|
|
|
xsltFreeExtDefList(xsltExtDefPtr extensiond)
|
|
|
|
|
{
|
|
|
|
|
xsltExtDefPtr cur;
|
|
|
|
|
|
|
|
|
|
while (extensiond != NULL) {
|
|
|
|
@ -180,7 +194,8 @@ xsltNewExtModule(xsltExtInitFunction initFunc,
|
|
|
|
|
* Free up the memory allocated by @ext
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
xsltFreeExtModule(xsltExtModulePtr ext) {
|
|
|
|
|
xsltFreeExtModule(xsltExtModulePtr ext)
|
|
|
|
|
{
|
|
|
|
|
if (ext == NULL)
|
|
|
|
|
return;
|
|
|
|
|
xmlFree(ext);
|
|
|
|
@ -220,7 +235,8 @@ xsltNewExtData(xsltExtModulePtr extModule, void *extData)
|
|
|
|
|
* Free up the memory allocated by @ext
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
xsltFreeExtData(xsltExtDataPtr ext) {
|
|
|
|
|
xsltFreeExtData(xsltExtDataPtr ext)
|
|
|
|
|
{
|
|
|
|
|
if (ext == NULL)
|
|
|
|
|
return;
|
|
|
|
|
xmlFree(ext);
|
|
|
|
@ -238,7 +254,8 @@ xsltFreeExtData(xsltExtDataPtr ext) {
|
|
|
|
|
*/
|
|
|
|
|
static xsltExtElementPtr
|
|
|
|
|
xsltNewExtElement(xsltPreComputeFunction precomp,
|
|
|
|
|
xsltTransformFunction transform) {
|
|
|
|
|
xsltTransformFunction transform)
|
|
|
|
|
{
|
|
|
|
|
xsltExtElementPtr cur;
|
|
|
|
|
|
|
|
|
|
if (transform == NULL)
|
|
|
|
@ -262,13 +279,93 @@ xsltNewExtElement (xsltPreComputeFunction precomp,
|
|
|
|
|
* Frees up the memory allocated by @ext
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
xsltFreeExtElement (xsltExtElementPtr ext) {
|
|
|
|
|
xsltFreeExtElement(xsltExtElementPtr ext)
|
|
|
|
|
{
|
|
|
|
|
if (ext == NULL)
|
|
|
|
|
return;
|
|
|
|
|
xmlFree(ext);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef WITH_MODULES
|
|
|
|
|
typedef void (*exsltRegisterFunction) (void);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* xsltExtModuleRegisterDynamic:
|
|
|
|
|
* @URI: the function or element namespace URI
|
|
|
|
|
*
|
|
|
|
|
* Looks up an extension module to dynamically load
|
|
|
|
|
* based on the namespace URI
|
|
|
|
|
*
|
|
|
|
|
* Returns 0 if successful, -1 in case of error.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
xsltExtModuleRegisterDynamic(const xmlChar * URI)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
xmlModulePtr m;
|
|
|
|
|
exsltRegisterFunction regfunc;
|
|
|
|
|
xmlChar module_filename[PATH_MAX];
|
|
|
|
|
const xmlChar *extNameBegin = NULL;
|
|
|
|
|
const xmlChar *extDirectory = NULL;
|
|
|
|
|
int i, rc, seen_before;
|
|
|
|
|
|
|
|
|
|
/* check for bad inputs */
|
|
|
|
|
if (URI == NULL)
|
|
|
|
|
return (-1);
|
|
|
|
|
|
|
|
|
|
if (NULL == xsltModuleHash) {
|
|
|
|
|
xsltModuleHash = xmlHashCreate(5);
|
|
|
|
|
if (xsltModuleHash == NULL)
|
|
|
|
|
return (-1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* have we attempted to register this module already? */
|
|
|
|
|
seen_before = (int) xmlHashLookup(xsltModuleHash, URI);
|
|
|
|
|
if (0 != seen_before) {
|
|
|
|
|
return (-1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = xmlStrlen(URI); i != 0 && extNameBegin == NULL; --i) {
|
|
|
|
|
if (URI[i - 1] == '/')
|
|
|
|
|
extNameBegin = URI + i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (extNameBegin == NULL || *extNameBegin == '\0')
|
|
|
|
|
return (-1);
|
|
|
|
|
|
|
|
|
|
/* determine module directory */
|
|
|
|
|
extDirectory = getenv("LIBXSLT_PLUGINS_PATH");
|
|
|
|
|
if (NULL == extDirectory)
|
|
|
|
|
extDirectory = LIBXSLT_DEFAULT_PLUGINS_PATH();
|
|
|
|
|
if (NULL == extDirectory)
|
|
|
|
|
return (-1);
|
|
|
|
|
|
|
|
|
|
/* build the module filename, and confirm the module exists */
|
|
|
|
|
xmlStrPrintf(module_filename, sizeof(module_filename), "%s%s%s",
|
|
|
|
|
extDirectory, extNameBegin, LIBXML_MODULE_EXTENSION);
|
|
|
|
|
if (1 != xmlCheckFilename(module_filename))
|
|
|
|
|
return (-1);
|
|
|
|
|
|
|
|
|
|
m = xmlModuleOpen(module_filename, 0);
|
|
|
|
|
if (NULL == m)
|
|
|
|
|
return (-1);
|
|
|
|
|
|
|
|
|
|
rc = xmlModuleSymbol(m, "exsltRegisterModule", (void **) ®func);
|
|
|
|
|
if (0 == rc) {
|
|
|
|
|
(*regfunc) ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* register this module in our hash */
|
|
|
|
|
xmlHashAddEntry(xsltModuleHash, URI, (void *) m);
|
|
|
|
|
|
|
|
|
|
return (NULL == regfunc) ? -1 : 0;
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
#define xsltExtModuleRegisterDynamic(b) -1
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
|
* *
|
|
|
|
|
* The stylesheet extension prefixes handling *
|
|
|
|
@ -283,7 +380,8 @@ xsltFreeExtElement (xsltExtElementPtr ext) {
|
|
|
|
|
* Free up the memory used by XSLT extensions in a stylesheet
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
xsltFreeExts(xsltStylesheetPtr style) {
|
|
|
|
|
xsltFreeExts(xsltStylesheetPtr style)
|
|
|
|
|
{
|
|
|
|
|
if (style->nsDefs != NULL)
|
|
|
|
|
xsltFreeExtDefList((xsltExtDefPtr) style->nsDefs);
|
|
|
|
|
}
|
|
|
|
@ -300,7 +398,8 @@ xsltFreeExts(xsltStylesheetPtr style) {
|
|
|
|
|
*/
|
|
|
|
|
int
|
|
|
|
|
xsltRegisterExtPrefix(xsltStylesheetPtr style,
|
|
|
|
|
const xmlChar *prefix, const xmlChar *URI) {
|
|
|
|
|
const xmlChar * prefix, const xmlChar * URI)
|
|
|
|
|
{
|
|
|
|
|
xsltExtDefPtr def, ret;
|
|
|
|
|
|
|
|
|
|
if ((style == NULL) || (prefix == NULL) | (URI == NULL))
|
|
|
|
@ -308,7 +407,8 @@ xsltRegisterExtPrefix(xsltStylesheetPtr style,
|
|
|
|
|
|
|
|
|
|
#ifdef WITH_XSLT_DEBUG_EXTENSIONS
|
|
|
|
|
xsltGenericDebug(xsltGenericDebugContext,
|
|
|
|
|
"Registering extension prefix %s : %s\n", prefix, URI);
|
|
|
|
|
"Registering extension prefix %s : %s\n", prefix,
|
|
|
|
|
URI);
|
|
|
|
|
#endif
|
|
|
|
|
def = (xsltExtDefPtr) style->nsDefs;
|
|
|
|
|
while (def != NULL) {
|
|
|
|
@ -330,6 +430,12 @@ xsltRegisterExtPrefix(xsltStylesheetPtr style,
|
|
|
|
|
xsltExtModulePtr module;
|
|
|
|
|
|
|
|
|
|
module = xmlHashLookup(xsltExtensionsHash, URI);
|
|
|
|
|
if (NULL == module) {
|
|
|
|
|
if (!xsltExtModuleRegisterDynamic(URI)) {
|
|
|
|
|
module = xmlHashLookup(xsltExtensionsHash, URI);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (module != NULL) {
|
|
|
|
|
xsltStyleGetExtData(style, URI);
|
|
|
|
|
}
|
|
|
|
@ -356,7 +462,8 @@ xsltRegisterExtPrefix(xsltStylesheetPtr style,
|
|
|
|
|
*/
|
|
|
|
|
int
|
|
|
|
|
xsltRegisterExtFunction(xsltTransformContextPtr ctxt, const xmlChar * name,
|
|
|
|
|
const xmlChar *URI, xmlXPathFunction function) {
|
|
|
|
|
const xmlChar * URI, xmlXPathFunction function)
|
|
|
|
|
{
|
|
|
|
|
if ((ctxt == NULL) || (name == NULL) ||
|
|
|
|
|
(URI == NULL) || (function == NULL))
|
|
|
|
|
return (-1);
|
|
|
|
@ -367,7 +474,8 @@ xsltRegisterExtFunction(xsltTransformContextPtr ctxt, const xmlChar *name,
|
|
|
|
|
ctxt->extFunctions = xmlHashCreate(10);
|
|
|
|
|
if (ctxt->extFunctions == NULL)
|
|
|
|
|
return (-1);
|
|
|
|
|
return(xmlHashAddEntry2(ctxt->extFunctions, name, URI, XML_CAST_FPTR(function)));
|
|
|
|
|
return (xmlHashAddEntry2
|
|
|
|
|
(ctxt->extFunctions, name, URI, XML_CAST_FPTR(function)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -383,7 +491,8 @@ xsltRegisterExtFunction(xsltTransformContextPtr ctxt, const xmlChar *name,
|
|
|
|
|
*/
|
|
|
|
|
int
|
|
|
|
|
xsltRegisterExtElement(xsltTransformContextPtr ctxt, const xmlChar * name,
|
|
|
|
|
const xmlChar *URI, xsltTransformFunction function) {
|
|
|
|
|
const xmlChar * URI, xsltTransformFunction function)
|
|
|
|
|
{
|
|
|
|
|
if ((ctxt == NULL) || (name == NULL) ||
|
|
|
|
|
(URI == NULL) || (function == NULL))
|
|
|
|
|
return (-1);
|
|
|
|
@ -391,7 +500,8 @@ xsltRegisterExtElement(xsltTransformContextPtr ctxt, const xmlChar *name,
|
|
|
|
|
ctxt->extElements = xmlHashCreate(10);
|
|
|
|
|
if (ctxt->extElements == NULL)
|
|
|
|
|
return (-1);
|
|
|
|
|
return(xmlHashAddEntry2(ctxt->extElements, name, URI, XML_CAST_FPTR(function)));
|
|
|
|
|
return (xmlHashAddEntry2
|
|
|
|
|
(ctxt->extElements, name, URI, XML_CAST_FPTR(function)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -401,7 +511,8 @@ xsltRegisterExtElement(xsltTransformContextPtr ctxt, const xmlChar *name,
|
|
|
|
|
* Free the XSLT extension data
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
xsltFreeCtxtExts(xsltTransformContextPtr ctxt) {
|
|
|
|
|
xsltFreeCtxtExts(xsltTransformContextPtr ctxt)
|
|
|
|
|
{
|
|
|
|
|
if (ctxt->extElements != NULL)
|
|
|
|
|
xmlHashFree(ctxt->extElements, NULL);
|
|
|
|
|
if (ctxt->extFunctions != NULL)
|
|
|
|
@ -419,7 +530,8 @@ xsltFreeCtxtExts(xsltTransformContextPtr ctxt) {
|
|
|
|
|
* Returns the pointer or NULL if not present
|
|
|
|
|
*/
|
|
|
|
|
void *
|
|
|
|
|
xsltStyleGetExtData(xsltStylesheetPtr style, const xmlChar * URI) {
|
|
|
|
|
xsltStyleGetExtData(xsltStylesheetPtr style, const xmlChar * URI)
|
|
|
|
|
{
|
|
|
|
|
xsltExtDataPtr data = NULL;
|
|
|
|
|
xsltStylesheetPtr tmp;
|
|
|
|
|
|
|
|
|
@ -472,10 +584,10 @@ xsltStyleGetExtData(xsltStylesheetPtr style, const xmlChar * URI) {
|
|
|
|
|
data = xsltNewExtData(module, extData);
|
|
|
|
|
if (data == NULL)
|
|
|
|
|
return (NULL);
|
|
|
|
|
if (xmlHashAddEntry(style->extInfos, URI,
|
|
|
|
|
(void *) data) < 0) {
|
|
|
|
|
if (xmlHashAddEntry(style->extInfos, URI, (void *) data) < 0) {
|
|
|
|
|
xsltGenericError(xsltGenericErrorContext,
|
|
|
|
|
"Failed to register module data: %s\n", URI);
|
|
|
|
|
"Failed to register module data: %s\n",
|
|
|
|
|
URI);
|
|
|
|
|
if (module->styleShutdownFunc)
|
|
|
|
|
module->styleShutdownFunc(style, URI, extData);
|
|
|
|
|
xsltFreeExtData(data);
|
|
|
|
@ -497,7 +609,8 @@ xsltStyleGetExtData(xsltStylesheetPtr style, const xmlChar * URI) {
|
|
|
|
|
* Returns the pointer or NULL if not present
|
|
|
|
|
*/
|
|
|
|
|
void *
|
|
|
|
|
xsltGetExtData(xsltTransformContextPtr ctxt, const xmlChar * URI) {
|
|
|
|
|
xsltGetExtData(xsltTransformContextPtr ctxt, const xmlChar * URI)
|
|
|
|
|
{
|
|
|
|
|
xsltExtDataPtr data;
|
|
|
|
|
|
|
|
|
|
if ((ctxt == NULL) || (URI == NULL))
|
|
|
|
@ -537,10 +650,10 @@ xsltGetExtData(xsltTransformContextPtr ctxt, const xmlChar * URI) {
|
|
|
|
|
data = xsltNewExtData(module, extData);
|
|
|
|
|
if (data == NULL)
|
|
|
|
|
return (NULL);
|
|
|
|
|
if (xmlHashAddEntry(ctxt->extInfos, URI,
|
|
|
|
|
(void *) data) < 0) {
|
|
|
|
|
if (xmlHashAddEntry(ctxt->extInfos, URI, (void *) data) < 0) {
|
|
|
|
|
xsltTransformError(ctxt, NULL, NULL,
|
|
|
|
|
"Failed to register module data: %s\n", URI);
|
|
|
|
|
"Failed to register module data: %s\n",
|
|
|
|
|
URI);
|
|
|
|
|
if (module->shutdownFunc)
|
|
|
|
|
module->shutdownFunc(ctxt, URI, extData);
|
|
|
|
|
xsltFreeExtData(data);
|
|
|
|
@ -567,7 +680,8 @@ struct _xsltInitExtCtxt {
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
xsltInitCtxtExt(xsltExtDataPtr styleData, xsltInitExtCtxt * ctxt,
|
|
|
|
|
const xmlChar *URI) {
|
|
|
|
|
const xmlChar * URI)
|
|
|
|
|
{
|
|
|
|
|
xsltExtModulePtr module;
|
|
|
|
|
xsltExtDataPtr ctxtData;
|
|
|
|
|
void *extData;
|
|
|
|
@ -714,7 +828,8 @@ xsltShutdownCtxtExts(xsltTransformContextPtr ctxt)
|
|
|
|
|
return;
|
|
|
|
|
if (ctxt->extInfos == NULL)
|
|
|
|
|
return;
|
|
|
|
|
xmlHashScan(ctxt->extInfos, (xmlHashScanner) xsltShutdownCtxtExt, ctxt);
|
|
|
|
|
xmlHashScan(ctxt->extInfos, (xmlHashScanner) xsltShutdownCtxtExt,
|
|
|
|
|
ctxt);
|
|
|
|
|
xmlHashFree(ctxt->extInfos, (xmlHashDeallocator) xsltFreeExtData);
|
|
|
|
|
ctxt->extInfos = NULL;
|
|
|
|
|
}
|
|
|
|
@ -776,7 +891,8 @@ xsltShutdownExts(xsltStylesheetPtr style)
|
|
|
|
|
* Returns 1 if this is an extension, 0 otherwise
|
|
|
|
|
*/
|
|
|
|
|
int
|
|
|
|
|
xsltCheckExtPrefix(xsltStylesheetPtr style, const xmlChar *prefix) {
|
|
|
|
|
xsltCheckExtPrefix(xsltStylesheetPtr style, const xmlChar * prefix)
|
|
|
|
|
{
|
|
|
|
|
xsltExtDefPtr cur;
|
|
|
|
|
|
|
|
|
|
if ((style == NULL) || (style->nsDefs == NULL))
|
|
|
|
@ -852,7 +968,8 @@ xsltRegisterExtModuleFull(const xmlChar * URI,
|
|
|
|
|
int
|
|
|
|
|
xsltRegisterExtModule(const xmlChar * URI,
|
|
|
|
|
xsltExtInitFunction initFunc,
|
|
|
|
|
xsltExtShutdownFunction shutdownFunc) {
|
|
|
|
|
xsltExtShutdownFunction shutdownFunc)
|
|
|
|
|
{
|
|
|
|
|
return xsltRegisterExtModuleFull(URI, initFunc, shutdownFunc,
|
|
|
|
|
NULL, NULL);
|
|
|
|
|
}
|
|
|
|
@ -892,7 +1009,8 @@ xsltUnregisterAllExtModules(void)
|
|
|
|
|
if (xsltExtensionsHash == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
xmlHashFree(xsltExtensionsHash, (xmlHashDeallocator) xsltFreeExtModule);
|
|
|
|
|
xmlHashFree(xsltExtensionsHash,
|
|
|
|
|
(xmlHashDeallocator) xsltFreeExtModule);
|
|
|
|
|
xsltExtensionsHash = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -928,7 +1046,8 @@ xsltXPathGetTransformContext(xmlXPathParserContextPtr ctxt)
|
|
|
|
|
*/
|
|
|
|
|
int
|
|
|
|
|
xsltRegisterExtModuleFunction(const xmlChar * name, const xmlChar * URI,
|
|
|
|
|
xmlXPathFunction function) {
|
|
|
|
|
xmlXPathFunction function)
|
|
|
|
|
{
|
|
|
|
|
if ((name == NULL) || (URI == NULL) || (function == NULL))
|
|
|
|
|
return (-1);
|
|
|
|
|
|
|
|
|
@ -953,12 +1072,23 @@ xsltRegisterExtModuleFunction (const xmlChar *name, const xmlChar *URI,
|
|
|
|
|
* Returns the function if found, NULL otherwise.
|
|
|
|
|
*/
|
|
|
|
|
xmlXPathFunction
|
|
|
|
|
xsltExtModuleFunctionLookup (const xmlChar *name, const xmlChar *URI) {
|
|
|
|
|
xsltExtModuleFunctionLookup(const xmlChar * name, const xmlChar * URI)
|
|
|
|
|
{
|
|
|
|
|
xmlXPathFunction ret;
|
|
|
|
|
|
|
|
|
|
if ((xsltFunctionsHash == NULL) || (name == NULL) || (URI == NULL))
|
|
|
|
|
return (NULL);
|
|
|
|
|
|
|
|
|
|
XML_CAST_FPTR(ret) = xmlHashLookup2(xsltFunctionsHash, name, URI);
|
|
|
|
|
|
|
|
|
|
/* if lookup fails, attempt a dynamic load on supported platforms */
|
|
|
|
|
if (NULL == ret) {
|
|
|
|
|
if (!xsltExtModuleRegisterDynamic(URI)) {
|
|
|
|
|
XML_CAST_FPTR(ret) =
|
|
|
|
|
xmlHashLookup2(xsltFunctionsHash, name, URI);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -972,8 +1102,8 @@ xsltExtModuleFunctionLookup (const xmlChar *name, const xmlChar *URI) {
|
|
|
|
|
* Returns 0 if successful, -1 in case of error.
|
|
|
|
|
*/
|
|
|
|
|
int
|
|
|
|
|
xsltUnregisterExtModuleFunction (const xmlChar *name,
|
|
|
|
|
const xmlChar *URI) {
|
|
|
|
|
xsltUnregisterExtModuleFunction(const xmlChar * name, const xmlChar * URI)
|
|
|
|
|
{
|
|
|
|
|
if ((xsltFunctionsHash == NULL) || (name == NULL) || (URI == NULL))
|
|
|
|
|
return (-1);
|
|
|
|
|
|
|
|
|
@ -986,7 +1116,8 @@ xsltUnregisterExtModuleFunction (const xmlChar *name,
|
|
|
|
|
* Unregisters all extension module function
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
xsltUnregisterAllExtModuleFunction (void) {
|
|
|
|
|
xsltUnregisterAllExtModuleFunction(void)
|
|
|
|
|
{
|
|
|
|
|
xmlHashFree(xsltFunctionsHash, NULL);
|
|
|
|
|
xsltFunctionsHash = NULL;
|
|
|
|
|
}
|
|
|
|
@ -1004,7 +1135,8 @@ xsltUnregisterAllExtModuleFunction (void) {
|
|
|
|
|
*/
|
|
|
|
|
xsltElemPreCompPtr
|
|
|
|
|
xsltNewElemPreComp(xsltStylesheetPtr style, xmlNodePtr inst,
|
|
|
|
|
xsltTransformFunction function) {
|
|
|
|
|
xsltTransformFunction function)
|
|
|
|
|
{
|
|
|
|
|
xsltElemPreCompPtr cur;
|
|
|
|
|
|
|
|
|
|
cur = (xsltElemPreCompPtr) xmlMalloc(sizeof(xsltElemPreComp));
|
|
|
|
@ -1037,7 +1169,8 @@ xsltNewElemPreComp (xsltStylesheetPtr style, xmlNodePtr inst,
|
|
|
|
|
void
|
|
|
|
|
xsltInitElemPreComp(xsltElemPreCompPtr comp, xsltStylesheetPtr style,
|
|
|
|
|
xmlNodePtr inst, xsltTransformFunction function,
|
|
|
|
|
xsltElemPreCompDeallocator freeFunc) {
|
|
|
|
|
xsltElemPreCompDeallocator freeFunc)
|
|
|
|
|
{
|
|
|
|
|
comp->type = XSLT_FUNC_EXTENSION;
|
|
|
|
|
comp->func = function;
|
|
|
|
|
comp->inst = inst;
|
|
|
|
@ -1057,8 +1190,8 @@ xsltInitElemPreComp (xsltElemPreCompPtr comp, xsltStylesheetPtr style,
|
|
|
|
|
* Returns the precomputed data
|
|
|
|
|
*/
|
|
|
|
|
xsltElemPreCompPtr
|
|
|
|
|
xsltPreComputeExtModuleElement (xsltStylesheetPtr style,
|
|
|
|
|
xmlNodePtr inst) {
|
|
|
|
|
xsltPreComputeExtModuleElement(xsltStylesheetPtr style, xmlNodePtr inst)
|
|
|
|
|
{
|
|
|
|
|
xsltExtElementPtr ext;
|
|
|
|
|
xsltElemPreCompPtr comp = NULL;
|
|
|
|
|
|
|
|
|
@ -1067,8 +1200,7 @@ xsltPreComputeExtModuleElement (xsltStylesheetPtr style,
|
|
|
|
|
return (NULL);
|
|
|
|
|
|
|
|
|
|
ext = (xsltExtElementPtr)
|
|
|
|
|
xmlHashLookup2 (xsltElementsHash, inst->name,
|
|
|
|
|
inst->ns->href);
|
|
|
|
|
xmlHashLookup2(xsltElementsHash, inst->name, inst->ns->href);
|
|
|
|
|
if (ext == NULL)
|
|
|
|
|
return (NULL);
|
|
|
|
|
|
|
|
|
@ -1094,7 +1226,8 @@ xsltPreComputeExtModuleElement (xsltStylesheetPtr style,
|
|
|
|
|
int
|
|
|
|
|
xsltRegisterExtModuleElement(const xmlChar * name, const xmlChar * URI,
|
|
|
|
|
xsltPreComputeFunction precomp,
|
|
|
|
|
xsltTransformFunction transform) {
|
|
|
|
|
xsltTransformFunction transform)
|
|
|
|
|
{
|
|
|
|
|
xsltExtElementPtr ext;
|
|
|
|
|
|
|
|
|
|
if ((name == NULL) || (URI == NULL) || (transform == NULL))
|
|
|
|
@ -1128,7 +1261,8 @@ xsltRegisterExtModuleElement (const xmlChar *name, const xmlChar *URI,
|
|
|
|
|
*/
|
|
|
|
|
xsltTransformFunction
|
|
|
|
|
xsltExtElementLookup(xsltTransformContextPtr ctxt,
|
|
|
|
|
const xmlChar *name, const xmlChar *URI) {
|
|
|
|
|
const xmlChar * name, const xmlChar * URI)
|
|
|
|
|
{
|
|
|
|
|
xsltTransformFunction ret;
|
|
|
|
|
|
|
|
|
|
if ((name == NULL) || (URI == NULL))
|
|
|
|
@ -1152,7 +1286,8 @@ xsltExtElementLookup (xsltTransformContextPtr ctxt,
|
|
|
|
|
* Returns the callback function if found, NULL otherwise.
|
|
|
|
|
*/
|
|
|
|
|
xsltTransformFunction
|
|
|
|
|
xsltExtModuleElementLookup (const xmlChar *name, const xmlChar *URI) {
|
|
|
|
|
xsltExtModuleElementLookup(const xmlChar * name, const xmlChar * URI)
|
|
|
|
|
{
|
|
|
|
|
xsltExtElementPtr ext;
|
|
|
|
|
|
|
|
|
|
if ((xsltElementsHash == NULL) || (name == NULL) || (URI == NULL))
|
|
|
|
@ -1160,6 +1295,15 @@ xsltExtModuleElementLookup (const xmlChar *name, const xmlChar *URI) {
|
|
|
|
|
|
|
|
|
|
ext = (xsltExtElementPtr) xmlHashLookup2(xsltElementsHash, name, URI);
|
|
|
|
|
|
|
|
|
|
/* if function lookup fails, attempt a dynamic load on supported platforms */
|
|
|
|
|
ext = (xsltExtElementPtr) xmlHashLookup2(xsltElementsHash, name, URI);
|
|
|
|
|
if (NULL == ext) {
|
|
|
|
|
if (!xsltExtModuleRegisterDynamic(URI)) {
|
|
|
|
|
ext = (xsltExtElementPtr)
|
|
|
|
|
xmlHashLookup2(xsltElementsHash, name, URI);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ext == NULL)
|
|
|
|
|
return (NULL);
|
|
|
|
|
return (ext->transform);
|
|
|
|
@ -1176,7 +1320,8 @@ xsltExtModuleElementLookup (const xmlChar *name, const xmlChar *URI) {
|
|
|
|
|
*/
|
|
|
|
|
xsltPreComputeFunction
|
|
|
|
|
xsltExtModuleElementPreComputeLookup(const xmlChar * name,
|
|
|
|
|
const xmlChar *URI) {
|
|
|
|
|
const xmlChar * URI)
|
|
|
|
|
{
|
|
|
|
|
xsltExtElementPtr ext;
|
|
|
|
|
|
|
|
|
|
if ((xsltElementsHash == NULL) || (name == NULL) || (URI == NULL))
|
|
|
|
@ -1184,6 +1329,13 @@ xsltExtModuleElementPreComputeLookup (const xmlChar *name,
|
|
|
|
|
|
|
|
|
|
ext = (xsltExtElementPtr) xmlHashLookup2(xsltElementsHash, name, URI);
|
|
|
|
|
|
|
|
|
|
if (ext == NULL) {
|
|
|
|
|
if (!xsltExtModuleRegisterDynamic(URI)) {
|
|
|
|
|
ext = (xsltExtElementPtr)
|
|
|
|
|
xmlHashLookup2(xsltElementsHash, name, URI);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ext == NULL)
|
|
|
|
|
return (NULL);
|
|
|
|
|
return (ext->precomp);
|
|
|
|
@ -1199,8 +1351,8 @@ xsltExtModuleElementPreComputeLookup (const xmlChar *name,
|
|
|
|
|
* Returns 0 if successful, -1 in case of error.
|
|
|
|
|
*/
|
|
|
|
|
int
|
|
|
|
|
xsltUnregisterExtModuleElement (const xmlChar *name,
|
|
|
|
|
const xmlChar *URI) {
|
|
|
|
|
xsltUnregisterExtModuleElement(const xmlChar * name, const xmlChar * URI)
|
|
|
|
|
{
|
|
|
|
|
if ((xsltElementsHash == NULL) || (name == NULL) || (URI == NULL))
|
|
|
|
|
return (-1);
|
|
|
|
|
|
|
|
|
@ -1214,7 +1366,8 @@ xsltUnregisterExtModuleElement (const xmlChar *name,
|
|
|
|
|
* Unregisters all extension module element
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
xsltUnregisterAllExtModuleElement (void) {
|
|
|
|
|
xsltUnregisterAllExtModuleElement(void)
|
|
|
|
|
{
|
|
|
|
|
xmlHashFree(xsltElementsHash, (xmlHashDeallocator) xsltFreeExtElement);
|
|
|
|
|
xsltElementsHash = NULL;
|
|
|
|
|
}
|
|
|
|
@ -1231,7 +1384,8 @@ xsltUnregisterAllExtModuleElement (void) {
|
|
|
|
|
*/
|
|
|
|
|
int
|
|
|
|
|
xsltRegisterExtModuleTopLevel(const xmlChar * name, const xmlChar * URI,
|
|
|
|
|
xsltTopLevelFunction function) {
|
|
|
|
|
xsltTopLevelFunction function)
|
|
|
|
|
{
|
|
|
|
|
if ((name == NULL) || (URI == NULL) || (function == NULL))
|
|
|
|
|
return (-1);
|
|
|
|
|
|
|
|
|
@ -1256,12 +1410,22 @@ xsltRegisterExtModuleTopLevel (const xmlChar *name, const xmlChar *URI,
|
|
|
|
|
* Returns the callback function if found, NULL otherwise.
|
|
|
|
|
*/
|
|
|
|
|
xsltTopLevelFunction
|
|
|
|
|
xsltExtModuleTopLevelLookup (const xmlChar *name, const xmlChar *URI) {
|
|
|
|
|
xsltExtModuleTopLevelLookup(const xmlChar * name, const xmlChar * URI)
|
|
|
|
|
{
|
|
|
|
|
xsltTopLevelFunction ret;
|
|
|
|
|
|
|
|
|
|
if ((xsltTopLevelsHash == NULL) || (name == NULL) || (URI == NULL))
|
|
|
|
|
return (NULL);
|
|
|
|
|
|
|
|
|
|
XML_CAST_FPTR(ret) = xmlHashLookup2(xsltTopLevelsHash, name, URI);
|
|
|
|
|
|
|
|
|
|
/* if lookup fails, attempt a dynamic load on supported platforms */
|
|
|
|
|
if (NULL == ret) {
|
|
|
|
|
if (!xsltExtModuleRegisterDynamic(URI)) {
|
|
|
|
|
XML_CAST_FPTR(ret) = xmlHashLookup2(xsltTopLevelsHash, name, URI);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (ret);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1275,8 +1439,8 @@ xsltExtModuleTopLevelLookup (const xmlChar *name, const xmlChar *URI) {
|
|
|
|
|
* Returns 0 if successful, -1 in case of error.
|
|
|
|
|
*/
|
|
|
|
|
int
|
|
|
|
|
xsltUnregisterExtModuleTopLevel (const xmlChar *name,
|
|
|
|
|
const xmlChar *URI) {
|
|
|
|
|
xsltUnregisterExtModuleTopLevel(const xmlChar * name, const xmlChar * URI)
|
|
|
|
|
{
|
|
|
|
|
if ((xsltTopLevelsHash == NULL) || (name == NULL) || (URI == NULL))
|
|
|
|
|
return (-1);
|
|
|
|
|
|
|
|
|
@ -1289,7 +1453,8 @@ xsltUnregisterExtModuleTopLevel (const xmlChar *name,
|
|
|
|
|
* Unregisters all extension module function
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
xsltUnregisterAllExtModuleTopLevel (void) {
|
|
|
|
|
xsltUnregisterAllExtModuleTopLevel(void)
|
|
|
|
|
{
|
|
|
|
|
xmlHashFree(xsltTopLevelsHash, NULL);
|
|
|
|
|
xsltTopLevelsHash = NULL;
|
|
|
|
|
}
|
|
|
|
@ -1304,7 +1469,8 @@ xsltUnregisterAllExtModuleTopLevel (void) {
|
|
|
|
|
* returns a pointer to the hash table if found, else NULL
|
|
|
|
|
*/
|
|
|
|
|
xmlHashTablePtr
|
|
|
|
|
xsltGetExtInfo (xsltStylesheetPtr style, const xmlChar *URI) {
|
|
|
|
|
xsltGetExtInfo(xsltStylesheetPtr style, const xmlChar * URI)
|
|
|
|
|
{
|
|
|
|
|
xsltExtDataPtr data;
|
|
|
|
|
|
|
|
|
|
if (style != NULL && style->extInfos != NULL) {
|
|
|
|
@ -1338,7 +1504,8 @@ static xmlChar *testStyleData = NULL;
|
|
|
|
|
* function libxslt:test() for testing the extensions support.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
xsltExtFunctionTest(xmlXPathParserContextPtr ctxt, int nargs ATTRIBUTE_UNUSED)
|
|
|
|
|
xsltExtFunctionTest(xmlXPathParserContextPtr ctxt,
|
|
|
|
|
int nargs ATTRIBUTE_UNUSED)
|
|
|
|
|
{
|
|
|
|
|
xsltTransformContextPtr tctxt;
|
|
|
|
|
void *data = NULL;
|
|
|
|
@ -1388,7 +1555,8 @@ xsltExtFunctionTest(xmlXPathParserContextPtr ctxt, int nargs ATTRIBUTE_UNUSED)
|
|
|
|
|
*/
|
|
|
|
|
static xsltElemPreCompPtr
|
|
|
|
|
xsltExtElementPreCompTest(xsltStylesheetPtr style, xmlNodePtr inst,
|
|
|
|
|
xsltTransformFunction function) {
|
|
|
|
|
xsltTransformFunction function)
|
|
|
|
|
{
|
|
|
|
|
xsltElemPreCompPtr ret;
|
|
|
|
|
|
|
|
|
|
if (style == NULL) {
|
|
|
|
@ -1404,14 +1572,16 @@ xsltExtElementPreCompTest(xsltStylesheetPtr style, xmlNodePtr inst,
|
|
|
|
|
if (testStyleData == NULL) {
|
|
|
|
|
xsltTransformError(NULL, style, inst,
|
|
|
|
|
"xsltExtElementPreCompTest: not initialized\n");
|
|
|
|
|
if (style != NULL) style->errors++;
|
|
|
|
|
if (style != NULL)
|
|
|
|
|
style->errors++;
|
|
|
|
|
return (NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (inst == NULL) {
|
|
|
|
|
xsltTransformError(NULL, style, inst,
|
|
|
|
|
"xsltExtElementPreCompTest: no instruction\n");
|
|
|
|
|
if (style != NULL) style->errors++;
|
|
|
|
|
if (style != NULL)
|
|
|
|
|
style->errors++;
|
|
|
|
|
return (NULL);
|
|
|
|
|
}
|
|
|
|
|
ret = xsltNewElemPreComp(style, inst, function);
|
|
|
|
@ -1465,8 +1635,7 @@ xsltExtElementTest(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
|
|
|
|
"xsltExtElementTest: no insertion point\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
commentNode =
|
|
|
|
|
xmlNewComment((const xmlChar *)
|
|
|
|
|
commentNode = xmlNewComment((const xmlChar *)
|
|
|
|
|
"libxslt:test element test worked");
|
|
|
|
|
xmlAddChild(ctxt->insert, commentNode);
|
|
|
|
|
}
|
|
|
|
@ -1481,7 +1650,8 @@ xsltExtElementTest(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
|
|
|
|
* Returns a pointer to the module specific data for this transformation
|
|
|
|
|
*/
|
|
|
|
|
static void *
|
|
|
|
|
xsltExtInitTest(xsltTransformContextPtr ctxt, const xmlChar * URI) {
|
|
|
|
|
xsltExtInitTest(xsltTransformContextPtr ctxt, const xmlChar * URI)
|
|
|
|
|
{
|
|
|
|
|
if (testStyleData == NULL) {
|
|
|
|
|
xsltGenericDebug(xsltGenericErrorContext,
|
|
|
|
|
"xsltExtInitTest: not initialized,"
|
|
|
|
@ -1515,7 +1685,8 @@ xsltExtInitTest(xsltTransformContextPtr ctxt, const xmlChar * URI) {
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
xsltExtShutdownTest(xsltTransformContextPtr ctxt,
|
|
|
|
|
const xmlChar * URI, void *data) {
|
|
|
|
|
const xmlChar * URI, void *data)
|
|
|
|
|
{
|
|
|
|
|
if (testData == NULL) {
|
|
|
|
|
xsltTransformError(ctxt, NULL, NULL,
|
|
|
|
|
"xsltExtShutdownTest: not initialized\n");
|
|
|
|
@ -1529,6 +1700,7 @@ xsltExtShutdownTest(xsltTransformContextPtr ctxt,
|
|
|
|
|
xsltGenericDebug(xsltGenericDebugContext,
|
|
|
|
|
"Unregistered test module : %s\n", URI);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* xsltExtStyleInitTest:
|
|
|
|
|
* @style: an XSLT stylesheet
|
|
|
|
@ -1564,7 +1736,8 @@ xsltExtStyleInitTest(xsltStylesheetPtr style ATTRIBUTE_UNUSED,
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
xsltExtStyleShutdownTest(xsltStylesheetPtr style ATTRIBUTE_UNUSED,
|
|
|
|
|
const xmlChar * URI, void *data) {
|
|
|
|
|
const xmlChar * URI, void *data)
|
|
|
|
|
{
|
|
|
|
|
if (testStyleData == NULL) {
|
|
|
|
|
xsltGenericError(xsltGenericErrorContext,
|
|
|
|
|
"xsltExtShutdownTest: not initialized\n");
|
|
|
|
@ -1585,7 +1758,8 @@ xsltExtStyleShutdownTest(xsltStylesheetPtr style ATTRIBUTE_UNUSED,
|
|
|
|
|
* Registers the test module
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
xsltRegisterTestModule (void) {
|
|
|
|
|
xsltRegisterTestModule(void)
|
|
|
|
|
{
|
|
|
|
|
xsltRegisterExtModuleFull((const xmlChar *) XSLT_DEFAULT_URL,
|
|
|
|
|
xsltExtInitTest, xsltExtShutdownTest,
|
|
|
|
|
xsltExtStyleInitTest,
|
|
|
|
@ -1599,6 +1773,15 @@ xsltRegisterTestModule (void) {
|
|
|
|
|
xsltExtElementTest);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
xsltHashScannerModuleFree(void *payload, void *data ATTRIBUTE_UNUSED,
|
|
|
|
|
xmlChar * name ATTRIBUTE_UNUSED)
|
|
|
|
|
{
|
|
|
|
|
#ifdef WITH_MODULES
|
|
|
|
|
xmlModuleClose(payload);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* xsltCleanupGlobals:
|
|
|
|
|
*
|
|
|
|
@ -1611,13 +1794,21 @@ xsltCleanupGlobals(void)
|
|
|
|
|
xsltUnregisterAllExtModuleFunction();
|
|
|
|
|
xsltUnregisterAllExtModuleElement();
|
|
|
|
|
xsltUnregisterAllExtModuleTopLevel();
|
|
|
|
|
|
|
|
|
|
/* cleanup dynamic module hash */
|
|
|
|
|
if (NULL != xsltModuleHash) {
|
|
|
|
|
xmlHashScan(xsltModuleHash, xsltHashScannerModuleFree, 0);
|
|
|
|
|
xmlHashFree(xsltModuleHash, NULL);
|
|
|
|
|
xsltModuleHash = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
xsltDebugDumpExtensionsCallback(void *function ATTRIBUTE_UNUSED,
|
|
|
|
|
FILE * output, const xmlChar * name,
|
|
|
|
|
const xmlChar * URI,
|
|
|
|
|
const xmlChar* not_used ATTRIBUTE_UNUSED) {
|
|
|
|
|
const xmlChar * not_used ATTRIBUTE_UNUSED)
|
|
|
|
|
{
|
|
|
|
|
if (!name || !URI)
|
|
|
|
|
return;
|
|
|
|
|
fprintf(output, "{%s}%s\n", URI, name);
|
|
|
|
@ -1627,7 +1818,8 @@ static void
|
|
|
|
|
xsltDebugDumpExtModulesCallback(void *function ATTRIBUTE_UNUSED,
|
|
|
|
|
FILE * output, const xmlChar * URI,
|
|
|
|
|
const xmlChar * not_used ATTRIBUTE_UNUSED,
|
|
|
|
|
const xmlChar* not_used2 ATTRIBUTE_UNUSED) {
|
|
|
|
|
const xmlChar * not_used2 ATTRIBUTE_UNUSED)
|
|
|
|
|
{
|
|
|
|
|
if (!URI)
|
|
|
|
|
return;
|
|
|
|
|
fprintf(output, "%s\n", URI);
|
|
|
|
@ -1644,25 +1836,31 @@ xsltDebugDumpExtensions(FILE * output)
|
|
|
|
|
{
|
|
|
|
|
if (output == NULL)
|
|
|
|
|
output = stdout;
|
|
|
|
|
fprintf(output,"Registered XSLT Extensions\n--------------------------\n");
|
|
|
|
|
fprintf(output,
|
|
|
|
|
"Registered XSLT Extensions\n--------------------------\n");
|
|
|
|
|
if (!xsltFunctionsHash)
|
|
|
|
|
fprintf(output, "No registered extension functions\n");
|
|
|
|
|
else {
|
|
|
|
|
fprintf(output, "Registered Extension Functions:\n");
|
|
|
|
|
xmlHashScanFull(xsltFunctionsHash,(xmlHashScannerFull)xsltDebugDumpExtensionsCallback,output);
|
|
|
|
|
xmlHashScanFull(xsltFunctionsHash,
|
|
|
|
|
(xmlHashScannerFull)
|
|
|
|
|
xsltDebugDumpExtensionsCallback, output);
|
|
|
|
|
}
|
|
|
|
|
if (!xsltElementsHash)
|
|
|
|
|
fprintf(output, "\nNo registered extension elements\n");
|
|
|
|
|
else {
|
|
|
|
|
fprintf(output, "\nRegistered Extension Elements:\n");
|
|
|
|
|
xmlHashScanFull(xsltElementsHash,(xmlHashScannerFull)xsltDebugDumpExtensionsCallback,output);
|
|
|
|
|
xmlHashScanFull(xsltElementsHash,
|
|
|
|
|
(xmlHashScannerFull)
|
|
|
|
|
xsltDebugDumpExtensionsCallback, output);
|
|
|
|
|
}
|
|
|
|
|
if (!xsltExtensionsHash)
|
|
|
|
|
fprintf(output, "\nNo registered extension modules\n");
|
|
|
|
|
else {
|
|
|
|
|
fprintf(output, "\nRegistered Extension Modules:\n");
|
|
|
|
|
xmlHashScanFull(xsltExtensionsHash,(xmlHashScannerFull)xsltDebugDumpExtModulesCallback,output);
|
|
|
|
|
xmlHashScanFull(xsltExtensionsHash,
|
|
|
|
|
(xmlHashScannerFull)
|
|
|
|
|
xsltDebugDumpExtModulesCallback, output);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|