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:
11
ChangeLog
11
ChangeLog
@@ -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
|
||||
|
@@ -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",
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
*/
|
||||
|
@@ -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,
|
||||
|
@@ -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 */
|
||||
|
@@ -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");
|
||||
|
@@ -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
|
||||
|
4030
libxslt/xslt.c
4030
libxslt/xslt.c
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user