1
0
mirror of https://gitlab.gnome.org/GNOME/libxslt synced 2025-08-07 10:42:55 +03:00

Next step of refactoring (plus some bug-fixes). For more details see

* libxslt/xsltInternals.h libxslt/attributes.c
  libxslt/documents.c libxslt/extensions.c
  libxslt/extensions.h libxslt/functions.c
  libxslt/imports.c libxslt/keys.c libxslt/preproc.c
  libxslt/transform.c libxslt/variables.c libxslt/xslt.c
  libxslt/xsltutils.c libxslt/xsltutils.h libexslt/functions.c:
  Next step of refactoring (plus some bug-fixes).
  For more details see #340780.
This commit is contained in:
Kasimier T. Buchcik
2006-05-05 21:18:25 +00:00
parent 178887dd23
commit eb037ebd81
15 changed files with 4803 additions and 921 deletions

View File

@@ -1,3 +1,14 @@
Fri May 5 23:10:47 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
* libxslt/xsltInternals.h libxslt/attributes.c
libxslt/documents.c libxslt/extensions.c
libxslt/extensions.h libxslt/functions.c
libxslt/imports.c libxslt/keys.c libxslt/preproc.c
libxslt/transform.c libxslt/variables.c libxslt/xslt.c
libxslt/xsltutils.c libxslt/xsltutils.h libexslt/functions.c:
Next step of refactoring (plus some bug-fixes).
For more details see #340780.
Fri May 5 14:31:53 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
* tests/exslt/common/node-set.5.out

View File

