summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Veillard <veillard@src.gnome.org>2001-04-29 09:52:50 +0000
committerDaniel Veillard <veillard@src.gnome.org>2001-04-29 09:52:50 +0000
commiteef9a85837a010e65565b207fbc51790a549b2b4 (patch)
treec9190440f5b5085f738ddc1b0f8efe54aec57a58
parent765abf021e19a6b7f7b4d64868916f0cfb0019db (diff)
downloadlibxslt-eef9a85837a010e65565b207fbc51790a549b2b4.tar.gz
libxslt-eef9a85837a010e65565b207fbc51790a549b2b4.tar.bz2
libxslt-eef9a85837a010e65565b207fbc51790a549b2b4.zip
Big changes (but planned for a long time) small mem leak in docbook
still to fix: - preproc.[ch] templates.[ch] variables.[ch] xslt.c xsltInternals.h attributes.c extensions.[ch]: moved all stylesheet precomputation at stylesheet loading time (stylesheet transform should be thread safe now), improved params and variables evaluations (but optim is not complete yet). - TODO: updated Daniel
-rw-r--r--ChangeLog9
-rw-r--r--TODO17
-rw-r--r--configure.in2
-rw-r--r--libxslt/attributes.c5
-rw-r--r--libxslt/extensions.c2
-rw-r--r--libxslt/extensions.h1
-rw-r--r--libxslt/preproc.c549
-rw-r--r--libxslt/preproc.h4
-rw-r--r--libxslt/templates.c6
-rw-r--r--libxslt/templates.h2
-rw-r--r--libxslt/transform.c77
-rw-r--r--libxslt/variables.c379
-rw-r--r--libxslt/variables.h6
-rw-r--r--libxslt/xslt.c19
-rw-r--r--libxslt/xsltInternals.h175
15 files changed, 707 insertions, 546 deletions
diff --git a/ChangeLog b/ChangeLog
index cd8a1e25..cf3b8bb1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Sun Apr 29 11:47:58 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+ * preproc.[ch] templates.[ch] variables.[ch] xslt.c xsltInternals.h
+ attributes.c extensions.[ch]: moved all stylesheet precomputation
+ at stylesheet loading time (stylesheet transform should be thread
+ safe now), improved params and variables evaluations (but optim
+ is not complete yet).
+ * TODO: updated
+
Sat Apr 28 16:28:45 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
* libxslt/xsltproc.c : changed the way --repeat works when
diff --git a/TODO b/TODO
index 8c4dfcf6..bb4c72c0 100644
--- a/TODO
+++ b/TODO
@@ -8,15 +8,9 @@ Doc:
- manpage and doc for xsltproc
Design:
- - should transforms for a given stylesheet be thread clean,
- or can a stylesheet be enriched with document specific
- informations and cleaned up later ?
- seems that saving back XSLT stylesheet from a compiled form might
be a bit ugly ...
-Embedding Stylesheets:
- - example in 2.7 would force to validate, we do it by default now
-
Import:
@@ -51,6 +45,17 @@ Sorting:
* *
********
+Design:
+ - should transforms for a given stylesheet be thread clean,
+ -> the precompilation now occur only at stylesheet processing
+ time (except the binding for named templates and extension
+ functions which need to be computed once at run-time).
+ Multiple threads should be able to reuse the same stylesheet
+ now.
+
+Embedding Stylesheets:
+ - example in 2.7 would force to validate, we do it by default now
+
ID and Key support:
-> Done
diff --git a/configure.in b/configure.in
index e2e114cc..6332e284 100644
--- a/configure.in
+++ b/configure.in
@@ -49,7 +49,7 @@ if test "${LOGNAME}" = "veillard" -a "`pwd`" = "/u/veillard/XSLT" ; then
fi
AC_ARG_WITH(debug, [ --with-debug Add the debugging code (on)])
-if test "$with_mem_debug" = "no" ; then
+if test "$with_debug" = "no" ; then
echo Disabling debug support
WITH_XSLT_DEBUG=0
else
diff --git a/libxslt/attributes.c b/libxslt/attributes.c
index dde13ed7..06478b70 100644
--- a/libxslt/attributes.c
+++ b/libxslt/attributes.c
@@ -418,7 +418,10 @@ xsltApplyAttributeSet(xsltTransformContextPtr ctxt, xmlNodePtr node,
while (style != NULL) {
values = xmlHashLookup2(style->attributeSets, ncname, prefix);
while (values != NULL) {
- xsltAttribute(ctxt, node, values->attr, NULL);
+ if (values->attr != NULL) {
+ xsltAttribute(ctxt, node, values->attr,
+ values->attr->_private);
+ }
values = values->next;
}
style = xsltNextImport(style);
diff --git a/libxslt/extensions.c b/libxslt/extensions.c
index d6d60efc..d56e6fb9 100644
--- a/libxslt/extensions.c
+++ b/libxslt/extensions.c
@@ -35,8 +35,6 @@ struct _xsltExtDef {
xmlChar *URI;
};
-const xmlChar *xsltExtMarker = (const xmlChar *)"extension";
-
/************************************************************************
* *
* Type functions *
diff --git a/libxslt/extensions.h b/libxslt/extensions.h
index d14a314c..65685848 100644
--- a/libxslt/extensions.h
+++ b/libxslt/extensions.h
@@ -32,7 +32,6 @@ int xsltRegisterExtElement (xsltTransformContextPtr ctxt,
void xsltFreeCtxtExts (xsltTransformContextPtr ctxt);
void xsltFreeExts (xsltStylesheetPtr style);
-extern const xmlChar *xsltExtMarker;
#ifdef __cplusplus
}
#endif
diff --git a/libxslt/preproc.c b/libxslt/preproc.c
index cdc2e5a5..aece8fc5 100644
--- a/libxslt/preproc.c
+++ b/libxslt/preproc.c
@@ -41,6 +41,7 @@
#define WITH_XSLT_DEBUG_PREPROC
#endif
+const xmlChar *xsltExtMarker = (const xmlChar *) "Extension Element";
/************************************************************************
* *
@@ -50,7 +51,7 @@
/**
* xsltNewStylePreComp:
- * @ctxt: an XSLT processing context
+ * @style: the XSLT stylesheet
* @type: the construct type
*
* Create a new XSLT Style precomputed block
@@ -58,7 +59,7 @@
* Returns the newly allocated xsltStylePreCompPtr or NULL in case of error
*/
static xsltStylePreCompPtr
-xsltNewStylePreComp(xsltTransformContextPtr ctxt, xsltStyleType type) {
+xsltNewStylePreComp(xsltStylesheetPtr style, xsltStyleType type) {
xsltStylePreCompPtr cur;
cur = (xsltStylePreCompPtr) xmlMalloc(sizeof(xsltStylePreComp));
@@ -105,13 +106,22 @@ xsltNewStylePreComp(xsltTransformContextPtr ctxt, xsltStyleType type) {
cur->func = xsltForEach;break;
case XSLT_FUNC_DOCUMENT:
cur->func = xsltDocumentElem;break;
+ case XSLT_FUNC_WITHPARAM:
+ cur->func = NULL;break;
+ case XSLT_FUNC_PARAM:
+ cur->func = NULL;break;
+ case XSLT_FUNC_VARIABLE:
+ cur->func = NULL;break;
+ case XSLT_FUNC_WHEN:
+ cur->func = NULL;break;
+ default:
+ if (cur->func == NULL) {
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltNewStylePreComp : no function for type %d\n", type);
+ }
}
- if (cur->func == NULL) {
- xsltGenericError(xsltGenericErrorContext,
- "xsltNewStylePreComp : no function for type %d\n", type);
- }
- cur->next = ctxt->preComps;
- ctxt->preComps = cur;
+ cur->next = style->preComps;
+ style->preComps = cur;
return(cur);
}
@@ -165,8 +175,6 @@ xsltFreeStylePreComp(xsltStylePreCompPtr comp) {
if (comp->nsList != NULL)
xmlFree(comp->nsList);
- memset(comp, -1, sizeof(xsltStylePreComp));
-
xmlFree(comp);
}
@@ -179,19 +187,19 @@ xsltFreeStylePreComp(xsltStylePreCompPtr comp) {
/**
* xsltDocumentComp:
- * @ctxt: an XSLT processing context
+ * @style: the XSLT stylesheet
* @inst: the instruction in the stylesheet
*
* Pre process an XSLT-1.1 document element
*/
static void
-xsltDocumentComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
+xsltDocumentComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
xmlChar *filename = NULL;
xmlChar *base = NULL;
xmlChar *URL = NULL;
- comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_DOCUMENT);
+ comp = xsltNewStylePreComp(style, XSLT_FUNC_DOCUMENT);
if (comp == NULL)
return;
inst->_private = comp;
@@ -203,7 +211,7 @@ xsltDocumentComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
xsltGenericDebug(xsltGenericDebugContext,
"Found saxon:output extension\n");
#endif
- filename = xsltEvalStaticAttrValueTemplate(ctxt, inst,
+ filename = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"file",
XSLT_SAXON_NAMESPACE, &comp->has_filename);
} else if (xmlStrEqual(inst->name, (const xmlChar *) "write")) {
@@ -211,11 +219,11 @@ xsltDocumentComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
xsltGenericDebug(xsltGenericDebugContext,
"Found xalan:write extension\n");
#endif
- filename = xsltEvalStaticAttrValueTemplate(ctxt, inst,
+ filename = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"select",
XSLT_XALAN_NAMESPACE, &comp->has_filename);
} else if (xmlStrEqual(inst->name, (const xmlChar *) "document")) {
- filename = xsltEvalStaticAttrValueTemplate(ctxt, inst,
+ filename = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"href",
XSLT_XT_NAMESPACE, &comp->has_filename);
if (filename == NULL) {
@@ -223,7 +231,7 @@ xsltDocumentComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
xsltGenericDebug(xsltGenericDebugContext,
"Found xslt11:document construct\n");
#endif
- filename = xsltEvalStaticAttrValueTemplate(ctxt, inst,
+ filename = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"href",
XSLT_NAMESPACE, &comp->has_filename);
comp->ver11 = 1;
@@ -273,25 +281,25 @@ error:
/**
* xsltSortComp:
- * @ctxt: a XSLT process context
+ * @style: the XSLT stylesheet
* @inst: the xslt sort node
*
* Process the xslt sort node on the source node
*/
static void
-xsltSortComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
+xsltSortComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
- if ((ctxt == NULL) || (inst == NULL))
+ if ((style == NULL) || (inst == NULL))
return;
- comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_SORT);
+ comp = xsltNewStylePreComp(style, XSLT_FUNC_SORT);
if (comp == NULL)
return;
inst->_private = comp;
comp->inst = inst;
- comp->stype = xsltEvalStaticAttrValueTemplate(ctxt, inst,
+ comp->stype = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"data-type",
XSLT_NAMESPACE, &comp->has_stype);
if (comp->stype != NULL) {
@@ -305,7 +313,7 @@ xsltSortComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
comp->number = -1;
}
}
- comp->order = xsltEvalStaticAttrValueTemplate(ctxt, inst,
+ comp->order = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"order",
XSLT_NAMESPACE, &comp->has_order);
if (comp->order != NULL) {
@@ -335,19 +343,19 @@ xsltSortComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
/**
* xsltCopyComp:
- * @ctxt: a XSLT process context
+ * @style: the XSLT stylesheet
* @inst: the xslt copy node
*
* Process the xslt copy node on the source node
*/
static void
-xsltCopyComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
+xsltCopyComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
- if ((ctxt == NULL) || (inst == NULL))
+ if ((style == NULL) || (inst == NULL))
return;
- comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_COPY);
+ comp = xsltNewStylePreComp(style, XSLT_FUNC_COPY);
if (comp == NULL)
return;
inst->_private = comp;
@@ -364,19 +372,19 @@ xsltCopyComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
/**
* xsltTextComp:
- * @ctxt: a XSLT process context
+ * @style: a XSLT process context
* @inst: the xslt text node
*
* Process the xslt text node on the source node
*/
static void
-xsltTextComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
+xsltTextComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
xmlChar *prop;
- if ((ctxt == NULL) || (inst == NULL))
+ if ((style == NULL) || (inst == NULL))
return;
- comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_TEXT);
+ comp = xsltNewStylePreComp(style, XSLT_FUNC_TEXT);
if (comp == NULL)
return;
inst->_private = comp;
@@ -400,18 +408,18 @@ xsltTextComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
/**
* xsltElementComp:
- * @ctxt: a XSLT process context
+ * @style: a XSLT process context
* @inst: the xslt element node
*
* Process the xslt element node on the source node
*/
static void
-xsltElementComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
+xsltElementComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
- if ((ctxt == NULL) || (inst == NULL))
+ if ((style == NULL) || (inst == NULL))
return;
- comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_ELEMENT);
+ comp = xsltNewStylePreComp(style, XSLT_FUNC_ELEMENT);
if (comp == NULL)
return;
inst->_private = comp;
@@ -420,32 +428,32 @@ xsltElementComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
/*
* TODO: more computation can be done there, especially namespace lookup
*/
- comp->name = xsltEvalStaticAttrValueTemplate(ctxt, inst,
+ comp->name = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"name",
XSLT_NAMESPACE, &comp->has_name);
- comp->ns = xsltEvalStaticAttrValueTemplate(ctxt, inst,
+ comp->ns = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"namespace",
XSLT_NAMESPACE, &comp->has_ns);
- comp->use = xsltEvalStaticAttrValueTemplate(ctxt, inst,
+ comp->use = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"use-attribute-sets",
XSLT_NAMESPACE, &comp->has_use);
}
/**
* xsltAttributeComp:
- * @ctxt: a XSLT process context
+ * @style: a XSLT process context
* @inst: the xslt attribute node
*
* Process the xslt attribute node on the source node
*/
static void
-xsltAttributeComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
+xsltAttributeComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
- if ((ctxt == NULL) || (inst == NULL))
+ if ((style == NULL) || (inst == NULL))
return;
- comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_ATTRIBUTE);
+ comp = xsltNewStylePreComp(style, XSLT_FUNC_ATTRIBUTE);
if (comp == NULL)
return;
inst->_private = comp;
@@ -454,10 +462,10 @@ xsltAttributeComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
/*
* TODO: more computation can be done there, especially namespace lookup
*/
- comp->name = xsltEvalStaticAttrValueTemplate(ctxt, inst,
+ comp->name = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"name",
XSLT_NAMESPACE, &comp->has_name);
- comp->ns = xsltEvalStaticAttrValueTemplate(ctxt, inst,
+ comp->ns = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"namespace",
XSLT_NAMESPACE, &comp->has_ns);
@@ -465,18 +473,18 @@ xsltAttributeComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
/**
* xsltCommentComp:
- * @ctxt: a XSLT process context
+ * @style: a XSLT process context
* @inst: the xslt comment node
*
* Process the xslt comment node on the source node
*/
static void
-xsltCommentComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
+xsltCommentComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
- if ((ctxt == NULL) || (inst == NULL))
+ if ((style == NULL) || (inst == NULL))
return;
- comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_COMMENT);
+ comp = xsltNewStylePreComp(style, XSLT_FUNC_COMMENT);
if (comp == NULL)
return;
inst->_private = comp;
@@ -485,42 +493,42 @@ xsltCommentComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
/**
* xsltProcessingInstructionComp:
- * @ctxt: a XSLT process context
+ * @style: a XSLT process context
* @inst: the xslt processing-instruction node
*
* Process the xslt processing-instruction node on the source node
*/
static void
-xsltProcessingInstructionComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
+xsltProcessingInstructionComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
- if ((ctxt == NULL) || (inst == NULL))
+ if ((style == NULL) || (inst == NULL))
return;
- comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_PI);
+ comp = xsltNewStylePreComp(style, XSLT_FUNC_PI);
if (comp == NULL)
return;
inst->_private = comp;
comp->inst = inst;
- comp->name = xsltEvalStaticAttrValueTemplate(ctxt, inst,
+ comp->name = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"name",
XSLT_NAMESPACE, &comp->has_name);
}
/**
* xsltCopyOfComp:
- * @ctxt: a XSLT process context
+ * @style: a XSLT process context
* @inst: the xslt copy-of node
*
* Process the xslt copy-of node on the source node
*/
static void
-xsltCopyOfComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
+xsltCopyOfComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
- if ((ctxt == NULL) || (inst == NULL))
+ if ((style == NULL) || (inst == NULL))
return;
- comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_COPYOF);
+ comp = xsltNewStylePreComp(style, XSLT_FUNC_COPYOF);
if (comp == NULL)
return;
inst->_private = comp;
@@ -536,19 +544,19 @@ xsltCopyOfComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
/**
* xsltValueOfComp:
- * @ctxt: a XSLT process context
+ * @style: a XSLT process context
* @inst: the xslt value-of node
*
* Process the xslt value-of node on the source node
*/
static void
-xsltValueOfComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
+xsltValueOfComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
xmlChar *prop;
- if ((ctxt == NULL) || (inst == NULL))
+ if ((style == NULL) || (inst == NULL))
return;
- comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_VALUEOF);
+ comp = xsltNewStylePreComp(style, XSLT_FUNC_VALUEOF);
if (comp == NULL)
return;
inst->_private = comp;
@@ -576,25 +584,96 @@ xsltValueOfComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
}
/**
+ * xsltWithParamComp:
+ * @style: a XSLT process context
+ * @inst: the xslt with-param node
+ *
+ * Process the xslt with-param node on the source node
+ */
+static void
+xsltWithParamComp(xsltStylesheetPtr style, xmlNodePtr inst) {
+ xsltStylePreCompPtr comp;
+ xmlChar *prop;
+ xmlChar *ncname = NULL;
+ xmlChar *prefix = NULL;
+ xmlNsPtr ns = NULL;
+
+ if ((style == NULL) || (inst == NULL))
+ return;
+ comp = xsltNewStylePreComp(style, XSLT_FUNC_WITHPARAM);
+ if (comp == NULL)
+ return;
+ inst->_private = comp;
+ comp->inst = inst;
+
+ /*
+ * The full namespace resolution can be done statically
+ */
+ prop = xmlGetNsProp(inst, (const xmlChar *)"name", XSLT_NAMESPACE);
+ if (prop == NULL) {
+ xsltGenericError(xsltGenericErrorContext,
+ "xslt:with-param : name is missing\n");
+ } else {
+
+ ncname = xmlSplitQName2(prop, &prefix);
+ if (ncname == NULL) {
+ ncname = prop;
+ prop = NULL;
+ prefix = NULL;
+ }
+ if (prefix != NULL) {
+ ns = xmlSearchNs(inst->doc, inst, prefix);
+ if (ns == NULL) {
+ xsltGenericError(xsltGenericErrorContext,
+ "xslt:with-param : no namespace bound to prefix %s\n", prefix);
+ }
+ }
+ comp->name = xmlStrdup(ncname);
+ comp->has_name = 1;
+ if (ns != NULL) {
+ comp->has_ns = 1;
+ comp->ns = xmlStrdup(ns->href);
+ } else
+ comp->has_ns = 0;
+ }
+
+ comp->select = xmlGetNsProp(inst, (const xmlChar *)"select",
+ XSLT_NAMESPACE);
+ if (comp->select != NULL) {
+ if (inst->children != NULL)
+ xsltGenericError(xsltGenericErrorContext,
+ "xsl:param : content should be empty since select is present \n");
+ }
+ comp->comp = NULL;
+
+ if (prop != NULL)
+ xmlFree(prop);
+ if (ncname != NULL)
+ xmlFree(ncname);
+ if (prefix != NULL)
+ xmlFree(prefix);
+}
+
+/**
* xsltNumberComp:
- * @ctxt: a XSLT process context
+ * @style: a XSLT process context
* @cur: the xslt number node
*
* Process the xslt number node on the source node
*/
static void
-xsltNumberComp(xsltTransformContextPtr ctxt, xmlNodePtr cur) {
+xsltNumberComp(xsltStylesheetPtr style, xmlNodePtr cur) {
xsltStylePreCompPtr comp;
xmlChar *prop;
- if ((ctxt == NULL) || (cur == NULL))
+ if ((style == NULL) || (cur == NULL))
return;
- comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_NUMBER);
+ comp = xsltNewStylePreComp(style, XSLT_FUNC_NUMBER);
if (comp == NULL)
return;
cur->_private = comp;
- if ((ctxt == NULL) || (cur == NULL))
+ if ((style == NULL) || (cur == NULL))
return;
comp->numdata.doc = cur->doc;
@@ -671,18 +750,18 @@ xsltNumberComp(xsltTransformContextPtr ctxt, xmlNodePtr cur) {
/**
* xsltApplyImportsComp:
- * @ctxt: a XSLT process context
+ * @style: a XSLT process context
* @inst: the xslt apply-imports node
*
* Process the xslt apply-imports node on the source node
*/
static void
-xsltApplyImportsComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
+xsltApplyImportsComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
- if ((ctxt == NULL) || (inst == NULL))
+ if ((style == NULL) || (inst == NULL))
return;
- comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_APPLYIMPORTS);
+ comp = xsltNewStylePreComp(style, XSLT_FUNC_APPLYIMPORTS);
if (comp == NULL)
return;
inst->_private = comp;
@@ -691,22 +770,22 @@ xsltApplyImportsComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
/**
* xsltCallTemplateComp:
- * @ctxt: a XSLT process context
+ * @style: a XSLT process context
* @inst: the xslt call-template node
*
* Process the xslt call-template node on the source node
*/
static void
-xsltCallTemplateComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
+xsltCallTemplateComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
xmlChar *prop;
xmlChar *ncname = NULL;
xmlChar *prefix = NULL;
xmlNsPtr ns = NULL;
- if ((ctxt == NULL) || (inst == NULL))
+ if ((style == NULL) || (inst == NULL))
return;
- comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_CALLTEMPLATE);
+ comp = xsltNewStylePreComp(style, XSLT_FUNC_CALLTEMPLATE);
if (comp == NULL)
return;
inst->_private = comp;
@@ -728,25 +807,22 @@ xsltCallTemplateComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
prefix = NULL;
}
if (prefix != NULL) {
- ns = xmlSearchNs(ctxt->insert->doc, ctxt->insert, prefix);
+ ns = xmlSearchNs(inst->doc, inst, prefix);
if (ns == NULL) {
xsltGenericError(xsltGenericErrorContext,
- "no namespace bound to prefix %s\n", prefix);
+ "xslt:call-template : no namespace bound to prefix %s\n", prefix);
}
}
- if (ns != NULL)
- comp->templ = xsltFindTemplate(ctxt, ncname, ns->href);
- else
- comp->templ = xsltFindTemplate(ctxt, ncname, NULL);
-
- if (comp->templ == NULL) {
- xsltGenericError(xsltGenericErrorContext,
- "xslt:call-template : template %s not found\n", ncname);
- }
+ comp->name = xmlStrdup(ncname);
+ comp->has_name = 1;
+ if (ns != NULL) {
+ comp->ns = xmlStrdup(ns->href);
+ comp->has_ns = 1;
+ } else
+ comp->has_ns = 0;
+ comp->templ = NULL;
}
- /* TODO: with-param could be optimized too */
-
if (prop != NULL)
xmlFree(prop);
if (ncname != NULL)
@@ -757,19 +833,19 @@ xsltCallTemplateComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
/**
* xsltApplyTemplatesComp:
- * @ctxt: a XSLT process context
+ * @style: a XSLT process context
* @inst: the apply-templates node
*
* Process the apply-templates node on the source node
*/
static void
-xsltApplyTemplatesComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
+xsltApplyTemplatesComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
xmlChar *prop;
- if ((ctxt == NULL) || (inst == NULL))
+ if ((style == NULL) || (inst == NULL))
return;
- comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_APPLYTEMPLATES);
+ comp = xsltNewStylePreComp(style, XSLT_FUNC_APPLYTEMPLATES);
if (comp == NULL)
return;
inst->_private = comp;
@@ -817,18 +893,18 @@ xsltApplyTemplatesComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
/**
* xsltChooseComp:
- * @ctxt: a XSLT process context
+ * @style: a XSLT process context
* @inst: the xslt choose node
*
* Process the xslt choose node on the source node
*/
static void
-xsltChooseComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
+xsltChooseComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
- if ((ctxt == NULL) || (inst == NULL))
+ if ((style == NULL) || (inst == NULL))
return;
- comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_CHOOSE);
+ comp = xsltNewStylePreComp(style, XSLT_FUNC_CHOOSE);
if (comp == NULL)
return;
inst->_private = comp;
@@ -837,18 +913,18 @@ xsltChooseComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
/**
* xsltIfComp:
- * @ctxt: a XSLT process context
+ * @style: a XSLT process context
* @inst: the xslt if node
*
* Process the xslt if node on the source node
*/
static void
-xsltIfComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
+xsltIfComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
- if ((ctxt == NULL) || (inst == NULL))
+ if ((style == NULL) || (inst == NULL))
return;
- comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_IF);
+ comp = xsltNewStylePreComp(style, XSLT_FUNC_IF);
if (comp == NULL)
return;
inst->_private = comp;
@@ -857,25 +933,52 @@ xsltIfComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
comp->test = xmlGetNsProp(inst, (const xmlChar *)"test", XSLT_NAMESPACE);
if (comp->test == NULL) {
xsltGenericError(xsltGenericErrorContext,
- "xsltIf: test is not defined\n");
+ "xslt:if : test is not defined\n");
+ return;
+ }
+}
+
+/**
+ * xsltWhenComp:
+ * @style: a XSLT process context
+ * @inst: the xslt if node
+ *
+ * Process the xslt if node on the source node
+ */
+static void
+xsltWhenComp(xsltStylesheetPtr style, xmlNodePtr inst) {
+ xsltStylePreCompPtr comp;
+
+ if ((style == NULL) || (inst == NULL))
+ return;
+ comp = xsltNewStylePreComp(style, XSLT_FUNC_WHEN);
+ if (comp == NULL)
+ return;
+ inst->_private = comp;
+ comp->inst = inst;
+
+ comp->test = xmlGetNsProp(inst, (const xmlChar *)"test", XSLT_NAMESPACE);
+ if (comp->test == NULL) {
+ xsltGenericError(xsltGenericErrorContext,
+ "xsl:when : test is not defined\n");
return;
}
}
/**
* xsltForEachComp:
- * @ctxt: a XSLT process context
+ * @style: a XSLT process context
* @inst: the xslt for-each node
*
* Process the xslt for-each node on the source node
*/
static void
-xsltForEachComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
+xsltForEachComp(xsltStylesheetPtr style, xmlNodePtr inst) {
xsltStylePreCompPtr comp;
- if ((ctxt == NULL) || (inst == NULL))
+ if ((style == NULL) || (inst == NULL))
return;
- comp = xsltNewStylePreComp(ctxt, XSLT_FUNC_FOREACH);
+ comp = xsltNewStylePreComp(style, XSLT_FUNC_FOREACH);
if (comp == NULL)
return;
inst->_private = comp;
@@ -887,6 +990,144 @@ xsltForEachComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
/* TODO: handle and skip the xsl:sort */
}
+/**
+ * xsltVariableComp:
+ * @style: a XSLT process context
+ * @inst: the xslt variable node
+ *
+ * Process the xslt variable node on the source node
+ */
+static void
+xsltVariableComp(xsltStylesheetPtr style, xmlNodePtr inst) {
+ xsltStylePreCompPtr comp;
+ xmlChar *prop;
+ xmlChar *ncname = NULL;
+ xmlChar *prefix = NULL;
+ xmlNsPtr ns = NULL;
+
+ if ((style == NULL) || (inst == NULL))
+ return;
+ comp = xsltNewStylePreComp(style, XSLT_FUNC_VARIABLE);
+ if (comp == NULL)
+ return;
+ inst->_private = comp;
+ comp->inst = inst;
+
+ /*
+ * The full template resolution can be done statically
+ */
+ prop = xmlGetNsProp(inst, (const xmlChar *)"name", XSLT_NAMESPACE);
+ if (prop == NULL) {
+ xsltGenericError(xsltGenericErrorContext,
+ "xslt:variable : name is missing\n");
+ } else {
+ ncname = xmlSplitQName2(prop, &prefix);
+ if (ncname == NULL) {
+ ncname = prop;
+ prop = NULL;
+ prefix = NULL;
+ }
+ if (prefix != NULL) {
+ ns = xmlSearchNs(inst->doc, inst, prefix);
+ if (ns == NULL) {
+ xsltGenericError(xsltGenericErrorContext,
+ "xsl:variable no namespace bound to prefix %s\n", prefix);
+ }
+ }
+ comp->name = xmlStrdup(ncname);
+ comp->has_name = 1;
+ if (ns != NULL) {
+ comp->ns = xmlStrdup(ns->href);
+ comp->has_ns = 1;
+ } else
+ comp->has_ns = 0;
+ }
+
+ comp->select = xmlGetNsProp(inst, (const xmlChar *)"select",
+ XSLT_NAMESPACE);
+ if (comp->select != NULL) {
+ if (inst->children != NULL)
+ xsltGenericError(xsltGenericErrorContext,
+ "xsl:variable : content should be empty since select is present \n");
+ }
+
+ if (prop != NULL)
+ xmlFree(prop);
+ if (ncname != NULL)
+ xmlFree(ncname);
+ if (prefix != NULL)
+ xmlFree(prefix);
+}
+
+/**
+ * xsltParamComp:
+ * @style: a XSLT process context
+ * @inst: the xslt param node
+ *
+ * Process the xslt param node on the source node
+ */
+static void
+xsltParamComp(xsltStylesheetPtr style, xmlNodePtr inst) {
+ xsltStylePreCompPtr comp;
+ xmlChar *prop;
+ xmlChar *ncname = NULL;
+ xmlChar *prefix = NULL;
+ xmlNsPtr ns = NULL;
+
+ if ((style == NULL) || (inst == NULL))
+ return;
+ comp = xsltNewStylePreComp(style, XSLT_FUNC_PARAM);
+ if (comp == NULL)
+ return;
+ inst->_private = comp;
+ comp->inst = inst;
+
+ /*
+ * The full template resolution can be done statically
+ */
+ prop = xmlGetNsProp(inst, (const xmlChar *)"name", XSLT_NAMESPACE);
+ if (prop == NULL) {
+ xsltGenericError(xsltGenericErrorContext,
+ "xslt:param : name is missing\n");
+ } else {
+ ncname = xmlSplitQName2(prop, &prefix);
+ if (ncname == NULL) {
+ ncname = prop;
+ prop = NULL;
+ prefix = NULL;
+ }
+ if (prefix != NULL) {
+ ns = xmlSearchNs(inst->doc, inst, prefix);
+ if (ns == NULL) {
+ xsltGenericError(xsltGenericErrorContext,
+ "xsl:param no namespace bound to prefix %s\n", prefix);
+ }
+ }
+ comp->name = xmlStrdup(ncname);
+ comp->has_name = 1;
+ if (ns != NULL) {
+ comp->ns = xmlStrdup(ns->href);
+ comp->has_ns = 1;
+ } else
+ comp->has_ns = 0;
+ }
+
+ comp->select = xmlGetNsProp(inst, (const xmlChar *)"select",
+ XSLT_NAMESPACE);
+ if (comp->select != NULL) {
+ if (inst->children != NULL)
+ xsltGenericError(xsltGenericErrorContext,
+ "xsl:variable : content should be empty since select is present \n");
+ }
+
+ if (prop != NULL)
+ xmlFree(prop);
+ if (ncname != NULL)
+ xmlFree(ncname);
+ if (prefix != NULL)
+ xmlFree(prefix);
+}
+
/************************************************************************
* *
@@ -896,17 +1137,17 @@ xsltForEachComp(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
/**
* xsltFreeStylePreComps:
- * @ctxt: an XSLT transformation context
+ * @style: an XSLT transformation context
*
* Free up the memory allocated by all precomputed blocks
*/
void
-xsltFreeStylePreComps(xsltTransformContextPtr ctxt) {
+xsltFreeStylePreComps(xsltStylesheetPtr style) {
xsltStylePreCompPtr cur, next;
- if (ctxt == NULL)
+ if (style == NULL)
return;
- cur = ctxt->preComps;
+ cur = style->preComps;
while (cur != NULL) {
next = cur->next;
xsltFreeStylePreComp(cur);
@@ -916,61 +1157,99 @@ xsltFreeStylePreComps(xsltTransformContextPtr ctxt) {
/**
* xsltDocumentCompute:
- * @ctxt: an XSLT processing context
+ * @style: the XSLT stylesheet
* @inst: the instruction in the stylesheet
*
* Precompute an XSLT stylesheet element
*/
void
-xsltStylePreCompute(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
+xsltStylePreCompute(xsltStylesheetPtr style, xmlNodePtr inst) {
if (inst->_private != NULL)
return;
if (IS_XSLT_ELEM(inst)) {
xsltStylePreCompPtr cur;
if (IS_XSLT_NAME(inst, "apply-templates")) {
- xsltApplyTemplatesComp(ctxt, inst);
+ xsltApplyTemplatesComp(style, inst);
+ } else if (IS_XSLT_NAME(inst, "with-param")) {
+ xsltWithParamComp(style, inst);
} else if (IS_XSLT_NAME(inst, "value-of")) {
- xsltValueOfComp(ctxt, inst);
+ xsltValueOfComp(style, inst);
} else if (IS_XSLT_NAME(inst, "copy")) {
- xsltCopyComp(ctxt, inst);
+ xsltCopyComp(style, inst);
} else if (IS_XSLT_NAME(inst, "copy-of")) {
- xsltCopyOfComp(ctxt, inst);
+ xsltCopyOfComp(style, inst);
} else if (IS_XSLT_NAME(inst, "if")) {
- xsltIfComp(ctxt, inst);
+ xsltIfComp(style, inst);
+ } else if (IS_XSLT_NAME(inst, "when")) {
+ xsltWhenComp(style, inst);
} else if (IS_XSLT_NAME(inst, "choose")) {
- xsltChooseComp(ctxt, inst);
+ xsltChooseComp(style, inst);
} else if (IS_XSLT_NAME(inst, "for-each")) {
- xsltForEachComp(ctxt, inst);
+ xsltForEachComp(style, inst);
} else if (IS_XSLT_NAME(inst, "apply-imports")) {
- xsltApplyImportsComp(ctxt, inst);
+ xsltApplyImportsComp(style, inst);
} else if (IS_XSLT_NAME(inst, "attribute")) {
- xsltAttributeComp(ctxt, inst);
+ xsltAttributeComp(style, inst);
} else if (IS_XSLT_NAME(inst, "element")) {
- xsltElementComp(ctxt, inst);
+ xsltElementComp(style, inst);
} else if (IS_XSLT_NAME(inst, "text")) {
- xsltTextComp(ctxt, inst);
+ xsltTextComp(style, inst);
} else if (IS_XSLT_NAME(inst, "sort")) {
- xsltSortComp(ctxt, inst);
+ xsltSortComp(style, inst);
} else if (IS_XSLT_NAME(inst, "comment")) {
- xsltCommentComp(ctxt, inst);
+ xsltCommentComp(style, inst);
} else if (IS_XSLT_NAME(inst, "number")) {
- xsltNumberComp(ctxt, inst);
+ xsltNumberComp(style, inst);
} else if (IS_XSLT_NAME(inst, "processing-instruction")) {
- xsltProcessingInstructionComp(ctxt, inst);
+ xsltProcessingInstructionComp(style, inst);
} else if (IS_XSLT_NAME(inst, "call-template")) {
- xsltCallTemplateComp(ctxt, inst);
+ xsltCallTemplateComp(style, inst);
} else if (IS_XSLT_NAME(inst, "param")) {
- /* TODO: is there any use optimizing param too ? */
- return;
+ xsltParamComp(style, inst);
} else if (IS_XSLT_NAME(inst, "variable")) {
- /* TODO: is there any use optimizing variable too ? */
+ xsltVariableComp(style, inst);
+ } else if (IS_XSLT_NAME(inst, "otherwise")) {
+ /* no computation needed */
+ return;
+ } else if (IS_XSLT_NAME(inst, "template")) {
+ /* no computation needed */
+ return;
+ } else if (IS_XSLT_NAME(inst, "output")) {
+ /* no computation needed */
+ return;
+ } else if (IS_XSLT_NAME(inst, "preserve-space")) {
+ /* no computation needed */
+ return;
+ } else if (IS_XSLT_NAME(inst, "strip-space")) {
+ /* no computation needed */
+ return;
+ } else if (IS_XSLT_NAME(inst, "stylesheet")) {
+ /* no computation needed */
+ return;
+ } else if (IS_XSLT_NAME(inst, "key")) {
+ /* no computation needed */
return;
} else if (IS_XSLT_NAME(inst, "message")) {
- /* no optimization needed */
+ /* no computation needed */
+ return;
+ } else if (IS_XSLT_NAME(inst, "attribute-set")) {
+ /* no computation needed */
+ return;
+ } else if (IS_XSLT_NAME(inst, "namespace-alias")) {
+ /* no computation needed */
+ return;
+ } else if (IS_XSLT_NAME(inst, "include")) {
+ /* no computation needed */
+ return;
+ } else if (IS_XSLT_NAME(inst, "import")) {
+ /* no computation needed */
+ return;
+ } else if (IS_XSLT_NAME(inst, "decimal-format")) {
+ /* no computation needed */
return;
} else if (IS_XSLT_NAME(inst, "document")) {
- xsltDocumentComp(ctxt, inst);
+ xsltDocumentComp(style, inst);
} else {
xsltGenericError(xsltGenericDebugContext,
"xsltStylePreCompute: unknown xslt:%s\n", inst->name);
@@ -992,7 +1271,13 @@ xsltStylePreCompute(xsltTransformContextPtr ctxt, xmlNodePtr inst) {
}
} else {
if (IS_XSLT_NAME(inst, "document")) {
- xsltDocumentComp(ctxt, inst);
+ xsltDocumentComp(style, inst);
+ } else {
+ /*
+ * Mark the element for later recognition.
+ */
+ if (inst->_private == NULL)
+ inst->_private = (void *) xsltExtMarker;
}
}
}
diff --git a/libxslt/preproc.h b/libxslt/preproc.h
index f07412ea..7700db6d 100644
--- a/libxslt/preproc.h
+++ b/libxslt/preproc.h
@@ -19,9 +19,9 @@ extern "C" {
/*
* Interfaces
*/
-void xsltStylePreCompute (xsltTransformContextPtr ctxt,
+void xsltStylePreCompute (xsltStylesheetPtr style,
xmlNodePtr inst);
-void xsltFreeStylePreComps (xsltTransformContextPtr ctxt);
+void xsltFreeStylePreComps (xsltStylesheetPtr style);
#ifdef __cplusplus
}
#endif
diff --git a/libxslt/templates.c b/libxslt/templates.c
index db21a2a2..ea9aa2d5 100644
--- a/libxslt/templates.c
+++ b/libxslt/templates.c
@@ -262,7 +262,7 @@ xsltEvalAttrValueTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
/**
* xsltEvalStaticAttrValueTemplate:
- * @ctxt: the XSLT transformation context
+ * @style: the XSLT stylesheet
* @node: the stylesheet node
* @name: the attribute Name
* @name: the attribute namespace URI
@@ -275,12 +275,12 @@ xsltEvalAttrValueTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
* caller.
*/
xmlChar *
-xsltEvalStaticAttrValueTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
+xsltEvalStaticAttrValueTemplate(xsltStylesheetPtr style, xmlNodePtr node,
const xmlChar *name, const xmlChar *ns, int *found) {
const xmlChar *ret;
xmlChar *expr;
- if ((ctxt == NULL) || (node == NULL) || (name == NULL))
+ if ((style == NULL) || (node == NULL) || (name == NULL))
return(NULL);
expr = xmlGetNsProp(node, name, ns);
diff --git a/libxslt/templates.h b/libxslt/templates.h
index 78edefcf..02637c5a 100644
--- a/libxslt/templates.h
+++ b/libxslt/templates.h
@@ -26,7 +26,7 @@ xmlChar * xsltEvalAttrValueTemplate (xsltTransformContextPtr ctxt,
xmlNodePtr node,
const xmlChar *name,
const xmlChar *ns);
-xmlChar * xsltEvalStaticAttrValueTemplate (xsltTransformContextPtr ctxt,
+xmlChar * xsltEvalStaticAttrValueTemplate (xsltStylesheetPtr style,
xmlNodePtr node,
const xmlChar *name,
const xmlChar *ns,
diff --git a/libxslt/transform.c b/libxslt/transform.c
index d4fe1d89..052adc38 100644
--- a/libxslt/transform.c
+++ b/libxslt/transform.c
@@ -214,7 +214,6 @@ xsltFreeTransformContext(xsltTransformContextPtr ctxt) {
xmlFree(ctxt->varsTab);
xsltFreeDocuments(ctxt);
xsltFreeCtxtExts(ctxt);
- xsltFreeStylePreComps(ctxt);
memset(ctxt, -1, sizeof(xsltTransformContext));
xmlFree(ctxt);
}
@@ -876,20 +875,18 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
}
if (IS_XSLT_ELEM(cur)) {
- if (cur->_private == NULL)
- xsltStylePreCompute(ctxt, cur);
+ xsltStylePreCompPtr info = (xsltStylePreCompPtr) cur->_private;
+ if (info == NULL) {
+ xsltGenericError(xsltGenericDebugContext,
+ "xsltApplyOneTemplate: %s was not compiled\n",
+ cur->name);
+ goto skip_children;
+ }
- if (cur->_private != NULL) {
- xsltStylePreCompPtr info = (xsltStylePreCompPtr) cur->_private;
- if (info->func != NULL) {
- ctxt->insert = insert;
- info->func(ctxt, node, cur, info);
- ctxt->insert = oldInsert;
- } else {
- xsltGenericError(xsltGenericDebugContext,
- "xsltApplyOneTemplate: %s has _private without function\n",
- cur->name);
- }
+ if (info->func != NULL) {
+ ctxt->insert = insert;
+ info->func(ctxt, node, cur, info);
+ ctxt->insert = oldInsert;
goto skip_children;
}
@@ -953,10 +950,6 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
"xsltApplyOneTemplate: extension construct %s\n", cur->name);
#endif
- if (cur->_private == (void *) xsltExtMarker) {
- cur->_private = NULL;
- xsltStylePreCompute(ctxt, cur);
- }
ctxt->insert = insert;
function(ctxt, node, cur, cur->_private);
ctxt->insert = oldInsert;
@@ -1195,8 +1188,9 @@ xsltSort(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlNodePtr oldNode;
if (comp == NULL) {
- xsltStylePreCompute(ctxt, inst);
- comp = inst->_private;
+ xsltGenericError(xsltGenericErrorContext,
+ "xslt:sort : compilation had failed\n");
+ return;
}
if ((ctxt == NULL) || (node == NULL) || (inst == NULL) || (comp == NULL))
@@ -1560,8 +1554,9 @@ xsltAttribute(xsltTransformContextPtr ctxt, xmlNodePtr node,
if (ctxt->insert == NULL)
return;
if (comp == NULL) {
- xsltStylePreCompute(ctxt, inst);
- comp = inst->_private;
+ xsltGenericError(xsltGenericErrorContext,
+ "xslt:attribute : compilation had failed\n");
+ return;
}
if ((ctxt == NULL) || (node == NULL) || (inst == NULL) || (comp == NULL))
@@ -1916,8 +1911,9 @@ xsltNumber(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlNodePtr inst, xsltStylePreCompPtr comp)
{
if (comp == NULL) {
- xsltStylePreCompute(ctxt, inst);
- comp = inst->_private;
+ xsltGenericError(xsltGenericErrorContext,
+ "xslt:number : compilation had failed\n");
+ return;
}
if ((ctxt == NULL) || (node == NULL) || (inst == NULL) || (comp == NULL))
@@ -1974,18 +1970,24 @@ xsltCallTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
xsltStackElemPtr params = NULL, param;
- if (comp == NULL) {
- xsltStylePreCompute(ctxt, inst);
- comp = inst->_private;
- }
if (ctxt->insert == NULL)
return;
+ if (comp == NULL) {
+ xsltGenericError(xsltGenericErrorContext,
+ "xslt:call-template : compilation had failed\n");
+ return;
+ }
/*
* The template must have been precomputed
*/
- if (comp->templ == NULL)
- return;
+ if (comp->templ == NULL) {
+ comp->templ = xsltFindTemplate(ctxt, comp->name, comp->ns);
+ if (comp->templ == NULL) {
+ xsltGenericError(xsltGenericErrorContext,
+ "xslt:call-template : template %s not found\n", comp->name);
+ }
+ }
/*
* Create a new frame but block access to variables
@@ -2039,8 +2041,9 @@ xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node,
if (comp == NULL) {
- xsltStylePreCompute(ctxt, inst);
- comp = inst->_private;
+ xsltGenericError(xsltGenericErrorContext,
+ "xslt:apply-templates : compilation had failed\n");
+ return;
}
if ((ctxt == NULL) || (node == NULL) || (inst == NULL) || (comp == NULL))
return;
@@ -2363,8 +2366,9 @@ xsltIf(xsltTransformContextPtr ctxt, xmlNodePtr node,
int oldContextSize, oldProximityPosition;
if (comp == NULL) {
- xsltStylePreCompute(ctxt, inst);
- comp = inst->_private;
+ xsltGenericError(xsltGenericErrorContext,
+ "xslt:if : compilation had failed\n");
+ return;
}
if ((ctxt == NULL) || (node == NULL) || (inst == NULL) || (comp == NULL))
return;
@@ -2439,8 +2443,9 @@ xsltForEach(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlNodePtr oldNode = ctxt->node;
if (comp == NULL) {
- xsltStylePreCompute(ctxt, inst);
- comp = inst->_private;
+ xsltGenericError(xsltGenericErrorContext,
+ "xslt:for-each : compilation had failed\n");
+ return;
}
if ((ctxt == NULL) || (node == NULL) || (inst == NULL) || (comp == NULL))
return;
diff --git a/libxslt/variables.c b/libxslt/variables.c
index 8730de53..3a5d7b28 100644
--- a/libxslt/variables.c
+++ b/libxslt/variables.c
@@ -28,6 +28,7 @@
#include "variables.h"
#include "transform.h"
#include "imports.h"
+#include "preproc.h"
#ifdef WITH_XSLT_DEBUG
#define WITH_XSLT_DEBUG_VARIABLE
@@ -245,8 +246,9 @@ xsltStackLookup(xsltTransformContextPtr ctxt, const xmlChar *name,
* Returns 0 in case of success, -1 in case of error
*/
static int
-xsltEvalVariable(xsltTransformContextPtr ctxt, xsltStackElemPtr elem) {
-int oldProximityPosition, oldContextSize;
+xsltEvalVariable(xsltTransformContextPtr ctxt, xsltStackElemPtr elem,
+ xsltStylePreCompPtr precomp) {
+ int oldProximityPosition, oldContextSize;
if ((ctxt == NULL) || (elem == NULL))
return(-1);
@@ -255,10 +257,18 @@ int oldProximityPosition, oldContextSize;
"Evaluating variable %s\n", elem->name);
#endif
if (elem->select != NULL) {
- xmlXPathCompExprPtr comp;
+ xmlXPathCompExprPtr comp = NULL;
xmlXPathObjectPtr result;
- comp = xmlXPathCompile(elem->select);
+ if (precomp != NULL) {
+ comp = precomp->comp;
+ if (comp == NULL) {
+ comp = xmlXPathCompile(elem->select);
+ precomp->comp = comp;
+ }
+ } else {
+ comp = xmlXPathCompile(elem->select);
+ }
if (comp == NULL)
return(-1);
oldProximityPosition = ctxt->xpathCtxt->proximityPosition;
@@ -270,7 +280,8 @@ int oldProximityPosition, oldContextSize;
result = xmlXPathCompiledEval(comp, ctxt->xpathCtxt);
ctxt->xpathCtxt->contextSize = oldContextSize;
ctxt->xpathCtxt->proximityPosition = oldProximityPosition;
- xmlXPathFreeCompExpr(comp);
+ if (precomp == NULL)
+ xmlXPathFreeCompExpr(comp);
if (result == NULL) {
xsltGenericError(xsltGenericErrorContext,
"Evaluating variable %s failed\n", elem->name);
@@ -358,7 +369,7 @@ xsltEvalGlobalVariables(xsltTransformContextPtr ctxt) {
while (elem != NULL) {
if (elem->computed == 0)
- xsltEvalVariable(ctxt, elem);
+ xsltEvalVariable(ctxt, elem, NULL);
elem = elem->next;
}
@@ -498,21 +509,16 @@ xsltEvalUserParams(xsltTransformContextPtr ctxt, const char **params) {
* Returns the xsltStackElemPtr or NULL in case of error
*/
static xsltStackElemPtr
-xsltBuildVariable(xsltTransformContextPtr ctxt, const xmlChar *name,
- const xmlChar *ns_uri, const xmlChar *select,
- xmlNodePtr tree, int param) {
+xsltBuildVariable(xsltTransformContextPtr ctxt, xsltStylePreCompPtr comp,
+ xmlNodePtr tree, int param) {
xsltStackElemPtr elem;
- if (ctxt == NULL)
- return(NULL);
- if (name == NULL)
- return(NULL);
#ifdef WITH_XSLT_DEBUG_VARIABLE
xsltGenericDebug(xsltGenericDebugContext,
- "Building variable %s", name);
- if (select != NULL)
+ "Building variable %s", comp->name);
+ if (comp->select != NULL)
xsltGenericDebug(xsltGenericDebugContext,
- " select %s", select);
+ " select %s", comp->select);
xsltGenericDebug(xsltGenericDebugContext, "\n");
#endif
elem = xsltNewStackElem();
@@ -522,15 +528,15 @@ xsltBuildVariable(xsltTransformContextPtr ctxt, const xmlChar *name,
elem->type = XSLT_ELEM_PARAM;
else
elem->type = XSLT_ELEM_VARIABLE;
- elem->name = xmlStrdup(name);
- if (select != NULL)
- elem->select = xmlStrdup(select);
+ elem->name = xmlStrdup(comp->name);
+ if (comp->select != NULL)
+ elem->select = xmlStrdup(comp->select);
else
elem->select = NULL;
- if (ns_uri)
- elem->nameURI = xmlStrdup(ns_uri);
+ if (comp->ns)
+ elem->nameURI = xmlStrdup(comp->ns);
elem->tree = tree;
- xsltEvalVariable(ctxt, elem);
+ xsltEvalVariable(ctxt, elem, comp);
return(elem);
}
@@ -547,29 +553,24 @@ xsltBuildVariable(xsltTransformContextPtr ctxt, const xmlChar *name,
*
* Returns 0 in case of success, -1 in case of error
*/
-int
-xsltRegisterVariable(xsltTransformContextPtr ctxt, const xmlChar *name,
- const xmlChar *ns_uri, const xmlChar *select,
+static int
+xsltRegisterVariable(xsltTransformContextPtr ctxt, xsltStylePreCompPtr comp,
xmlNodePtr tree, int param) {
xsltStackElemPtr elem;
- if (ctxt == NULL)
- return(-1);
- if (name == NULL)
- return(-1);
- if (xsltCheckStackElem(ctxt, name, ns_uri) != 0) {
+ if (xsltCheckStackElem(ctxt, comp->name, comp->ns) != 0) {
if (!param) {
xsltGenericError(xsltGenericErrorContext,
- "xsl:variable : redefining %s\n", name);
+ "xsl:variable : redefining %s\n", comp->name);
}
#ifdef WITH_XSLT_DEBUG_VARIABLE
else
xsltGenericDebug(xsltGenericDebugContext,
- "param %s defined by caller", name);
+ "param %s defined by caller", comp->name);
#endif
return(0);
}
- elem = xsltBuildVariable(ctxt, name, ns_uri, select, tree, param);
+ elem = xsltBuildVariable(ctxt, comp, tree, param);
xsltAddStackElem(ctxt, elem);
return(0);
}
@@ -621,7 +622,7 @@ xsltGlobalVariableLookup(xsltTransformContextPtr ctxt, const xmlChar *name,
xsltGenericDebug(xsltGenericDebugContext,
"uncomputed global variable %s\n", name);
#endif
- xsltEvalVariable(ctxt, elem);
+ xsltEvalVariable(ctxt, elem, NULL);
}
if (elem->value != NULL)
return(xmlXPathObjectCopy(elem->value));
@@ -660,7 +661,7 @@ xsltVariableLookup(xsltTransformContextPtr ctxt, const xmlChar *name,
xsltGenericDebug(xsltGenericDebugContext,
"uncomputed variable %s\n", name);
#endif
- xsltEvalVariable(ctxt, elem);
+ xsltEvalVariable(ctxt, elem, NULL);
}
if (elem->value != NULL)
return(xmlXPathObjectCopy(elem->value));
@@ -684,137 +685,43 @@ xsltVariableLookup(xsltTransformContextPtr ctxt, const xmlChar *name,
xsltStackElemPtr
xsltParseStylesheetCallerParam(xsltTransformContextPtr ctxt, xmlNodePtr cur) {
- xmlChar *name, *ncname, *prefix;
- xmlChar *select;
xmlNodePtr tree = NULL;
xsltStackElemPtr elem = NULL;
+ xsltStylePreCompPtr comp;
if ((cur == NULL) || (ctxt == NULL))
return(NULL);
-
- name = xmlGetNsProp(cur, (const xmlChar *)"name", XSLT_NAMESPACE);
- if (name == NULL) {
+ comp = (xsltStylePreCompPtr) cur->_private;
+ if (comp == NULL) {
xsltGenericError(xsltGenericErrorContext,
- "xsl:param : missing name attribute\n");
+ "xsl:param : compilation error\n");
return(NULL);
}
-#ifdef WITH_XSLT_DEBUG_VARIABLE
- xsltGenericDebug(xsltGenericDebugContext,
- "Parsing param %s\n", name);
-#endif
-
- select = xmlGetNsProp(cur, (const xmlChar *)"select", XSLT_NAMESPACE);
- if (select == NULL) {
- tree = cur->children;
- } else {
-#ifdef WITH_XSLT_DEBUG_VARIABLE
- xsltGenericDebug(xsltGenericDebugContext,
- " select %s\n", select);
-#endif
- if (cur->children != NULL)
- xsltGenericError(xsltGenericErrorContext,
- "xsl:param : content shuld be empty since select is present \n");
- }
-
- ncname = xmlSplitQName2(name, &prefix);
-
- if (ncname != NULL) {
- if (prefix != NULL) {
- xmlNsPtr ns;
-
- ns = xmlSearchNs(cur->doc, cur, prefix);
- if (ns == NULL) {
- xsltGenericError(xsltGenericErrorContext,
- "xsl:param : no namespace bound to prefix %s\n", prefix);
- } else {
- elem = xsltBuildVariable(ctxt, ncname, ns->href, select,
- tree, 1);
- }
- xmlFree(prefix);
- } else {
- elem = xsltBuildVariable(ctxt, ncname, NULL, select, tree, 1);
- }
- xmlFree(ncname);
- } else {
- elem = xsltBuildVariable(ctxt, name, NULL, select, tree, 1);
- }
-
- xmlFree(name);
- if (select != NULL)
- xmlFree(select);
- return(elem);
-}
-
-/**
- * xsltParseStylesheetParam:
- * @ctxt: the XSLT transformation context
- * @cur: the "param" element
- *
- * parse an XSLT transformation param declaration and record
- * its value.
- */
-
-void
-xsltParseStylesheetParam(xsltTransformContextPtr ctxt, xmlNodePtr cur) {
- xmlChar *name, *ncname, *prefix;
- xmlChar *select;
- xmlNodePtr tree = NULL;
-
- if ((cur == NULL) || (ctxt == NULL))
- return;
-
- name = xmlGetNsProp(cur, (const xmlChar *)"name", XSLT_NAMESPACE);
- if (name == NULL) {
+ if (comp->name == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsl:param : missing name attribute\n");
- return;
+ return(NULL);
}
-
#ifdef WITH_XSLT_DEBUG_VARIABLE
xsltGenericDebug(xsltGenericDebugContext,
- "Parsing param %s\n", name);
+ "Handling param %s\n", comp->name);
#endif
- select = xmlGetNsProp(cur, (const xmlChar *)"select", XSLT_NAMESPACE);
- if (select == NULL) {
+
+ if (comp->select == NULL) {
tree = cur->children;
} else {
#ifdef WITH_XSLT_DEBUG_VARIABLE
xsltGenericDebug(xsltGenericDebugContext,
- " select %s\n", select);
+ " select %s\n", comp->select);
#endif
- if (cur->children != NULL)
- xsltGenericError(xsltGenericErrorContext,
- "xsl:param : content shuld be empty since select is present \n");
+ tree = cur;
}
- ncname = xmlSplitQName2(name, &prefix);
-
- if (ncname != NULL) {
- if (prefix != NULL) {
- xmlNsPtr ns;
-
- ns = xmlSearchNs(cur->doc, cur, prefix);
- if (ns == NULL) {
- xsltGenericError(xsltGenericErrorContext,
- "xsl:param : no namespace bound to prefix %s\n", prefix);
- } else {
- xsltRegisterVariable(ctxt, ncname, ns->href, select, tree, 1);
- }
- xmlFree(prefix);
- } else {
- xsltRegisterVariable(ctxt, ncname, NULL, select, tree, 1);
- }
- xmlFree(ncname);
- } else {
- xsltRegisterVariable(ctxt, name, NULL, select, tree, 1);
- }
-
- xmlFree(name);
- if (select != NULL)
- xmlFree(select);
+ elem = xsltBuildVariable(ctxt, comp, tree, 1);
+ return(elem);
}
/**
@@ -828,15 +735,20 @@ xsltParseStylesheetParam(xsltTransformContextPtr ctxt, xmlNodePtr cur) {
void
xsltParseGlobalVariable(xsltStylesheetPtr style, xmlNodePtr cur) {
- xmlChar *name, *ncname, *prefix;
- xmlChar *select;
- xmlNodePtr tree = NULL;
+ xsltStylePreCompPtr comp;
if ((cur == NULL) || (style == NULL))
return;
- name = xmlGetNsProp(cur, (const xmlChar *)"name", XSLT_NAMESPACE);
- if (name == NULL) {
+ xsltStylePreCompute(style, cur);
+ comp = (xsltStylePreCompPtr) cur->_private;
+ if (comp == NULL) {
+ xsltGenericError(xsltGenericErrorContext,
+ "xsl:variable : compilation had failed\n");
+ return;
+ }
+
+ if (comp->name == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsl:variable : missing name attribute\n");
return;
@@ -844,46 +756,11 @@ xsltParseGlobalVariable(xsltStylesheetPtr style, xmlNodePtr cur) {
#ifdef WITH_XSLT_DEBUG_VARIABLE
xsltGenericDebug(xsltGenericDebugContext,
- "Parsing global variable %s\n", name);
+ "Registering global variable %s\n", comp->name);
#endif
- select = xmlGetNsProp(cur, (const xmlChar *)"select", XSLT_NAMESPACE);
- if (select == NULL) {
- tree = cur->children;
- } else {
- if (cur->children != NULL)
- xsltGenericError(xsltGenericErrorContext,
- "xsl:variable : content shuld be empty since select is present \n");
- }
-
- ncname = xmlSplitQName2(name, &prefix);
-
- if (ncname != NULL) {
- if (prefix != NULL) {
- xmlNsPtr ns;
-
- ns = xmlSearchNs(cur->doc, cur, prefix);
- if (ns == NULL) {
- xsltGenericError(xsltGenericErrorContext,
- "xsl:variable : no namespace bound to prefix %s\n", prefix);
- } else {
- xsltRegisterGlobalVariable(style, ncname, ns->href, select,
- tree, 0, NULL);
- }
- xmlFree(prefix);
- } else {
- xsltRegisterGlobalVariable(style, ncname, NULL, select, tree,
- 0, NULL);
- }
- xmlFree(ncname);
- } else {
- xsltRegisterGlobalVariable(style, name, NULL, select, tree, 0, NULL);
- }
-
- xmlFree(name);
- if (select != NULL)
- xmlFree(select);
-
+ xsltRegisterGlobalVariable(style, comp->name, comp->ns, comp->select,
+ cur->children, 0, NULL);
}
/**
@@ -897,15 +774,20 @@ xsltParseGlobalVariable(xsltStylesheetPtr style, xmlNodePtr cur) {
void
xsltParseGlobalParam(xsltStylesheetPtr style, xmlNodePtr cur) {
- xmlChar *name, *ncname, *prefix;
- xmlChar *select;
- xmlNodePtr tree = NULL;
+ xsltStylePreCompPtr comp;
if ((cur == NULL) || (style == NULL))
return;
- name = xmlGetNsProp(cur, (const xmlChar *)"name", XSLT_NAMESPACE);
- if (name == NULL) {
+ xsltStylePreCompute(style, cur);
+ comp = (xsltStylePreCompPtr) cur->_private;
+ if (comp == NULL) {
+ xsltGenericError(xsltGenericErrorContext,
+ "xsl:param : compilation had failed\n");
+ return;
+ }
+
+ if (comp->name == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsl:param : missing name attribute\n");
return;
@@ -913,45 +795,11 @@ xsltParseGlobalParam(xsltStylesheetPtr style, xmlNodePtr cur) {
#ifdef WITH_XSLT_DEBUG_VARIABLE
xsltGenericDebug(xsltGenericDebugContext,
- "Parsing global param %s\n", name);
+ "Registering global param %s\n", comp->name);
#endif
- select = xmlGetNsProp(cur, (const xmlChar *)"select", XSLT_NAMESPACE);
- if (select == NULL) {
- tree = cur->children;
- } else {
- if (cur->children != NULL)
- xsltGenericError(xsltGenericErrorContext,
- "xsl:param : content shuld be empty since select is present \n");
- }
-
- ncname = xmlSplitQName2(name, &prefix);
-
- if (ncname != NULL) {
- if (prefix != NULL) {
- xmlNsPtr ns;
-
- ns = xmlSearchNs(cur->doc, cur, prefix);
- if (ns == NULL) {
- xsltGenericError(xsltGenericErrorContext,
- "xsl:param : no namespace bound to prefix %s\n", prefix);
- } else {
- xsltRegisterGlobalVariable(style, ncname, ns->href, select,
- tree, 1, NULL);
- }
- xmlFree(prefix);
- } else {
- xsltRegisterGlobalVariable(style, ncname, NULL, select, tree,
- 1, NULL);
- }
- xmlFree(ncname);
- } else {
- xsltRegisterGlobalVariable(style, name, NULL, select, tree, 1, NULL);
- }
-
- xmlFree(name);
- if (select != NULL)
- xmlFree(select);
+ xsltRegisterGlobalVariable(style, comp->name, comp->ns, comp->select,
+ cur->children, 1, NULL);
}
/**
@@ -965,15 +813,19 @@ xsltParseGlobalParam(xsltStylesheetPtr style, xmlNodePtr cur) {
void
xsltParseStylesheetVariable(xsltTransformContextPtr ctxt, xmlNodePtr cur) {
- xmlChar *name, *ncname, *prefix;
- xmlChar *select;
- xmlNodePtr tree = NULL;
+ xsltStylePreCompPtr comp;
if ((cur == NULL) || (ctxt == NULL))
return;
- name = xmlGetNsProp(cur, (const xmlChar *)"name", XSLT_NAMESPACE);
- if (name == NULL) {
+ comp = (xsltStylePreCompPtr) cur->_private;
+ if (comp == NULL) {
+ xsltGenericError(xsltGenericErrorContext,
+ "xsl:variable : compilation had failed\n");
+ return;
+ }
+
+ if (comp->name == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsl:variable : missing name attribute\n");
return;
@@ -981,44 +833,47 @@ xsltParseStylesheetVariable(xsltTransformContextPtr ctxt, xmlNodePtr cur) {
#ifdef WITH_XSLT_DEBUG_VARIABLE
xsltGenericDebug(xsltGenericDebugContext,
- "Parsing variable %s\n", name);
+ "Registering variable %s\n", comp->name);
#endif
- select = xmlGetNsProp(cur, (const xmlChar *)"select", XSLT_NAMESPACE);
- if (select == NULL) {
- tree = cur->children;
- } else {
- if (cur->children != NULL)
- xsltGenericError(xsltGenericErrorContext,
- "xsl:variable : content should be empty since select is present \n");
- }
+ xsltRegisterVariable(ctxt, comp, cur->children, 0);
+}
+
+/**
+ * xsltParseStylesheetParam:
+ * @ctxt: the XSLT transformation context
+ * @cur: the "param" element
+ *
+ * parse an XSLT transformation param declaration and record
+ * its value.
+ */
- ncname = xmlSplitQName2(name, &prefix);
+void
+xsltParseStylesheetParam(xsltTransformContextPtr ctxt, xmlNodePtr cur) {
+ xsltStylePreCompPtr comp;
- if (ncname != NULL) {
- if (prefix != NULL) {
- xmlNsPtr ns;
+ if ((cur == NULL) || (ctxt == NULL))
+ return;
- ns = xmlSearchNs(cur->doc, cur, prefix);
- if (ns == NULL) {
- xsltGenericError(xsltGenericErrorContext,
- "xsl:variable : no namespace bound to prefix %s\n", prefix);
- } else {
- xsltRegisterVariable(ctxt, ncname, ns->href, select, tree, 0);
- }
- xmlFree(prefix);
- } else {
- xsltRegisterVariable(ctxt, ncname, NULL, select, tree, 0);
- }
- xmlFree(ncname);
- } else {
- xsltRegisterVariable(ctxt, name, NULL, select, tree, 0);
+ comp = (xsltStylePreCompPtr) cur->_private;
+ if (comp == NULL) {
+ xsltGenericError(xsltGenericErrorContext,
+ "xsl:param : compilation had failed\n");
+ return;
}
- xmlFree(name);
- if (select != NULL)
- xmlFree(select);
+ if (comp->name == NULL) {
+ xsltGenericError(xsltGenericErrorContext,
+ "xsl:param : missing name attribute\n");
+ return;
+ }
+
+#ifdef WITH_XSLT_DEBUG_VARIABLE
+ xsltGenericDebug(xsltGenericDebugContext,
+ "Registering param %s\n", comp->name);
+#endif
+ xsltRegisterVariable(ctxt, comp, cur->children, 1);
}
/**
diff --git a/libxslt/variables.h b/libxslt/variables.h
index 17f6576a..f9eb792c 100644
--- a/libxslt/variables.h
+++ b/libxslt/variables.h
@@ -54,12 +54,6 @@ void xsltFreeVariableHashes (xsltTransformContextPtr ctxt);
xmlXPathObjectPtr xsltVariableLookup (xsltTransformContextPtr ctxt,
const xmlChar *name,
const xmlChar *ns_uri);
-int xsltRegisterVariable (xsltTransformContextPtr ctxt,
- const xmlChar *name,
- const xmlChar *ns_uri,
- const xmlChar *select,
- xmlNodePtr tree,
- int param);
xmlXPathObjectPtr xsltXPathVariableLookup (void *ctxt,
const xmlChar *name,
const xmlChar *ns_uri);
diff --git a/libxslt/xslt.c b/libxslt/xslt.c
index 00114c0a..b8237ece 100644
--- a/libxslt/xslt.c
+++ b/libxslt/xslt.c
@@ -32,6 +32,7 @@
#include "keys.h"
#include "documents.h"
#include "extensions.h"
+#include "preproc.h"
#ifdef WITH_XSLT_DEBUG
#define WITH_XSLT_DEBUG_PARSING
@@ -293,6 +294,7 @@ xsltFreeStylesheet(xsltStylesheetPtr sheet) {
xsltFreeAttributeSetsHashes(sheet);
xsltFreeNamespaceAliasHashes(sheet);
xsltFreeStyleDocuments(sheet);
+ xsltFreeStylePreComps(sheet);
if (sheet->doc != NULL)
xmlFreeDoc(sheet->doc);
if (sheet->variables != NULL)
@@ -751,14 +753,16 @@ xsltParseStylesheetStripSpace(xsltStylesheetPtr style, xmlNodePtr cur) {
}
/**
- * xsltParseRemoveBlanks:
+ * xsltPrecomputeStylesheet:
* @style: the XSLT stylesheet
*
* Clean-up the stylesheet content from unwanted ignorable blank nodes
+ * and run the preprocessing of all XSLT constructs.
+ *
* and process xslt:text
*/
static void
-xsltParseRemoveBlanks(xsltStylesheetPtr style) {
+xsltPrecomputeStylesheet(xsltStylesheetPtr style) {
xmlNodePtr cur, delete;
/*
@@ -775,13 +779,14 @@ xsltParseRemoveBlanks(xsltStylesheetPtr style) {
if (delete != NULL) {
#ifdef WITH_XSLT_DEBUG_BLANKS
xsltGenericDebug(xsltGenericDebugContext,
- "xsltParseRemoveBlanks: removing ignorable blank node\n");
+ "xsltPrecomputeStylesheet: removing ignorable blank node\n");
#endif
xmlUnlinkNode(delete);
xmlFreeNode(delete);
delete = NULL;
}
if ((cur->type == XML_ELEMENT_NODE) && (IS_XSLT_ELEM(cur))) {
+ xsltStylePreCompute(style, cur);
if (IS_XSLT_NAME(cur, "text")) {
goto skip_children;
}
@@ -830,7 +835,7 @@ skip_children:
if (delete != NULL) {
#ifdef WITH_XSLT_DEBUG_PARSING
xsltGenericDebug(xsltGenericDebugContext,
- "xsltParseRemoveBlanks: removing ignorable blank node\n");
+ "xsltPrecomputeStylesheet: removing ignorable blank node\n");
#endif
xmlUnlinkNode(delete);
xmlFreeNode(delete);
@@ -991,9 +996,9 @@ xsltParseTemplateContent(xsltStylesheetPtr style, xsltTemplatePtr ret,
} else if ((cur->ns != NULL) && (style->nsDefs != NULL)) {
if (xsltCheckExtPrefix(style, cur->ns->prefix)) {
/*
- * Mark the element as being 'special'
+ * okay this is an extension element compile it too
*/
- cur->_private = (void *) xsltExtMarker;
+ xsltStylePreCompute(style, cur);
}
}
@@ -1431,7 +1436,7 @@ xsltParseStylesheetProcess(xsltStylesheetPtr ret, xmlDocPtr doc) {
return(NULL);
}
- xsltParseRemoveBlanks(ret);
+ xsltPrecomputeStylesheet(ret);
if ((IS_XSLT_ELEM(cur)) &&
((IS_XSLT_NAME(cur, "stylesheet")) ||
(IS_XSLT_NAME(cur, "transform")))) {
diff --git a/libxslt/xsltInternals.h b/libxslt/xsltInternals.h
index 9b744ae4..b2839f6b 100644
--- a/libxslt/xsltInternals.h
+++ b/libxslt/xsltInternals.h
@@ -39,7 +39,7 @@ struct _xsltStackElem {
xmlChar *name; /* the local part of the name QName */
xmlChar *nameURI; /* the URI part of the name QName */
xmlChar *select; /* the eval string */
- xmlNodePtr tree; /* the tree if no eval string */
+ xmlNodePtr tree; /* the tree if no eval string or the location */
xmlXPathObjectPtr value; /* The value if computed */
};
@@ -98,6 +98,92 @@ struct _xsltDocument {
};
/*
+ * The in-memory structure corresponding to XSLT stylesheet constructs
+ * precomputed data.
+ */
+
+typedef struct _xsltTransformContext xsltTransformContext;
+typedef xsltTransformContext *xsltTransformContextPtr;
+
+typedef struct _xsltStylePreComp xsltStylePreComp;
+typedef xsltStylePreComp *xsltStylePreCompPtr;
+
+typedef void (*xsltTransformFunction) (xsltTransformContextPtr ctxt,
+ xmlNodePtr node, xmlNodePtr inst,
+ xsltStylePreCompPtr comp);
+
+typedef enum {
+ XSLT_FUNC_COPY=1,
+ XSLT_FUNC_SORT,
+ XSLT_FUNC_TEXT,
+ XSLT_FUNC_ELEMENT,
+ XSLT_FUNC_ATTRIBUTE,
+ XSLT_FUNC_COMMENT,
+ XSLT_FUNC_PI,
+ XSLT_FUNC_COPYOF,
+ XSLT_FUNC_VALUEOF,
+ XSLT_FUNC_NUMBER,
+ XSLT_FUNC_APPLYIMPORTS,
+ XSLT_FUNC_CALLTEMPLATE,
+ XSLT_FUNC_APPLYTEMPLATES,
+ XSLT_FUNC_CHOOSE,
+ XSLT_FUNC_IF,
+ XSLT_FUNC_FOREACH,
+ XSLT_FUNC_DOCUMENT,
+ XSLT_FUNC_WITHPARAM,
+ XSLT_FUNC_PARAM,
+ XSLT_FUNC_VARIABLE,
+ XSLT_FUNC_WHEN
+} xsltStyleType;
+
+struct _xsltStylePreComp {
+ struct _xsltStylePreComp *next;/* chained list */
+ xsltStyleType type; /* type of the element */
+ xsltTransformFunction func; /* handling function */
+ xmlNodePtr inst; /* the instruction */
+
+ /*
+ * Pre computed values
+ */
+
+ xmlChar *stype; /* sort */
+ int has_stype; /* sort */
+ int number; /* sort */
+ xmlChar *order; /* sort */
+ int has_order; /* sort */
+ int descending; /* sort */
+
+ xmlChar *use; /* copy, element */
+ int has_use; /* copy, element */
+
+ int noescape; /* text */
+
+ xmlChar *name; /* element, attribute, pi */
+ int has_name; /* element, attribute, pi */
+ xmlChar *ns; /* element */
+ int has_ns; /* element */
+
+ xmlChar *mode; /* apply-templates */
+ xmlChar *modeURI; /* apply-templates */
+
+ xmlChar *test; /* if */
+
+ xsltTemplatePtr templ; /* call-template */
+
+ xmlChar *select; /* sort, copy-of, value-of, apply-templates */
+
+ int ver11; /* document */
+ xmlChar *filename; /* document URL */
+ int has_filename; /* document */
+
+ xsltNumberData numdata; /* number */
+
+ xmlXPathCompExprPtr comp; /* a precompiled XPath expression */
+ xmlNsPtr *nsList; /* the namespaces in scope */
+ int nsNr; /* the number of namespaces in scope */
+};
+
+/*
* The in-memory structure corresponding to an XSLT Stylesheet
* NOTE: most of the content is simply linked from the doc tree
* structure, no specific allocation is made.
@@ -179,89 +265,11 @@ struct _xsltStylesheet {
xmlChar *doctypeSystem; /* doctype-system string */
int indent; /* should output being indented */
xmlChar *mediaType; /* media-type string */
-};
-
-
-/*
- * The in-memory structure corresponding to XSLT stylesheet constructs
- * precomputed data.
- */
-
-typedef struct _xsltTransformContext xsltTransformContext;
-typedef xsltTransformContext *xsltTransformContextPtr;
-
-typedef struct _xsltStylePreComp xsltStylePreComp;
-typedef xsltStylePreComp *xsltStylePreCompPtr;
-
-typedef void (*xsltTransformFunction) (xsltTransformContextPtr ctxt,
- xmlNodePtr node, xmlNodePtr inst,
- xsltStylePreCompPtr comp);
-
-typedef enum {
- XSLT_FUNC_COPY=1,
- XSLT_FUNC_SORT,
- XSLT_FUNC_TEXT,
- XSLT_FUNC_ELEMENT,
- XSLT_FUNC_ATTRIBUTE,
- XSLT_FUNC_COMMENT,
- XSLT_FUNC_PI,
- XSLT_FUNC_COPYOF,
- XSLT_FUNC_VALUEOF,
- XSLT_FUNC_NUMBER,
- XSLT_FUNC_APPLYIMPORTS,
- XSLT_FUNC_CALLTEMPLATE,
- XSLT_FUNC_APPLYTEMPLATES,
- XSLT_FUNC_CHOOSE,
- XSLT_FUNC_IF,
- XSLT_FUNC_FOREACH,
- XSLT_FUNC_DOCUMENT
-} xsltStyleType;
-
-struct _xsltStylePreComp {
- struct _xsltStylePreComp *next;/* chained list */
- xsltStyleType type; /* type of the element */
- xsltTransformFunction func; /* handling function */
- xmlNodePtr inst; /* the instruction */
/*
- * Pre computed values
+ * Precomputed blocks
*/
-
- xmlChar *stype; /* sort */
- int has_stype; /* sort */
- int number; /* sort */
- xmlChar *order; /* sort */
- int has_order; /* sort */
- int descending; /* sort */
-
- xmlChar *use; /* copy, element */
- int has_use; /* copy, element */
-
- int noescape; /* text */
-
- xmlChar *name; /* element, attribute, pi */
- int has_name; /* element, attribute, pi */
- xmlChar *ns; /* element */
- int has_ns; /* element */
-
- xmlChar *mode; /* apply-templates */
- xmlChar *modeURI; /* apply-templates */
-
- xmlChar *test; /* if */
-
- xsltTemplatePtr templ; /* call-template */
-
- xmlChar *select; /* sort, copy-of, value-of, apply-templates */
-
- int ver11; /* document */
- xmlChar *filename; /* document URL */
- int has_filename; /* document */
-
- xsltNumberData numdata; /* number */
-
- xmlXPathCompExprPtr comp; /* a precompiled XPath expression */
- xmlNsPtr *nsList; /* the namespaces in scope */
- int nsNr; /* the number of namespaces in scope */
+ xsltStylePreCompPtr preComps; /* list of precomputed blocks */
};
/*
@@ -294,11 +302,6 @@ struct _xsltTransformContext {
xsltStackElemPtr *varsTab; /* the variable list stack */
/*
- * Precomputed blocks
- */
- xsltStylePreCompPtr preComps; /* list of precomputed blocks */
-
- /*
* Extensions
*/
xmlHashTablePtr extFunctions; /* the extension functions */