@@ -128,6 +128,10 @@ exsltFuncRegisterImportFunc (exsltFuncFunctionData *data,
* @URI: the namespace URI for the extension
*
* Initializes the EXSLT - Functions module.
* Called at transformation-time; merges all
* functions declared in the import tree taking
* import precedence into account, i.e. overriding
* functions with lower import precedence.
*
* Returns the data for this transformation
*/
@@ -170,8 +174,9 @@ exsltFuncInit (xsltTransformContextPtr ctxt, const xmlChar *URI) {
* @ctxt: an XSLT transformation context
* @URI: the namespace URI for the extension
* @data: the module data to free up
*
*
* Shutdown the EXSLT - Functions module
* Called at transformation-time.
*/
static void
exsltFuncShutdown (xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED,
@@ -188,6 +193,7 @@ exsltFuncShutdown (xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED,
* @URI: the namespace URI for the extension
*
* Allocates the stylesheet data for EXSLT - Function
* Called at compile-time.
*
* Returns the allocated data
*/
@@ -201,9 +207,10 @@ exsltFuncStyleInit (xsltStylesheetPtr style ATTRIBUTE_UNUSED,
* exsltFuncStyleShutdown:
* @style: an XSLT stylesheet
* @URI: the namespace URI for the extension
* @data: the stylesheet data to free up
* @data: the stylesheet data to free up
*
* Shutdown the EXSLT - Function module
* Called at compile-time.
*/
static void
exsltFuncStyleShutdown (xsltStylesheetPtr style ATTRIBUTE_UNUSED,
@@ -431,8 +438,19 @@ exsltFuncFunctionComp (xsltStylesheetPtr style, xmlNodePtr inst) {
* Register the function data such that it can be retrieved
* by exslFuncFunctionFunction
*/
data = (xmlHashTablePtr) xsltStyleGetExtData (style,
EXSLT_FUNCTIONS_NAMESPACE);
#ifdef XSLT_REFACTORED
/*
* Ensure that the hash table will be stored in the *current*
* stylesheet level in order to correctly evaluate the
* import precedence.
*/
data = (xmlHashTablePtr)
xsltStyleStylesheetLevelGetExtData(style,
EXSLT_FUNCTIONS_NAMESPACE);
#else
data = (xmlHashTablePtr)
xsltStyleGetExtData (style, EXSLT_FUNCTIONS_NAMESPACE);
#endif
if (data == NULL) {
xsltGenericError(xsltGenericErrorContext,
"exsltFuncFunctionComp: no stylesheet data\n");
@@ -441,9 +459,10 @@ exsltFuncFunctionComp (xsltStylesheetPtr style, xmlNodePtr inst) {
}
if (xmlHashAddEntry2 (data, ns->href, name, func) < 0) {
xsltGenericError(xsltGenericErrorContext,
"Failed to register function {%s}%s\n",
xsltTransformError(NULL, style, inst,
"Failed to register function {%s}%s\n",
ns->href, name);
style->errors++;
} else {
xsltGenericDebug(xsltGenericDebugContext,
"exsltFuncFunctionComp: register {%s}%s\n",

View File

@@ -46,6 +46,7 @@
#include "templates.h"
#include "imports.h"
#include "transform.h"
#include "preproc.h"
#define WITH_XSLT_DEBUG_ATTRIBUTES
#ifdef WITH_XSLT_DEBUG
@@ -143,6 +144,11 @@ xsltFreeAttrElemList(xsltAttrElemPtr list) {
}
}
#ifdef XSLT_REFACTORED
/*
* This was moved to xsltParseStylesheetAttributeSet().
*/
#else
/**
* xsltAddAttrElemList:
* @list: an XSLT AttrElem list
@@ -161,7 +167,7 @@ xsltAddAttrElemList(xsltAttrElemPtr list, xmlNodePtr attr) {
if (list == NULL)
return(xsltNewAttrElem(attr));
cur = list;
while (cur != NULL) {
while (cur != NULL) {
next = cur->next;
if (cur->attr == attr)
return(cur);
@@ -173,6 +179,7 @@ xsltAddAttrElemList(xsltAttrElemPtr list, xmlNodePtr attr) {
}
return(list);
}
#endif /* XSLT_REFACTORED */
/**
* xsltMergeAttrElemList:
@@ -185,7 +192,8 @@ xsltAddAttrElemList(xsltAttrElemPtr list, xmlNodePtr attr) {
* Returns the new list pointer
*/
static xsltAttrElemPtr
xsltMergeAttrElemList(xsltAttrElemPtr list, xsltAttrElemPtr old) {
xsltMergeAttrElemList(xsltStylesheetPtr style,
xsltAttrElemPtr list, xsltAttrElemPtr old) {
xsltAttrElemPtr cur;
int add;
@@ -233,19 +241,23 @@ xsltMergeAttrElemList(xsltAttrElemPtr list, xsltAttrElemPtr old) {
}
if (add == 1) {
/*
* Changed to use the string-dict, rather than duplicating
* @set and @ns; this fixes bug #340400.
*/
if (cur == NULL) {
list = xsltNewAttrElem(old->attr);
if (old->set != NULL) {
list->set = xmlStrdup(old->set);
list->set = xmlDictLookup(style->dict, old->set, -1);
if (old->ns != NULL)
list->ns = xmlStrdup(old->ns);
list->ns = xmlDictLookup(style->dict, old->ns, -1);
}
} else if (add) {
cur->next = xsltNewAttrElem(old->attr);
if (old->set != NULL) {
cur->next->set = xmlStrdup(old->set);
cur->next->set = xmlDictLookup(style->dict, old->set, -1);
if (old->ns != NULL)
cur->next->ns = xmlStrdup(old->ns);
cur->next->ns = xmlDictLookup(style->dict, old->ns, -1);
}
}
}
@@ -273,24 +285,23 @@ void
xsltParseStylesheetAttributeSet(xsltStylesheetPtr style, xmlNodePtr cur) {
const xmlChar *ncname;
const xmlChar *prefix;
const xmlChar *attrib, *endattr;
xmlChar *prop;
xmlChar *attributes;
xmlNodePtr list;
xsltAttrElemPtr values;
xmlChar *value;
xmlNodePtr child;
xsltAttrElemPtr attrItems;
if ((cur == NULL) || (style == NULL))
return;
prop = xmlGetNsProp(cur, (const xmlChar *)"name", NULL);
if (prop == NULL) {
value = xmlGetNsProp(cur, (const xmlChar *)"name", NULL);
if (value == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsl:attribute-set : name is missing\n");
return;
}
ncname = xsltSplitQName(style->dict, prop, &prefix);
xmlFree(prop);
ncname = xsltSplitQName(style->dict, value, &prefix);
xmlFree(value);
value = NULL;
if (style->attributeSets == NULL) {
#ifdef WITH_XSLT_DEBUG_ATTRIBUTES
@@ -302,80 +313,141 @@ xsltParseStylesheetAttributeSet(xsltStylesheetPtr style, xmlNodePtr cur) {
if (style->attributeSets == NULL)
return;
values = xmlHashLookup2(style->attributeSets, ncname, prefix);
attrItems = xmlHashLookup2(style->attributeSets, ncname, prefix);
/*
* check the children list
*/
list = cur->children;
while (list != NULL) {
if (IS_XSLT_ELEM(list)) {
if (!IS_XSLT_NAME(list, "attribute")) {
xsltGenericError(xsltGenericErrorContext,
"xsl:attribute-set : unexpected child xsl:%s\n",
list->name);
} else {
#ifdef WITH_XSLT_DEBUG_ATTRIBUTES
xsltGenericDebug(xsltGenericDebugContext,
"add attribute to list %s\n", ncname);
#endif
values = xsltAddAttrElemList(values, list);
}
* Parse the content. Only xsl:attribute elements are allowed.
*/
child = cur->children;
while (child != NULL) {
/*
* Report invalid nodes.
*/
if ((child->type != XML_ELEMENT_NODE) ||
(child->ns == NULL) ||
(! IS_XSLT_ELEM(child)))
{
if (child->type == XML_ELEMENT_NODE)
xsltTransformError(NULL, style, child,
"xsl:attribute-set : unexpected child %s\n",
child->name);
else
xsltTransformError(NULL, style, child,
"xsl:attribute-set : child of unexpected type\n");
} else if (!IS_XSLT_NAME(child, "attribute")) {
xsltTransformError(NULL, style, child,
"xsl:attribute-set : unexpected child xsl:%s\n",
child->name);
} else {
xsltGenericError(xsltGenericErrorContext,
"xsl:attribute-set : unexpected child %s\n", list->name);
}
list = list->next;
}
#ifdef XSLT_REFACTORED
xsltAttrElemPtr nextAttr, curAttr;
/*
* Check a possible use-attribute-sets definition
*/
/* TODO check recursion */
attributes = xmlGetNsProp(cur, (const xmlChar *)"use-attribute-sets",
NULL);
if (attributes == NULL) {
goto done;
}
attrib = attributes;
while (*attrib != 0) {
while (IS_BLANK(*attrib)) attrib++;
if (*attrib == 0)
break;
endattr = attrib;
while ((*endattr != 0) && (!IS_BLANK(*endattr))) endattr++;
attrib = xmlDictLookup(style->dict, attrib, endattr - attrib);
if (attrib) {
const xmlChar *ncname2 = NULL;
const xmlChar *prefix2 = NULL;
xsltAttrElemPtr values2;
/*
* Process xsl:attribute
* ---------------------
*/
#ifdef WITH_XSLT_DEBUG_ATTRIBUTES
xsltGenericDebug(xsltGenericDebugContext,
"xsl:attribute-set : %s adds use %s\n", ncname, attrib);
"add attribute to list %s\n", ncname);
#endif
ncname2 = xsltSplitQName(style->dict, attrib, &prefix2);
values2 = xsltNewAttrElem(NULL);
if (values2 != NULL) {
values2->set = ncname2;
values2->ns = prefix2;
values = xsltMergeAttrElemList(values, values2);
xsltFreeAttrElem(values2);
/*
* The following was taken over from
* xsltAddAttrElemList().
*/
if (attrItems == NULL) {
attrItems = xsltNewAttrElem(child);
} else {
curAttr = attrItems;
while (curAttr != NULL) {
nextAttr = curAttr->next;
if (curAttr->attr == child) {
/*
* URGENT TODO: Can somebody explain
* why attrItems is set to curAttr
* here? Is this somehow related to
* avoidance of recursions?
*/
attrItems = curAttr;
goto next_child;
}
if (curAttr->next == NULL)
curAttr->next = xsltNewAttrElem(child);
curAttr = nextAttr;
}
}
/*
* Parse the xsl:attribute and its content.
*/
xsltParseAnyXSLTElem(XSLT_CCTXT(style), child);
#else
#ifdef WITH_XSLT_DEBUG_ATTRIBUTES
xsltGenericDebug(xsltGenericDebugContext,
"add attribute to list %s\n", ncname);
#endif
/*
* OLD behaviour:
*/
attrItems = xsltAddAttrElemList(attrItems, child);
#endif
}
attrib = endattr;
}
xmlFree(attributes);
done:
#ifdef XSLT_REFACTORED
next_child:
#endif
child = child->next;
}
/*
* Process attribue "use-attribute-sets".
*/
/* TODO check recursion */
value = xmlGetNsProp(cur, (const xmlChar *)"use-attribute-sets",
NULL);
if (value != NULL) {
const xmlChar *curval, *endval;
curval = value;
while (*curval != 0) {
while (IS_BLANK(*curval)) curval++;
if (*curval == 0)
break;
endval = curval;
while ((*endval != 0) && (!IS_BLANK(*endval))) endval++;
curval = xmlDictLookup(style->dict, curval, endval - curval);
if (curval) {
const xmlChar *ncname2 = NULL;
const xmlChar *prefix2 = NULL;
xsltAttrElemPtr refAttrItems;
#ifdef WITH_XSLT_DEBUG_ATTRIBUTES
xsltGenericDebug(xsltGenericDebugContext,
"xsl:attribute-set : %s adds use %s\n", ncname, curval);
#endif
ncname2 = xsltSplitQName(style->dict, curval, &prefix2);
refAttrItems = xsltNewAttrElem(NULL);
if (refAttrItems != NULL) {
refAttrItems->set = ncname2;
refAttrItems->ns = prefix2;
attrItems = xsltMergeAttrElemList(style,
attrItems, refAttrItems);
xsltFreeAttrElem(refAttrItems);
}
}
curval = endval;
}
xmlFree(value);
value = NULL;
}
/*
* Update the value
*/
if (values == NULL)
values = xsltNewAttrElem(NULL);
xmlHashUpdateEntry2(style->attributeSets, ncname, prefix, values, NULL);
/*
* TODO: Why is this dummy entry needed.?
*/
if (attrItems == NULL)
attrItems = xsltNewAttrElem(NULL);
xmlHashUpdateEntry2(style->attributeSets, ncname, prefix, attrItems, NULL);
#ifdef WITH_XSLT_DEBUG_ATTRIBUTES
xsltGenericDebug(xsltGenericDebugContext,
"updated attribute list %s\n", ncname);
@@ -447,15 +519,12 @@ xsltResolveSASCallback(xsltAttrElemPtr values, xsltStylesheetPtr style,
/*
* Then merge
*/
xsltMergeAttrElemList(values, refs);
xsltMergeAttrElemList(style, values, refs);
/*
* Then suppress the reference
*/
xmlFree((char *)tmp->set);
tmp->set = NULL;
if (tmp->ns != NULL) {
xmlFree((char *)tmp->ns);
}
tmp->ns = NULL;
}
}
}
@@ -492,7 +561,7 @@ xsltMergeSASCallback(xsltAttrElemPtr values, xsltStylesheetPtr style,
"xsl:attribute-set : logic error merging from imports for"
" attribute-set %s\n", name);
} else {
topSet = xsltMergeAttrElemList(topSet, values);
topSet = xsltMergeAttrElemList(style, topSet, values);
xmlHashUpdateEntry2(style->attributeSets, name, ns, topSet, NULL);
}
xsltFreeAttrElemList(values);

View File

@@ -192,18 +192,42 @@ xsltNewStyleDocument(xsltStylesheetPtr style, xmlDocPtr doc) {
/**
* xsltFreeStyleDocuments:
* @style: an XSLT style sheet
* @style: an XSLT stylesheet (representing a stylesheet-level)
*
* Free up all the space used by the loaded documents
* Frees the node-trees (and xsltDocument structures) of all
* stylesheet-modules of the stylesheet-level represented by
* the given @style.
*/
void
xsltFreeStyleDocuments(xsltStylesheetPtr style) {
xsltDocumentPtr doc, cur;
#ifdef XSLT_REFACTORED
xsltNsMapPtr nsMap;
#endif
if (style == NULL)
return;
#ifdef XSLT_REFACTORED
if (XSLT_HAS_INTERNAL_NSMAP(style))
nsMap = XSLT_GET_INTERNAL_NSMAP(style);
else
nsMap = NULL;
#endif
cur = style->docList;
while (cur != NULL) {
doc = cur;
cur = cur->next;
#ifdef XSLT_REFACTORED
/*
* Restore all changed namespace URIs of ns-decls.
*/
if (nsMap)
xsltRestoreDocumentNamespaces(nsMap, doc->doc);
#endif
xsltFreeDocumentKeys(doc);
if (!doc->main)
xmlFreeDoc(doc->doc);

View File

@@ -469,12 +469,19 @@ xsltFreeExts(xsltStylesheetPtr style)
/**
* xsltRegisterExtPrefix:
* @style: an XSLT stylesheet
* @prefix: the prefix used
* @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 in case of failure
* 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,
@@ -482,7 +489,7 @@ xsltRegisterExtPrefix(xsltStylesheetPtr style,
{
xsltExtDefPtr def, ret;
if ((style == NULL) || (prefix == NULL) | (URI == NULL))
if ((style == NULL) || (URI == NULL))
return (-1);
#ifdef WITH_XSLT_DEBUG_EXTENSIONS
@@ -491,11 +498,22 @@ xsltRegisterExtPrefix(xsltStylesheetPtr style,
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);
@@ -506,6 +524,12 @@ xsltRegisterExtPrefix(xsltStylesheetPtr style,
* check wether there is an extension module with a stylesheet
* initialization function.
*/
#ifdef XSLT_REFACTORED
/*
* Don't initialize modules based on specified namespaced via
* the attribute "[xsl:]extension-element-prefixes".
*/
#else
if (xsltExtensionsHash != NULL) {
xsltExtModulePtr module;
@@ -515,11 +539,11 @@ xsltRegisterExtPrefix(xsltStylesheetPtr style,
module = xmlHashLookup(xsltExtensionsHash, URI);
}
}
if (module != NULL) {
xsltStyleGetExtData(style, URI);
}
}
#endif
return (0);
}
@@ -599,83 +623,198 @@ xsltFreeCtxtExts(xsltTransformContextPtr ctxt)
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);
}
module = xmlHashLookup(xsltExtensionsHash, URI);
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);
}
/**
* xsltStyleGetExtDataPerStylesheetLevel:
* @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 *
xsltStyleGetExtData(xsltStylesheetPtr style, const xmlChar * URI)
xsltStyleStylesheetLevelGetExtData(xsltStylesheetPtr style,
const xmlChar * URI)
{
xsltExtDataPtr data = NULL;
xsltStylesheetPtr tmp;
xsltExtDataPtr dataContainer = NULL;
if ((style == NULL) || (URI == NULL) ||
(xsltExtensionsHash == NULL))
return (NULL);
if ((style == NULL) || (URI == 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);
}
tmp = style;
while (tmp != NULL) {
if (tmp->extInfos != NULL) {
data = (xsltExtDataPtr) xmlHashLookup(tmp->extInfos, URI);
if (data != NULL)
break;
}
tmp = xsltNextImport(tmp);
}
if (data == NULL) {
if (style->extInfos == NULL) {
style->extInfos = xmlHashCreate(10);
if (style->extInfos == NULL)
return (NULL);
}
}
if (data == NULL) {
void *extData;
xsltExtModulePtr module;
module = xmlHashLookup(xsltExtensionsHash, URI);
if (module == NULL) {
#ifdef WITH_XSLT_DEBUG_EXTENSIONS
xsltGenericDebug(xsltGenericDebugContext,
"Not registered extension module: %s\n", URI);
#endif
return (NULL);
} else {
if (module->styleInitFunc == NULL) {
#ifdef WITH_XSLT_DEBUG_EXTENSIONS
xsltGenericDebug(xsltGenericDebugContext,
"Registering style module: %s\n", URI);
#endif
extData = NULL;
} else {
#ifdef WITH_XSLT_DEBUG_EXTENSIONS
xsltGenericDebug(xsltGenericDebugContext,
"Initializing module: %s\n", URI);
#endif
extData = module->styleInitFunc(style, URI);
}
data = xsltNewExtData(module, extData);
if (data == NULL)
return (NULL);
if (xmlHashAddEntry(style->extInfos, URI, (void *) data) < 0) {
xsltGenericError(xsltGenericErrorContext,
"Failed to register module data: %s\n",
URI);
if (module->styleShutdownFunc)
module->styleShutdownFunc(style, URI, extData);
xsltFreeExtData(data);
return (NULL);
}
}
}
return (data->extData);
dataContainer =
xsltStyleInitializeStylesheetModule(style, URI);
if (dataContainer != NULL)
return (dataContainer->extData);
return(NULL);
}
/**
@@ -939,8 +1078,13 @@ xsltShutdownExt(xsltExtDataPtr data, xsltStylesheetPtr style,
"Shutting down module : %s\n", URI);
#endif
module->styleShutdownFunc(style, URI, data->extData);
xmlHashRemoveEntry(style->extInfos, URI,
(xmlHashDeallocator) xsltFreeExtData);
/*
* 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);
*/
}
/**
@@ -964,29 +1108,59 @@ xsltShutdownExts(xsltStylesheetPtr style)
/**
* xsltCheckExtPrefix:
* @style: the stylesheet
* @prefix: the namespace prefix (possibly NULL)
* @URI: the namespace URI (possibly NULL)
*
* Check if the given prefix is one of the declared extensions
* 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 * prefix)
{
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 (prefix == NULL)
prefix = BAD_CAST "#default";
if (URI == NULL)
URI = BAD_CAST "#default";
cur = (xsltExtDefPtr) style->nsDefs;
while (cur != NULL) {
if (xmlStrEqual(prefix, cur->prefix))
/*
* TODO: This is the old behaviour and it won't work
* correctly, since it works with the namespace prefix,
* but it should work with the namespace name.
*/
if (xmlStrEqual(URI, cur->prefix))
return (1);
cur = cur->next;
}
#endif
return (0);
}
@@ -1281,13 +1455,39 @@ xsltPreComputeExtModuleElement(xsltStylesheetPtr style, xmlNodePtr inst)
ext = (xsltExtElementPtr)
xmlHashLookup2(xsltElementsHash, inst->name, inst->ns->href);
/*
* EXT TODO: Now what?
*/
if (ext == NULL)
return (NULL);
if (ext->precomp != 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)
}
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);
}
@@ -1553,6 +1753,13 @@ 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)

View File

@@ -93,7 +93,12 @@ XSLTPUBFUN void * XSLTCALL
XSLTPUBFUN void * XSLTCALL
xsltStyleGetExtData (xsltStylesheetPtr style,
const xmlChar *URI);
#ifdef XSLT_REFACTORED
XSLTPUBFUN void * XSLTCALL
xsltStyleStylesheetLevelGetExtData(
xsltStylesheetPtr style,
const xmlChar * URI);
#endif
XSLTPUBFUN void XSLTCALL
xsltShutdownCtxtExts (xsltTransformContextPtr ctxt);
@@ -210,7 +215,7 @@ XSLTPUBFUN int XSLTCALL
const xmlChar *URI);
XSLTPUBFUN int XSLTCALL
xsltCheckExtPrefix (xsltStylesheetPtr style,
const xmlChar *prefix);
const xmlChar *URI);
XSLTPUBFUN int XSLTCALL
xsltInitCtxtExts (xsltTransformContextPtr ctxt);
XSLTPUBFUN void XSLTCALL

View File

@@ -41,6 +41,7 @@
#include "xslt.h"
#include "xsltInternals.h"
#include "xsltutils.h"
#include "preproc.h"
#include "imports.h"
#include "documents.h"
#include "security.h"
@@ -229,7 +230,16 @@ xsltParseStylesheetInclude(xsltStylesheetPtr style, xmlNodePtr cur) {
"xsl:include : unable to load %s\n", URI);
goto error;
}
#ifdef XSLT_REFACTORED
if (IS_XSLT_ELEM_FAST(cur) && (cur->psvi != NULL)) {
((xsltStyleItemIncludePtr) cur->psvi)->include = include;
} else {
xsltTransformError(NULL, style, cur,
"Internal error: (xsltParseStylesheetInclude) "
"The xsl:include element was not compiled.\n", URI);
style->errors++;
}
#endif
oldDoc = style->doc;
style->doc = include->doc;
/* chain to stylesheet for recursion checking */
@@ -237,6 +247,12 @@ xsltParseStylesheetInclude(xsltStylesheetPtr style, xmlNodePtr cur) {
style->includes = include;
oldNopreproc = style->nopreproc;
style->nopreproc = include->preproc;
/*
* TODO: This will change some values of the
* including stylesheet with every included module
* (e.g. excluded-result-prefixes)
* We need to strictly seperate such stylesheet-owned values.
*/
result = xsltParseStylesheetProcess(style, include->doc);
style->nopreproc = oldNopreproc;
include->preproc = 1;
@@ -359,6 +375,13 @@ xsltFindElemSpaceHandling(xsltTransformContextPtr ctxt, xmlNodePtr node) {
* @nameURI: the template name URI
*
* Finds the named template, apply import precedence rule.
* REVISIT TODO: We'll change the nameURI fields of
* templates to be in the string dict, so if the
* specified @nameURI is in the same dict, then use pointer
* comparison. Check if this can be done in a sane way.
* Maybe this function is not needed internally at
* transformation-time if we hard-wire the called templates
* to the caller.
*
* Returns the xsltTemplatePtr or NULL if not found
*/

View File

@@ -369,6 +369,14 @@ xsltAddKey(xsltStylesheetPtr style, const xmlChar *name,
xsltGenericDebug(xsltGenericDebugContext,
" resulting pattern %s\n", pattern);
#endif
/*
* XSLT-1: "It is an error for the value of either the use
* attribute or the match attribute to contain a
* VariableReference."
* TODO: We should report a variable-reference at compile-time.
* Maybe a search for "$", if it occurs outside of quotation
* marks, could be sufficient.
*/
key->comp = xsltXPathCompile(style, pattern);
if (key->comp == NULL) {
xsltTransformError(NULL, style, inst,

View File

@@ -52,6 +52,11 @@ const xmlChar *xsltExtMarker = (const xmlChar *) "Extension Element";
* *
************************************************************************/
#ifdef XSLT_REFACTORED
/*
* Grammar checks are now performed in xslt.c.
*/
#else
/**
* xsltCheckTopLevelElement:
* @style: the XSLT stylesheet
@@ -197,6 +202,7 @@ xsltCheckParentElement(xsltStylesheetPtr style, xmlNodePtr inst,
inst->name);
style->errors++;
}
#endif
/************************************************************************
* *
@@ -350,7 +356,6 @@ xsltNewStylePreComp(xsltStylesheetPtr style, xsltStyleType type) {
case XSLT_FUNC_PARAM:
case XSLT_FUNC_VARIABLE:
case XSLT_FUNC_WHEN:
case XSLT_FUNC_OTHERWISE:
break;
default:
if (cur->func == NULL) {
@@ -518,7 +523,8 @@ xsltDocumentComp(xsltStylesheetPtr style, xmlNodePtr inst,
* "output" in XSLT_SAXON_NAMESPACE
* "write" XSLT_XALAN_NAMESPACE
* "document" XSLT_XT_NAMESPACE
* "document" XSLT_NAMESPACE
* "document" XSLT_NAMESPACE (from the abandoned old working
* draft of XSLT 1.1)
* (in libexslt/common.c)
* "document" in EXSLT_COMMON_NAMESPACE
*/
@@ -544,6 +550,8 @@ xsltDocumentComp(xsltStylesheetPtr style, xmlNodePtr inst,
* (http://icl.com/saxon)
* The @file is in no namespace; it is an AVT.
* (http://www.computerwizards.com/saxon/doc/extensions.html#saxon:output)
*
* TODO: Do we need not to check the namespace here?
*/
filename = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"file",
@@ -557,6 +565,10 @@ xsltDocumentComp(xsltStylesheetPtr style, xmlNodePtr inst,
/*
* TODO: Is "filename need to be interpreted" meant to be a todo?
* Where will be the filename of xalan:write be processed?
*
* TODO: Do we need not to check the namespace here?
* The extension ns is "http://xml.apache.org/xalan/redirect".
* See http://xml.apache.org/xalan-j/extensionslib.html.
*/
} else if (xmlStrEqual(inst->name, (const xmlChar *) "document")) {
if (inst->ns != NULL) {
@@ -770,11 +782,17 @@ xsltCopyComp(xsltStylesheetPtr style, xmlNodePtr inst) {
comp->has_use = 1;
}
#ifdef XSLT_REFACTORED
/* Enable if ever needed for xsl:text. */
#else
/**
* xsltTextComp:
* @style: an XSLT compiled stylesheet
* @inst: the xslt text node
*
* TODO: This function is obsolete, since xsl:text won't
* be compiled, but removed from the tree.
*
* Process the xslt text node on the source node
*/
static void
@@ -807,13 +825,14 @@ xsltTextComp(xsltStylesheetPtr style, xmlNodePtr inst) {
if (xmlStrEqual(prop, (const xmlChar *)"yes")) {
comp->noescape = 1;
} else if (!xmlStrEqual(prop,
(const xmlChar *)"no")){
(const xmlChar *)"no")){
xsltTransformError(NULL, style, inst,
"xsl:text: disable-output-escaping allows only yes or no\n");
"xsl:text: disable-output-escaping allows only yes or no\n");
if (style != NULL) style->warnings++;
}
}
}
#endif /* else of XSLT_REFACTORED */
/**
* xsltElementComp:
@@ -1774,85 +1793,6 @@ xsltParamComp(xsltStylesheetPtr style, xmlNodePtr inst) {
}
}
#ifdef XSLT_REFACTORED
/*
* xsltCompilerGetInScopeNSInfo:
*
* Create and store the list of in-scope namespaces for the given
* node in the stylesheet. If there are no changes in the in-scope
* namespaces then the last ns-info of the ancestor axis will be returned.
* Compilation-time only.
*
* Returns the ns-info or NULL if there are no namespaces in scope.
*/
xsltNsListPtr
xsltCompilerGetInScopeNSInfo(xsltCompilerCtxtPtr cctxt, xmlNodePtr node)
{
xsltNsListPtr nsi = NULL;
xmlNsPtr *list = NULL;
/*
* Create a new ns-list for this position in the node-tree.
* xmlGetNsList() will return NULL, if there are no ns-decls in the
* tree. Note that the ns-decl for the XML namespace is not added
* to the resulting list; the XPath module handles the XML namespace
* internally.
*/
list = xmlGetNsList(node->doc, node);
if (list == NULL)
return(NULL);
/*
* Initialize the list hold by the stylesheet.
*/
if (cctxt->sheet->inScopeNamespaces == NULL) {
cctxt->sheet->inScopeNamespaces = xsltPointerListCreate();
if (cctxt->sheet->inScopeNamespaces == NULL) {
xsltTransformError(NULL, cctxt->sheet, NULL,
"xsltCompilerGetInScopeNSInfo: malloc failed.\n");
goto internal_err;
}
}
/*
* Create the info-structure.
*/
nsi = (xsltNsListPtr) xmlMalloc(sizeof(xsltNsList));
if (nsi == NULL) {
xsltTransformError(NULL, cctxt->sheet, NULL,
"xsltCompilerGetInScopeNSInfo: malloc failed.\n");
goto internal_err;
}
memset(nsi, 0, sizeof(xsltNsList));
nsi->list = list;
/*
* Eval the number of ns-decls; this is used to speed up
* XPath-context initialization.
*/
while (list[nsi->number] != NULL)
nsi->number++;
/*
* Store the ns-list in the stylesheet.
*/
if (xsltPointerListAdd(
(xsltPointerListPtr)cctxt->sheet->inScopeNamespaces,
(void *) nsi) == -1)
{
xmlFree(nsi);
nsi = NULL;
xsltTransformError(NULL, cctxt->sheet, NULL,
"xsltCompilerGetInScopeNSInfo: failed to add ns-info.\n");
goto internal_err;
}
return(nsi);
internal_err:
if (list != NULL)
xmlFree(list);
cctxt->sheet->errors++;
return(NULL);
}
#endif /* XSLT_REFACTORED */
/************************************************************************
* *
* Generic interface *
@@ -1870,10 +1810,11 @@ xsltFreeStylePreComps(xsltStylesheetPtr style) {
xsltElemPreCompPtr cur, next;
if (style == NULL)
return;
return;
cur = style->preComps;
while (cur != NULL) {
next = cur->next;
next = cur->next;
if (cur->type == XSLT_FUNC_EXTENSION)
cur->free(cur);
else
@@ -1882,6 +1823,221 @@ xsltFreeStylePreComps(xsltStylesheetPtr style) {
}
}
#ifdef XSLT_REFACTORED
/**
* xsltStylePreCompute:
* @style: the XSLT stylesheet
* @node: the element in the XSLT namespace
*
* Precompute an XSLT element.
* This expects the type of the element to be already
* set in style->compCtxt->inode->type;
*/
void
xsltStylePreCompute(xsltStylesheetPtr style, xmlNodePtr node) {
/*
* The xsltXSLTElemMarker marker was set beforehand by
* the parsing mechanism for all elements in the XSLT namespace.
*/
if (style == NULL) {
if (node != NULL)
node->psvi = NULL;
return;
}
if (node == NULL)
return;
if (! IS_XSLT_ELEM_FAST(node))
return;
node->psvi = NULL;
if (XSLT_CCTXT(style)->inode->type != 0) {
switch (XSLT_CCTXT(style)->inode->type) {
case XSLT_FUNC_APPLYTEMPLATES:
xsltApplyTemplatesComp(style, node);
break;
case XSLT_FUNC_WITHPARAM:
xsltWithParamComp(style, node);
break;
case XSLT_FUNC_VALUEOF:
xsltValueOfComp(style, node);
break;
case XSLT_FUNC_COPY:
xsltCopyComp(style, node);
break;
case XSLT_FUNC_COPYOF:
xsltCopyOfComp(style, node);
break;
case XSLT_FUNC_IF:
xsltIfComp(style, node);
break;
case XSLT_FUNC_CHOOSE:
xsltChooseComp(style, node);
break;
case XSLT_FUNC_WHEN:
xsltWhenComp(style, node);
break;
case XSLT_FUNC_OTHERWISE:
/* NOP yet */
return;
case XSLT_FUNC_FOREACH:
xsltForEachComp(style, node);
break;
case XSLT_FUNC_APPLYIMPORTS:
xsltApplyImportsComp(style, node);
break;
case XSLT_FUNC_ATTRIBUTE:
xsltAttributeComp(style, node);
break;
case XSLT_FUNC_ELEMENT:
xsltElementComp(style, node);
break;
case XSLT_FUNC_SORT:
xsltSortComp(style, node);
break;
case XSLT_FUNC_COMMENT:
xsltCommentComp(style, node);
break;
case XSLT_FUNC_NUMBER:
xsltNumberComp(style, node);
break;
case XSLT_FUNC_PI:
xsltProcessingInstructionComp(style, node);
break;
case XSLT_FUNC_CALLTEMPLATE:
xsltCallTemplateComp(style, node);
break;
case XSLT_FUNC_PARAM:
xsltParamComp(style, node);
break;
case XSLT_FUNC_VARIABLE:
xsltVariableComp(style, node);
break;
case XSLT_FUNC_FALLBACK:
/* NOP yet */
return;
case XSLT_FUNC_DOCUMENT:
/* The extra one */
node->psvi = (void *) xsltDocumentComp(style, node,
(xsltTransformFunction) xsltDocumentElem);
break;
case XSLT_FUNC_MESSAGE:
/* NOP yet */
return;
default:
/*
* NOTE that xsl:text, xsl:template, xsl:stylesheet,
* xsl:transform, xsl:import, xsl:include are not expected
* to be handed over to this function.
*/
xsltTransformError(NULL, style, node,
"Internal error: (xsltStylePreCompute) cannot handle "
"the XSLT element '%s'.\n", node->name);
style->errors++;
return;
}
} else {
/*
* Fallback to string comparison.
*/
if (IS_XSLT_NAME(node, "apply-templates")) {
xsltApplyTemplatesComp(style, node);
} else if (IS_XSLT_NAME(node, "with-param")) {
xsltWithParamComp(style, node);
} else if (IS_XSLT_NAME(node, "value-of")) {
xsltValueOfComp(style, node);
} else if (IS_XSLT_NAME(node, "copy")) {
xsltCopyComp(style, node);
} else if (IS_XSLT_NAME(node, "copy-of")) {
xsltCopyOfComp(style, node);
} else if (IS_XSLT_NAME(node, "if")) {
xsltIfComp(style, node);
} else if (IS_XSLT_NAME(node, "choose")) {
xsltChooseComp(style, node);
} else if (IS_XSLT_NAME(node, "when")) {
xsltWhenComp(style, node);
} else if (IS_XSLT_NAME(node, "otherwise")) {
/* NOP yet */
return;
} else if (IS_XSLT_NAME(node, "for-each")) {
xsltForEachComp(style, node);
} else if (IS_XSLT_NAME(node, "apply-imports")) {
xsltApplyImportsComp(style, node);
} else if (IS_XSLT_NAME(node, "attribute")) {
xsltAttributeComp(style, node);
} else if (IS_XSLT_NAME(node, "element")) {
xsltElementComp(style, node);
} else if (IS_XSLT_NAME(node, "sort")) {
xsltSortComp(style, node);
} else if (IS_XSLT_NAME(node, "comment")) {
xsltCommentComp(style, node);
} else if (IS_XSLT_NAME(node, "number")) {
xsltNumberComp(style, node);
} else if (IS_XSLT_NAME(node, "processing-instruction")) {
xsltProcessingInstructionComp(style, node);
} else if (IS_XSLT_NAME(node, "call-template")) {
xsltCallTemplateComp(style, node);
} else if (IS_XSLT_NAME(node, "param")) {
xsltParamComp(style, node);
} else if (IS_XSLT_NAME(node, "variable")) {
xsltVariableComp(style, node);
} else if (IS_XSLT_NAME(node, "fallback")) {
/* NOP yet */
return;
} else if (IS_XSLT_NAME(node, "document")) {
/* The extra one */
node->psvi = (void *) xsltDocumentComp(style, node,
(xsltTransformFunction) xsltDocumentElem);
} else if (IS_XSLT_NAME(node, "output")) {
/* Top-level */
return;
} else if (IS_XSLT_NAME(node, "preserve-space")) {
/* Top-level */
return;
} else if (IS_XSLT_NAME(node, "strip-space")) {
/* Top-level */
return;
} else if (IS_XSLT_NAME(node, "key")) {
/* Top-level */
return;
} else if (IS_XSLT_NAME(node, "message")) {
return;
} else if (IS_XSLT_NAME(node, "attribute-set")) {
/* Top-level */
return;
} else if (IS_XSLT_NAME(node, "namespace-alias")) {
/* Top-level */
return;
} else if (IS_XSLT_NAME(node, "decimal-format")) {
/* Top-level */
return;
} else if (IS_XSLT_NAME(node, "include")) {
/* Top-level */
} else {
/*
* NOTE that xsl:text, xsl:template, xsl:stylesheet,
* xsl:transform, xsl:import, xsl:include are not expected
* to be handed over to this function.
*/
xsltTransformError(NULL, style, node,
"Internal error: (xsltStylePreCompute) cannot handle "
"the XSLT element '%s'.\n", node->name);
style->errors++;
return;
}
}
/*
* Assign the current list of in-scope namespaces to the
* item. This is needed for XPath expressions.
*/
if (node->psvi != NULL) {
((xsltStylePreCompPtr) node->psvi)->inScopeNs =
XSLT_CCTXT(style)->inode->inScopeNs;
}
}
#else
/**
* xsltStylePreCompute:
* @style: the XSLT stylesheet
@@ -1895,10 +2051,14 @@ xsltStylePreCompute(xsltStylesheetPtr style, xmlNodePtr inst) {
* URGENT TODO: Normally inst->psvi Should never be reserved here,
* BUT: since if we include the same stylesheet from
* multiple imports, then the stylesheet will be parsed
* again. We simply must not try to compute the stylesheet again.
* again. We simply must not try to compute the stylesheet again.
* TODO: Get to the point where we don't need to query the
* namespace- and local-name of the node, but can evaluate this
* using cctxt->style->inode->category;
*/
if (inst->psvi != NULL)
return;
if (inst->psvi != NULL)
return;
if (IS_XSLT_ELEM(inst)) {
xsltStylePreCompPtr cur;
@@ -1965,7 +2125,7 @@ xsltStylePreCompute(xsltStylesheetPtr style, xmlNodePtr inst) {
} else if (IS_XSLT_NAME(inst, "call-template")) {
xsltCheckInstructionElement(style, inst);
xsltCallTemplateComp(style, inst);
} else if (IS_XSLT_NAME(inst, "param")) {
} else if (IS_XSLT_NAME(inst, "param")) {
if (xsltCheckTopLevelElement(style, inst, 0) == 0)
xsltCheckInstructionElement(style, inst);
xsltParamComp(style, inst);
@@ -2034,18 +2194,7 @@ xsltStylePreCompute(xsltStylesheetPtr style, xmlNodePtr inst) {
if (style != NULL) style->warnings++;
}
cur = (xsltStylePreCompPtr) inst->psvi;
#ifdef XSLT_REFACTORED
/*
* Assign the current list of in-scope namespaces to the
* item. This is needed for XPath expressions.
*/
if (cur != NULL) {
cur->inScopeNS = XSLT_CCTXT(style)->inode->inScopeNS;
}
#else
/*
* A ns-list is build for every XSLT item in the
* node-tree. This is needed for XPath expressions.
@@ -2060,7 +2209,6 @@ xsltStylePreCompute(xsltStylesheetPtr style, xmlNodePtr inst) {
}
cur->nsNr = i;
}
#endif
} else {
inst->psvi =
(void *) xsltPreComputeExtModuleElement(style, inst);
@@ -2073,3 +2221,4 @@ xsltStylePreCompute(xsltStylesheetPtr style, xmlNodePtr inst) {
inst->psvi = (void *) xsltExtMarker;
}
}
#endif /* XSLT_REFACTORED */

View File

@@ -1624,7 +1624,11 @@ xsltApplyOneTemplateInt(xsltTransformContextPtr ctxt, xmlNodePtr node,
xslHandleDebugger(cur, node, templ, ctxt);
#endif
#ifdef XSLT_REFACTORED
if (IS_XSLT_ELEM_FAST(cur)) {
#else
if (IS_XSLT_ELEM(cur)) {
#endif
/*
* This is an XSLT node
*/
@@ -2949,9 +2953,9 @@ xsltCopyOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
oldNamespaces = ctxt->xpathCtxt->namespaces;
ctxt->xpathCtxt->node = node;
#ifdef XSLT_REFACTORED
if (comp->inScopeNS != NULL) {
ctxt->xpathCtxt->namespaces = comp->inScopeNS->list;
ctxt->xpathCtxt->nsNr = comp->inScopeNS->number;
if (comp->inScopeNs != NULL) {
ctxt->xpathCtxt->namespaces = comp->inScopeNs->list;
ctxt->xpathCtxt->nsNr = comp->inScopeNs->number;
} else {
ctxt->xpathCtxt->namespaces = NULL;
ctxt->xpathCtxt->nsNr = 0;
@@ -3065,9 +3069,9 @@ xsltValueOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
oldNamespaces = ctxt->xpathCtxt->namespaces;
ctxt->xpathCtxt->node = node;
#ifdef XSLT_REFACTORED
if (comp->inScopeNS != NULL) {
ctxt->xpathCtxt->namespaces = comp->inScopeNS->list;
ctxt->xpathCtxt->nsNr = comp->inScopeNS->number;
if (comp->inScopeNs != NULL) {
ctxt->xpathCtxt->namespaces = comp->inScopeNs->list;
ctxt->xpathCtxt->nsNr = comp->inScopeNs->number;
} else {
ctxt->xpathCtxt->namespaces = NULL;
ctxt->xpathCtxt->nsNr = 0;
@@ -3232,7 +3236,11 @@ xsltCallTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
* structure. Avoid to "search" for params dynamically
* in the XML tree every time.
*/
#ifdef XSLT_REFACTORED
if (IS_XSLT_ELEM_FAST(cur)) {
#else
if (IS_XSLT_ELEM(cur)) {
#endif
if (IS_XSLT_NAME(cur, "with-param")) {
param = xsltParseStylesheetCallerParam(ctxt, cur);
if (param != NULL) {
@@ -3345,9 +3353,9 @@ xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node,
ctxt->xpathCtxt->node = node;
#ifdef XSLT_REFACTORED
if (comp->inScopeNS != NULL) {
ctxt->xpathCtxt->namespaces = comp->inScopeNS->list;
ctxt->xpathCtxt->nsNr = comp->inScopeNS->number;
if (comp->inScopeNs != NULL) {
ctxt->xpathCtxt->namespaces = comp->inScopeNs->list;
ctxt->xpathCtxt->nsNr = comp->inScopeNs->number;
} else {
ctxt->xpathCtxt->namespaces = NULL;
ctxt->xpathCtxt->nsNr = 0;
@@ -3500,7 +3508,11 @@ xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node,
#endif
#endif
if (ctxt->state == XSLT_STATE_STOPPED) break;
#ifdef XSLT_REFACTORED
if (IS_XSLT_ELEM_FAST(cur)) {
#else
if (IS_XSLT_ELEM(cur)) {
#endif
if (IS_XSLT_NAME(cur, "with-param")) {
param = xsltParseStylesheetCallerParam(ctxt, cur);
if (param != NULL) {
@@ -3620,13 +3632,23 @@ xsltChoose(xsltTransformContextPtr ctxt, xmlNodePtr node,
"xsl:choose: empty content not allowed\n");
goto error;
}
if (((!IS_XSLT_ELEM(replacement)) || (!IS_XSLT_NAME(replacement, "when")))
#ifdef XSLT_REFACTORED
if (((!IS_XSLT_ELEM_FAST(replacement)) ||
#else
if (((!IS_XSLT_ELEM(replacement)) ||
#endif
(!IS_XSLT_NAME(replacement, "when")))
&& (!xmlIsBlankNode(replacement))) {
xsltTransformError(ctxt, NULL, inst,
"xsl:choose: xsl:when expected first\n");
goto error;
}
while ((IS_XSLT_ELEM(replacement) && (IS_XSLT_NAME(replacement, "when")))
#ifdef XSLT_REFACTORED
while ((IS_XSLT_ELEM_FAST(replacement) &&
#else
while ((IS_XSLT_ELEM(replacement) &&
#endif
(IS_XSLT_NAME(replacement, "when")))
|| xmlIsBlankNode(replacement)) {
#ifdef XSLT_REFACTORED
xsltStyleItemWhenPtr wcomp =
@@ -3669,9 +3691,9 @@ xsltChoose(xsltTransformContextPtr ctxt, xmlNodePtr node,
oldNamespaces = ctxt->xpathCtxt->namespaces;
ctxt->xpathCtxt->node = node;
#ifdef XSLT_REFACTORED
if (wcomp->inScopeNS != NULL) {
ctxt->xpathCtxt->namespaces = wcomp->inScopeNS->list;
ctxt->xpathCtxt->nsNr = wcomp->inScopeNS->number;
if (wcomp->inScopeNs != NULL) {
ctxt->xpathCtxt->namespaces = wcomp->inScopeNs->list;
ctxt->xpathCtxt->nsNr = wcomp->inScopeNs->number;
} else {
ctxt->xpathCtxt->namespaces = NULL;
ctxt->xpathCtxt->nsNr = 0;
@@ -3715,7 +3737,12 @@ xsltChoose(xsltTransformContextPtr ctxt, xmlNodePtr node,
res = NULL;
replacement = replacement->next;
}
if (IS_XSLT_ELEM(replacement) && (IS_XSLT_NAME(replacement, "otherwise"))) {
#ifdef XSLT_REFACTORED
if (IS_XSLT_ELEM_FAST(replacement) &&
#else
if (IS_XSLT_ELEM(replacement) &&
#endif
(IS_XSLT_NAME(replacement, "otherwise"))) {
#ifdef WITH_DEBUGGER
if (xslDebugStatus != XSLT_DEBUG_NONE)
#ifdef XSLT_REFACTORED
@@ -3791,9 +3818,9 @@ xsltIf(xsltTransformContextPtr ctxt, xmlNodePtr node,
oldNamespaces = ctxt->xpathCtxt->namespaces;
ctxt->xpathCtxt->node = node;
#ifdef XSLT_REFACTORED
if (comp->inScopeNS != NULL) {
ctxt->xpathCtxt->namespaces = comp->inScopeNS->list;
ctxt->xpathCtxt->nsNr = comp->inScopeNS->number;
if (comp->inScopeNs != NULL) {
ctxt->xpathCtxt->namespaces = comp->inScopeNs->list;
ctxt->xpathCtxt->nsNr = comp->inScopeNs->number;
} else {
ctxt->xpathCtxt->namespaces = NULL;
ctxt->xpathCtxt->nsNr = 0;
@@ -3886,9 +3913,9 @@ xsltForEach(xsltTransformContextPtr ctxt, xmlNodePtr node,
oldNamespaces = ctxt->xpathCtxt->namespaces;
ctxt->xpathCtxt->node = node;
#ifdef XSLT_REFACTORED
if (comp->inScopeNS != NULL) {
ctxt->xpathCtxt->namespaces = comp->inScopeNS->list;
ctxt->xpathCtxt->nsNr = comp->inScopeNS->number;
if (comp->inScopeNs != NULL) {
ctxt->xpathCtxt->namespaces = comp->inScopeNs->list;
ctxt->xpathCtxt->nsNr = comp->inScopeNs->number;
} else {
ctxt->xpathCtxt->namespaces = NULL;
ctxt->xpathCtxt->nsNr = 0;
@@ -3933,7 +3960,12 @@ xsltForEach(xsltTransformContextPtr ctxt, xmlNodePtr node,
* handle and skip the xsl:sort
*/
replacement = inst->children;
while (IS_XSLT_ELEM(replacement) && (IS_XSLT_NAME(replacement, "sort"))) {
#ifdef XSLT_REFACTORED
while (IS_XSLT_ELEM_FAST(replacement) &&
#else
while (IS_XSLT_ELEM(replacement) &&
#endif
(IS_XSLT_NAME(replacement, "sort"))) {
if (nbsorts >= XSLT_MAX_SORT) {
xsltGenericError(xsltGenericErrorContext,
"xsl:for-each: too many sorts\n");

View File

@@ -467,9 +467,9 @@ xsltEvalVariable(xsltTransformContextPtr ctxt, xsltStackElemPtr elem,
if (precomp != NULL) {
ctxt->inst = precomp->inst;
#ifdef XSLT_REFACTORED
if (precomp->inScopeNS != NULL) {
ctxt->xpathCtxt->namespaces = precomp->inScopeNS->list;
ctxt->xpathCtxt->nsNr = precomp->inScopeNS->number;
if (precomp->inScopeNs != NULL) {
ctxt->xpathCtxt->namespaces = precomp->inScopeNs->list;
ctxt->xpathCtxt->nsNr = precomp->inScopeNs->number;
} else {
ctxt->xpathCtxt->namespaces = NULL;
ctxt->xpathCtxt->nsNr = 0;
@@ -628,9 +628,9 @@ xsltEvalGlobalVariable(xsltStackElemPtr elem, xsltTransformContextPtr ctxt)
if (precomp != NULL) {
ctxt->inst = precomp->inst;
#ifdef XSLT_REFACTORED
if (precomp->inScopeNS != NULL) {
ctxt->xpathCtxt->namespaces = precomp->inScopeNS->list;
ctxt->xpathCtxt->nsNr = precomp->inScopeNS->number;
if (precomp->inScopeNs != NULL) {
ctxt->xpathCtxt->namespaces = precomp->inScopeNs->list;
ctxt->xpathCtxt->nsNr = precomp->inScopeNs->number;
} else {
ctxt->xpathCtxt->namespaces = NULL;
ctxt->xpathCtxt->nsNr = 0;
@@ -1389,10 +1389,12 @@ xsltVariableLookup(xsltTransformContextPtr ctxt, const xmlChar *name,
/**
* xsltParseStylesheetCallerParam:
* @ctxt: the XSLT transformation context
* @cur: the "param" element
* @cur: the "xsl:with-param" element
*
* parse an XSLT transformation param declaration, compute
* its value but doesn't record it.
* NOTE that this is also called with an *xsl:param* element
* from exsltFuncFunctionFunction().
*
* Returns the new xsltStackElemPtr or NULL
*/
@@ -1417,19 +1419,19 @@ xsltParseStylesheetCallerParam(xsltTransformContextPtr ctxt, xmlNodePtr cur)
#endif
if (comp == NULL) {
xsltTransformError(ctxt, NULL, cur,
"xsl:param : compilation error\n");
"xsl:with-param : compilation error\n");
return(NULL);
}
if (comp->name == NULL) {
xsltTransformError(ctxt, NULL, cur,
"xsl:param : missing name attribute\n");
"xsl:with-param : missing name attribute\n");
return(NULL);
}
#ifdef WITH_XSLT_DEBUG_VARIABLE
XSLT_TRACE(ctxt,XSLT_TRACE_VARIABLES,xsltGenericDebug(xsltGenericDebugContext,
"Handling param %s\n", comp->name));
"Handling xsl:with-param %s\n", comp->name));
#endif
if (comp->select == NULL) {
@@ -1467,11 +1469,15 @@ xsltParseGlobalVariable(xsltStylesheetPtr style, xmlNodePtr cur)
if ((cur == NULL) || (style == NULL))
return;
xsltStylePreCompute(style, cur);
#ifdef XSLT_REFACTORED
/*
* Note that xsltStylePreCompute() will be called from
* xslt.c only.
*/
comp = (xsltStyleItemVariablePtr) cur->psvi;
#else
xsltStylePreCompute(style, cur);
comp = (xsltStylePreCompPtr) cur->psvi;
#endif
if (comp == NULL) {
@@ -1486,8 +1492,15 @@ xsltParseGlobalVariable(xsltStylesheetPtr style, xmlNodePtr cur)
return;
}
/*
* Parse the content (a sequence constructor) of xsl:variable.
*/
if (cur->children != NULL) {
#ifdef XSLT_REFACTORED
xsltParseSequenceConstructor(XSLT_CCTXT(style), cur->children);
#else
xsltParseTemplateContent(style, cur);
#endif
}
#ifdef WITH_XSLT_DEBUG_VARIABLE
xsltGenericDebug(xsltGenericDebugContext,
@@ -1518,11 +1531,15 @@ xsltParseGlobalParam(xsltStylesheetPtr style, xmlNodePtr cur) {
if ((cur == NULL) || (style == NULL))
return;
xsltStylePreCompute(style, cur);
#ifdef XSLT_REFACTORED
/*
* Note that xsltStylePreCompute() will be called from
* xslt.c only.
*/
comp = (xsltStyleItemParamPtr) cur->psvi;
#else
xsltStylePreCompute(style, cur);
comp = (xsltStylePreCompPtr) cur->psvi;
#endif
if (comp == NULL) {
@@ -1537,8 +1554,15 @@ xsltParseGlobalParam(xsltStylesheetPtr style, xmlNodePtr cur) {
return;
}
/*
* Parse the content (a sequence constructor) of xsl:param.
*/
if (cur->children != NULL) {
#ifdef XSLT_REFACTORED
xsltParseSequenceConstructor(XSLT_CCTXT(style), cur->children);
#else
xsltParseTemplateContent(style, cur);
#endif
}
#ifdef WITH_XSLT_DEBUG_VARIABLE

File diff suppressed because it is too large Load Diff

View File

@@ -26,7 +26,6 @@
extern "C" {
#endif
/**
* XSLT_REFACTORED:
*
@@ -35,6 +34,54 @@ extern "C" {
*/
/* #define XSLT_REFACTORED */
#ifdef XSLT_REFACTORED
extern const xmlChar *xsltConstNamespaceNameXSLT;
/**
* IS_XSLT_ELEM_FAST:
*
* Checks that the element pertains to XSLT namespace.
*/
#define IS_XSLT_ELEM_FAST(e) \
(((e) != NULL) && ((e)->type == XML_ELEMENT_NODE) && \
((e)->ns != NULL) && ((e)->ns->href == xsltConstNamespaceNameXSLT))
#define IS_IN_XSLT_NS(e) \
(((e)->ns != NULL) && ((e)->ns->href == xsltConstNamespaceNameXSLT))
#define XSLT_HAS_INTERNAL_NSMAP(s) \
(((s) != NULL) && ((s)->principal) && \
((s)->principal->principalData) && \
((s)->principal->principalData->nsMap))
#define XSLT_GET_INTERNAL_NSMAP(s) ((s)->principal->principalData->nsMap)
/**
* XSLT_REFACTORED_MANDATORY_VERSION:
*
* TODO: Currently disabled to surpress regression test failures, since
* the old behaviour was that a missing version attribute
* produced a only a warning and not an error, which was incerrect.
* So the regression tests need to be fixed if this is enabled.
*/
/* #define XSLT_REFACTORED_MANDATORY_VERSION */
/**
* xsltPointerList:
*
* Pointer-list for various purposes.
*/
typedef struct _xsltPointerList xsltPointerList;
typedef xsltPointerList *xsltPointerListPtr;
struct _xsltPointerList {
void **items;
int number;
int size;
};
#endif
/**
* XSLT_REFACTORED_PARSING:
*
@@ -110,8 +157,8 @@ struct _xsltTemplate {
struct _xsltStylesheet *style;/* the containing stylesheet */
xmlChar *match; /* the matching string */
float priority; /* as given from the stylesheet, not computed */
xmlChar *name; /* the local part of the name QName */
xmlChar *nameURI; /* the URI part of the name QName */
const xmlChar *name; /* the local part of the name QName */
const xmlChar *nameURI; /* the URI part of the name QName */
const xmlChar *mode;/* the local part of the mode QName */
const xmlChar *modeURI;/* the URI part of the mode QName */
xmlNodePtr content; /* the template replacement value */
@@ -236,7 +283,13 @@ typedef enum {
XSLT_FUNC_VARIABLE,
XSLT_FUNC_WHEN,
XSLT_FUNC_EXTENSION,
#ifdef XSLT_REFACTORED
XSLT_FUNC_OTHERWISE,
XSLT_FUNC_FALLBACK,
XSLT_FUNC_MESSAGE,
XSLT_FUNC_INCLUDE,
XSLT_FUNC_ATTRSET
#endif
} xsltStyleType;
/**
@@ -258,7 +311,7 @@ typedef void (*xsltElemPreCompDeallocator) (xsltElemPreCompPtr comp);
struct _xsltElemPreComp {
xsltElemPreCompPtr next; /* next item in the global chained
list hold by xsltStylesheet. */
xsltStyleType type; /* type of the element */
xsltStyleType type; /* type of the element */
xsltTransformFunction func; /* handling function */
xmlNodePtr inst; /* the node in the stylesheet's tree
corresponding to this item */
@@ -270,51 +323,44 @@ struct _xsltElemPreComp {
/**
* xsltStylePreComp:
*
* The abstract basic structure for items of the
* AST of the XSLT processor.
* The AST includes:
* The abstract basic structure for items of the XSLT processor.
* This includes:
* 1) compiled forms of XSLT instructions (xsl:if, xsl:attribute, etc.)
* 2) compiled forms of literal result elements
* 3) compiled forms of extension elements
*/
typedef struct _xsltStylePreComp xsltStylePreComp;
typedef xsltStylePreComp *xsltStylePreCompPtr;
/*************************
* Refactored structures *
*************************/
#ifdef XSLT_REFACTORED
typedef struct _xsltNsList xsltNsList;
/*
* Some pointer-list utility functions.
*/
XSLTPUBFUN xsltPointerListPtr XSLTCALL
xsltPointerListCreate (int initialSize);
XSLTPUBFUN void XSLTCALL
xsltPointerListFree (xsltPointerListPtr list);
XSLTPUBFUN void XSLTCALL
xsltPointerListClear (xsltPointerListPtr list);
XSLTPUBFUN int XSLTCALL
xsltPointerListAddSize (xsltPointerListPtr list,
void *item,
int initialSize);
/************************************************************************
* *
* Refactored structures *
* *
************************************************************************/
typedef struct _xsltNsList xsltNsList;
typedef xsltNsList *xsltNsListPtr;
struct _xsltNsList {
xmlNsPtr *list;
int number;
};
#if 0
/*
* TODO: xsltBasicItem is not used yet; maybe never will be used, since
* xsltElemPreCompPtr is acting as the base type for the compiled
* items of a stylesheet. It seems not practical to try to change
* this type to xsltBasicItemPtr, since xsltElemPreCompPtr is
* used already used too massively (e.g. xsltStylesheet->preComps) and
* for extension functions.
*/
/**
* xsltBasicItem:
*
* The basic structure for all items of the AST of the XSLT processor.
*/
typedef struct _xsltBasicItem xsltBasicItem;
typedef xsltBasicItem *xsltBasicItemPtr;
struct _xsltBasicItem {
xsltBasicASTItemPtr next;
xsltStyleType type;
};
#endif
/**
* XSLT_ITEM_COMPATIBILITY_FIELDS:
*
@@ -346,7 +392,7 @@ struct _xsltBasicItem {
*
* The in-scope namespaces.
*/
#define XSLT_ITEM_NSINSCOPE_FIELDS xsltNsListPtr inScopeNS;
#define XSLT_ITEM_NSINSCOPE_FIELDS xsltNsListPtr inScopeNs;
/**
* XSLT_ITEM_COMMON_FIELDS:
@@ -378,8 +424,8 @@ struct _xsltStylePreComp {
xsltTransformFunction func; /* handling function */
xmlNodePtr inst; /* the node in the stylesheet's tree
corresponding to this item. */
/* Currenlty to navigational fields. */
xsltNsListPtr inScopeNS;
/* Currently no navigational fields. */
xsltNsListPtr inScopeNs;
};
/**
@@ -868,14 +914,72 @@ struct _xsltStyleItemOtherwise {
XSLT_ITEM_COMMON_FIELDS
};
typedef struct _xsltStyleItemInclude xsltStyleItemInclude;
typedef xsltStyleItemInclude *xsltStyleItemIncludePtr;
struct _xsltStyleItemInclude {
XSLT_ITEM_COMMON_FIELDS
xsltDocumentPtr include;
};
/************************************************************************
* *
* Extension elements *
* *
************************************************************************/
/*
* xsltStyleItemExtElement:
*
* Reflects extension elements.
*
* NOTE: Due to the fact that the structure xsltElemPreComp is most
* probably already heavily in use out there by users, so we cannot
* easily change it, we'll create an intermediate structure which will
* hold an xsltElemPreCompPtr.
* BIG NOTE: The only problem I see here is that the user processes the
* content of the stylesheet tree, possibly he'll lookup the node->psvi
* fields in order to find subsequent extension functions.
* In this case, the user's code will break, since the node->psvi
* field will hold now the xsltStyleItemExtElementPtr and not
* the xsltElemPreCompPtr.
* However the place where the structure is anchored in the node-tree,
* namely node->psvi, has beed already once been moved from node->_private
* to node->psvi, so we have a precedent here, which, I think, should allow
* us to change such semantics without headaches.
*/
typedef struct _xsltStyleItemExtElement xsltStyleItemExtElement;
typedef xsltStyleItemExtElement *xsltStyleItemExtElementPtr;
struct _xsltStyleItemExtElement {
XSLT_ITEM_COMMON_FIELDS
xsltElemPreCompPtr item;
};
/************************************************************************
* *
* Literal result elements *
* *
************************************************************************/
/*
* Literal result elements.
* TODO: Not used yet.
*/
typedef struct _xsltStyleItemLRE xsltStyleItemLRE;
typedef xsltStyleItemLRE *xsltStyleItemLREPtr;
struct _xsltStyleItemLRE {
typedef struct _xsltStyleItemLRElement xsltStyleItemLRElement;
typedef xsltStyleItemLRElement *xsltStyleItemLRElementPtr;
struct _xsltStyleItemLRElement {
XSLT_ITEM_COMMON_FIELDS
xsltPointerListPtr exclResultNs;
};
typedef struct _xsltNsMap xsltNsMap;
typedef xsltNsMap *xsltNsMapPtr;
struct _xsltNsMap {
xsltNsMapPtr next; /* next in the list */
xmlDocPtr doc;
xmlNodePtr elem; /* the element holding the ns-decl */
xmlNsPtr ns; /* the xmlNs structure holding the XML namespace name */
const xmlChar *origNsName; /* the original XML namespace name */
const xmlChar *newNsName; /* the mapped XML namespace name */
};
/************************************************************************
@@ -884,6 +988,13 @@ struct _xsltStyleItemLRE {
* *
************************************************************************/
typedef struct _xsltPrincipalStylesheetData xsltPrincipalStylesheetData;
typedef xsltPrincipalStylesheetData *xsltPrincipalStylesheetDataPtr;
#define XSLT_ELEMENT_CATEGORY_XSLT 0
#define XSLT_ELEMENT_CATEGORY_EXTENSION 1
#define XSLT_ELEMENT_CATEGORY_LR 2
/**
* xsltCompilerNodeInfo:
*
@@ -896,29 +1007,68 @@ struct _xsltCompilerNodeInfo {
xsltCompilerNodeInfoPtr prev;
xmlNodePtr node;
int depth;
xsltNsListPtr inScopeNS; /* The in-scope namespaces for the current
position in the node-tree */
xsltTemplatePtr templ; /* The owning template */
int category; /* XSLT element, LR-element or
extension element */
xsltStyleType type;
xsltElemPreCompPtr item; /* The compiled information */
xsltNsListPtr inScopeNs; /* The in-scope namespaces for the current
position in the node-tree */
xsltPointerListPtr exclResultNs; /* The current excluded
result namespaces */
xsltPointerListPtr extElemNs;
int preserveWhitespace;
int stripWhitespace;
int isRoot; /* whether this is the stylesheet's root node */
int forwardsCompat; /* whether forwards-compatible mode is enabled */
/* whether the content of an extension element was processed */
int extContentHandled;
/* the type of the current child */
xsltStyleType curChildType;
};
#define XSLT_CCTXT(style) ((xsltCompilerCtxtPtr) style->compCtxt)
#define XSLT_CCTXT(style) ((xsltCompilerCtxtPtr) style->compCtxt)
typedef enum {
XSLT_ERROR_SEVERITY_ERROR = 0,
XSLT_ERROR_SEVERITY_WARNING
} xsltErrorSeverityType;
typedef struct _xsltCompilerCtxt xsltCompilerCtxt;
typedef xsltCompilerCtxt *xsltCompilerCtxtPtr;
struct _xsltCompilerCtxt {
void *errorCtxt; /* user specific error context */
void *errorCtxt; /* user specific error context */
/*
* used for error/warning reports; e.g. XSLT_ERROR_SEVERITY_WARNING */
xsltErrorSeverityType errSeverity;
int warnings; /* TODO: number of warnings found at
compilation */
int errors; /* TODO: number of errors found at
compilation */
xsltStylesheetPtr sheet;
xmlDictPtr dict;
xsltStylesheetPtr style;
int simplified; /* whether this is a simplified stylesheet */
/* TODO: structured/unstructured error contexts. */
int depth; /* TODO: current depth in the stylesheets node-tree */
int depth; /* Current depth of processing */
xsltCompilerNodeInfoPtr inode;
xsltCompilerNodeInfoPtr inodeList;
xsltCompilerNodeInfoPtr inodeLast;
xsltPointerListPtr tmpList; /* Used for various purposes */
/*
* The XSLT version as specified by the stylesheet's root element.
*/
int isInclude;
int hasForwardsCompat; /* whether forwards-compatible mode was used
in a parsing episode */
int maxNodeInfos; /* just for the interest */
/*
* In order to keep the old behaviour, applying strict rules of
* the spec can be turned off. This has effect only on special
* mechanisms like whitespace-stripping in the stylesheet.
*/
int strict;
xsltPrincipalStylesheetDataPtr psData;
};
#else /* XSLT_REFACTORED */
@@ -1002,10 +1152,39 @@ struct _xsltStackElem {
xmlXPathObjectPtr value; /* The value if computed */
};
#ifdef XSLT_REFACTORED
struct _xsltPrincipalStylesheetData {
/*
* Namespace dictionary for ns-prefixes and ns-names:
* TODO: Shared between stylesheets, and XPath mechanisms.
* Not used yet.
*/
xmlDictPtr namespaceDict;
/*
* Global list of in-scope namespaces.
*/
void *inScopeNamespaces;
/*
* Global list of information for [xsl:]excluded-result-prefixes.
*/
void *exclResultNamespaces;
/*
* Global list of information for [xsl:]extension-element-prefixes.
*/
void *extElemNamespaces;
/*
* Namespace name map to get rid of string comparison of namespace names.
*/
xsltNsMapPtr nsMap;
};
#endif
/*
* TODO: We need a field to anchor an stylesheet compilation context, since,
* due to historical reasons, various compile-time function take only the
* stylesheet as argument and not a compilation context.
* Note that we added a @compCtxt field to anchor an stylesheet compilation
* context, since, due to historical reasons, various compile-time function
* take only the stylesheet as argument and not a compilation context.
*/
struct _xsltStylesheet {
/*
@@ -1059,13 +1238,22 @@ struct _xsltStylesheet {
/*
* Namespaces.
*/
xmlHashTablePtr nsHash; /* the set of namespaces in use */
void *nsDefs; /* the namespaces defined */
xmlHashTablePtr nsHash; /* the set of namespaces in use:
ATTENTION: This is used for
execution of XPath expressions; unfortunately
it restricts the stylesheet to have distinct
prefixes.
TODO: We need to get rid of this.
*/
void *nsDefs; /* ATTENTION TODO: This is currently used to store
xsltExtDefPtr (in extensions.c) and
*not* xmlNsPtr.
*/
/*
* Key definitions.
*/
void *keys; /* key definitions */
void *keys; /* key definitions */
/*
* Output related stuff.
@@ -1112,7 +1300,7 @@ struct _xsltStylesheet {
xsltDocumentPtr includes; /* points to last nested include */
/*
* dictionnary: shared between stylesheet, context and documents.
* dictionary: shared between stylesheet, context and documents.
*/
xmlDictPtr dict;
/*
@@ -1135,16 +1323,18 @@ struct _xsltStylesheet {
* Literal Result Element as Stylesheet c.f. section 2.3
*/
int literal_result;
/*
* The principal stylesheet
*/
xsltStylesheetPtr principal;
#ifdef XSLT_REFACTORED
/*
* Compilation context used during compile-time.
*/
void * compCtxt;
/*
* Namespace lists.
*/
void *inScopeNamespaces;
#endif
xsltCompilerCtxtPtr compCtxt; /* TODO: Change this to (void *). */
xsltPrincipalStylesheetDataPtr principalData;
#endif
};
/*
@@ -1323,13 +1513,13 @@ XSLTPUBFUN xsltStylesheetPtr XSLTCALL
XSLTPUBFUN xsltStylesheetPtr XSLTCALL
xsltParseStylesheetFile (const xmlChar* filename);
XSLTPUBFUN void XSLTCALL
xsltFreeStylesheet (xsltStylesheetPtr sheet);
xsltFreeStylesheet (xsltStylesheetPtr style);
XSLTPUBFUN int XSLTCALL
xsltIsBlank (xmlChar *str);
XSLTPUBFUN void XSLTCALL
xsltFreeStackElemList (xsltStackElemPtr elem);
XSLTPUBFUN xsltDecimalFormatPtr XSLTCALL
xsltDecimalFormatGetByName(xsltStylesheetPtr sheet,
xsltDecimalFormatGetByName(xsltStylesheetPtr style,
xmlChar *name);
XSLTPUBFUN xsltStylesheetPtr XSLTCALL
@@ -1389,17 +1579,6 @@ XSLTPUBFUN xmlChar * XSLTCALL
XSLTPUBFUN void XSLTCALL
xsltFreeAVTList (void *avt);
/************************************************************************
* *
* Compile-time functions for *internal* use only *
* *
************************************************************************/
#ifdef XSLT_REFACTORED
XSLTPUBFUN xsltNsListPtr XSLTCALL
xsltCompilerGetInScopeNSInfo(xsltCompilerCtxtPtr cctxt,
xmlNodePtr node);
#endif /* XSLT_REFACTORED */
/*
* Extra function for successful xsltCleanupGlobals / xsltInit sequence.
*/
@@ -1407,6 +1586,26 @@ XSLTPUBFUN xsltNsListPtr XSLTCALL
XSLTPUBFUN void XSLTCALL
xsltUninit (void);
/************************************************************************
* *
* Compile-time functions for *internal* use only *
* *
************************************************************************/
#ifdef XSLT_REFACTORED
XSLTPUBFUN void XSLTCALL
xsltParseSequenceConstructor(
xsltCompilerCtxtPtr cctxt,
xmlNodePtr start);
XSLTPUBFUN int XSLTCALL
xsltParseAnyXSLTElem (xsltCompilerCtxtPtr cctxt,
xmlNodePtr elem);
XSLTPUBFUN int XSLTCALL
xsltRestoreDocumentNamespaces(
xsltNsMapPtr ns,
xmlDocPtr doc);
#endif /* XSLT_REFACTORED */
#ifdef __cplusplus
}
#endif

View File

@@ -302,6 +302,49 @@ error:
#ifdef XSLT_REFACTORED
/**
* xsltPointerListAddSize:
* @list: the pointer list structure
* @item: the item to be stored
* @initialSize: the initial size of the list
*
* Adds an item to the list.
*
* Returns the position of the added item in the list or
* -1 in case of an error.
*/
int
xsltPointerListAddSize(xsltPointerListPtr list,
void *item,
int initialSize)
{
if (list->items == NULL) {
if (initialSize <= 0)
initialSize = 1;
list->items = (void **) xmlMalloc(
initialSize * sizeof(void *));
if (list->items == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsltPointerListAddSize: memory allocation failure.\n");
return(-1);
}
list->number = 0;
list->size = initialSize;
} else if (list->size <= list->number) {
list->size *= 2;
list->items = (void **) xmlRealloc(list->items,
list->size * sizeof(void *));
if (list->items == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsltPointerListAddSize: memory re-allocation failure.\n");
list->size = 0;
return(-1);
}
}
list->items[list->number++] = item;
return(0);
}
/**
* xsltPointerListCreate:
*
@@ -310,7 +353,7 @@ error:
* Returns a xsltPointerList structure or NULL in case of an error.
*/
xsltPointerListPtr
xsltPointerListCreate(void)
xsltPointerListCreate(int initialSize)
{
xsltPointerListPtr ret;
@@ -321,6 +364,10 @@ xsltPointerListCreate(void)
return (NULL);
}
memset(ret, 0, sizeof(xsltPointerList));
if (initialSize > 0) {
xsltPointerListAddSize(ret, NULL, initialSize);
ret->number = 0;
}
return (ret);
}
@@ -357,76 +404,6 @@ xsltPointerListClear(xsltPointerListPtr list)
list->size = 0;
}
/**
* xsltPointerListAdd:
*
* Adds an item to the list.
*
* Returns the position of the added item in the list or
* -1 in case of an error.
*/
int
xsltPointerListAdd(xsltPointerListPtr list, void *item)
{
if (list->items == NULL) {
list->items = (void **) xmlMalloc(
20 * sizeof(void *));
if (list->items == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsltPointerListAdd: memory allocation failure.\n");
return(-1);
}
list->number = 0;
list->size = 20;
} else if (list->size <= list->number) {
list->size *= 2;
list->items = (void **) xmlRealloc(list->items,
list->size * sizeof(void *));
if (list->items == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsltPointerListAdd: memory re-allocation failure.\n");
list->size = 0;
return(-1);
}
}
list->items[list->number++] = item;
return(0);
}
#if 0 /* TODO: Not used yet. Enable if ever needed. */
static int
xsltPointerListAddSize(xsltPointerListPtr list,
int initialSize,
void *item)
{
if (list->items == NULL) {
if (initialSize <= 0)
initialSize = 1;
list->items = (void **) xmlMalloc(
initialSize * sizeof(void *));
if (list->items == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsltPointerListAddSize: memory allocation failure.\n");
return(-1);
}
list->number = 0;
list->size = initialSize;
} else if (list->size <= list->number) {
list->size *= 2;
list->items = (void **) xmlRealloc(list->items,
list->size * sizeof(void *));
if (list->items == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsltPointerListAddSize: memory re-allocation failure.\n");
list->size = 0;
return(-1);
}
}
list->items[list->number++] = item;
return(0);
}
#endif
#endif /* XSLT_REFACTORED */
/************************************************************************
@@ -650,8 +627,16 @@ xsltPrintErrorContext(xsltTransformContextPtr ctxt,
if (ctxt != NULL)
type = "runtime error";
else if (style != NULL)
else if (style != NULL) {
#ifdef XSLT_REFACTORED
if (XSLT_CCTXT(style)->errSeverity == XSLT_ERROR_SEVERITY_WARNING)
type = "compilation warning";
else
type = "compilation error";
#else
type = "compilation error";
#endif
}
if ((file != NULL) && (line != 0) && (name != NULL))
error(errctx, "%s: file %s line %d element %s\n",
@@ -1008,9 +993,9 @@ xsltComputeSortResult(xsltTransformContextPtr ctxt, xmlNodePtr sort) {
ctxt->node = list->nodeTab[i];
ctxt->xpathCtxt->node = ctxt->node;
#ifdef XSLT_REFACTORED
if (comp->inScopeNS != NULL) {
ctxt->xpathCtxt->namespaces = comp->inScopeNS->list;
ctxt->xpathCtxt->nsNr = comp->inScopeNS->number;
if (comp->inScopeNs != NULL) {
ctxt->xpathCtxt->namespaces = comp->inScopeNs->list;
ctxt->xpathCtxt->nsNr = comp->inScopeNs->number;
} else {
ctxt->xpathCtxt->namespaces = NULL;
ctxt->xpathCtxt->nsNr = 0;

View File

@@ -298,31 +298,6 @@ XSLTPUBFUN int XSLTCALL
XSLTPUBFUN void XSLTCALL
xslDropCall (void);
#ifdef XSLT_REFACTORED
/**
* xsltPointerList:
*
* Pointer-list for various purposes.
*/
typedef struct _xsltPointerList xsltPointerList;
typedef xsltPointerList *xsltPointerListPtr;
struct _xsltPointerList {
void **items;
int number;
int size;
};
XSLTPUBFUN xsltPointerListPtr XSLTCALL
xsltPointerListCreate (void);
XSLTPUBFUN void XSLTCALL
xsltPointerListFree (xsltPointerListPtr list);
XSLTPUBFUN void XSLTCALL
xsltPointerListClear (xsltPointerListPtr list);
XSLTPUBFUN int XSLTCALL
xsltPointerListAdd (xsltPointerListPtr list,
void *item);
#endif /* XSLT_REFACTOR */
#ifdef __cplusplus
}
#endif