[libxslt] Helper functions to evaluate compiled XPath expressions
- From: Nick Wellnhofer <nwellnhof src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libxslt] Helper functions to evaluate compiled XPath expressions
- Date: Sun, 15 Dec 2013 14:00:41 +0000 (UTC)
commit c618db4b74504c79c6fabb424bba8feb06a8ae1d
Author: Nick Wellnhofer <wellnhofer aevum de>
Date: Sun Dec 15 14:22:06 2013 +0100
Helper functions to evaluate compiled XPath expressions
Reduces code size in libxslt/transform.c and makes the code more
readable.
libxslt/transform.c | 348 +++++++++++++++------------------------------------
1 files changed, 99 insertions(+), 249 deletions(-)
---
diff --git a/libxslt/transform.c b/libxslt/transform.c
index 35701de..e68ee1d 100644
--- a/libxslt/transform.c
+++ b/libxslt/transform.c
@@ -338,6 +338,96 @@ profCallgraphAdd(xsltTemplatePtr templ, xsltTemplatePtr parent)
}
}
+/**
+ * xsltPreCompEval:
+ * @ctxt: transform context
+ * @node: context node
+ * @comp: precompiled expression
+ *
+ * Evaluate a precompiled XPath expression.
+ */
+static xmlXPathObjectPtr
+xsltPreCompEval(xsltTransformContextPtr ctxt, xmlNodePtr node,
+ xsltStylePreCompPtr comp) {
+ xmlXPathObjectPtr res;
+ xmlXPathContextPtr xpctxt;
+ xmlNodePtr oldXPContextNode;
+ xmlNsPtr *oldXPNamespaces;
+ int oldXPNsNr;
+
+ xpctxt = ctxt->xpathCtxt;
+ oldXPContextNode = xpctxt->node;
+ oldXPNsNr = xpctxt->nsNr;
+ oldXPNamespaces = xpctxt->namespaces;
+
+ xpctxt->node = node;
+#ifdef XSLT_REFACTORED
+ if (comp->inScopeNs != NULL) {
+ xpctxt->namespaces = comp->inScopeNs->list;
+ xpctxt->nsNr = comp->inScopeNs->xpathNumber;
+ } else {
+ xpctxt->namespaces = NULL;
+ xpctxt->nsNr = 0;
+ }
+#else
+ xpctxt->namespaces = comp->nsList;
+ xpctxt->nsNr = comp->nsNr;
+#endif
+
+ res = xmlXPathCompiledEval(comp->comp, xpctxt);
+
+ xpctxt->node = oldXPContextNode;
+ xpctxt->nsNr = oldXPNsNr;
+ xpctxt->namespaces = oldXPNamespaces;
+
+ return(res);
+}
+
+/**
+ * xsltPreCompEvalToBoolean:
+ * @ctxt: transform context
+ * @node: context node
+ * @comp: precompiled expression
+ *
+ * Evaluate a precompiled XPath expression as boolean.
+ */
+static int
+xsltPreCompEvalToBoolean(xsltTransformContextPtr ctxt, xmlNodePtr node,
+ xsltStylePreCompPtr comp) {
+ int res;
+ xmlXPathContextPtr xpctxt;
+ xmlNodePtr oldXPContextNode;
+ xmlNsPtr *oldXPNamespaces;
+ int oldXPNsNr;
+
+ xpctxt = ctxt->xpathCtxt;
+ oldXPContextNode = xpctxt->node;
+ oldXPNsNr = xpctxt->nsNr;
+ oldXPNamespaces = xpctxt->namespaces;
+
+ xpctxt->node = node;
+#ifdef XSLT_REFACTORED
+ if (comp->inScopeNs != NULL) {
+ xpctxt->namespaces = comp->inScopeNs->list;
+ xpctxt->nsNr = comp->inScopeNs->xpathNumber;
+ } else {
+ xpctxt->namespaces = NULL;
+ xpctxt->nsNr = 0;
+ }
+#else
+ xpctxt->namespaces = comp->nsList;
+ xpctxt->nsNr = comp->nsNr;
+#endif
+
+ res = xmlXPathCompiledEvalToBoolean(comp->comp, xpctxt);
+
+ xpctxt->node = oldXPContextNode;
+ xpctxt->nsNr = oldXPNsNr;
+ xpctxt->namespaces = oldXPNamespaces;
+
+ return(res);
+}
+
/************************************************************************
* *
* XInclude default settings *
@@ -4287,11 +4377,6 @@ xsltCopyOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlXPathObjectPtr res = NULL;
xmlNodeSetPtr list = NULL;
int i;
- xmlDocPtr oldXPContextDoc;
- xmlNsPtr *oldXPNamespaces;
- xmlNodePtr oldXPContextNode;
- int oldXPProximityPosition, oldXPContextSize, oldXPNsNr;
- xmlXPathContextPtr xpctxt;
if ((ctxt == NULL) || (node == NULL) || (inst == NULL))
return;
@@ -4327,42 +4412,7 @@ xsltCopyOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
/*
* Evaluate the "select" expression.
*/
- xpctxt = ctxt->xpathCtxt;
- oldXPContextDoc = xpctxt->doc;
- oldXPContextNode = xpctxt->node;
- oldXPProximityPosition = xpctxt->proximityPosition;
- oldXPContextSize = xpctxt->contextSize;
- oldXPNsNr = xpctxt->nsNr;
- oldXPNamespaces = xpctxt->namespaces;
-
- xpctxt->node = node;
- if (comp != NULL) {
-
-#ifdef XSLT_REFACTORED
- if (comp->inScopeNs != NULL) {
- xpctxt->namespaces = comp->inScopeNs->list;
- xpctxt->nsNr = comp->inScopeNs->xpathNumber;
- } else {
- xpctxt->namespaces = NULL;
- xpctxt->nsNr = 0;
- }
-#else
- xpctxt->namespaces = comp->nsList;
- xpctxt->nsNr = comp->nsNr;
-#endif
- } else {
- xpctxt->namespaces = NULL;
- xpctxt->nsNr = 0;
- }
-
- res = xmlXPathCompiledEval(comp->comp, xpctxt);
-
- xpctxt->doc = oldXPContextDoc;
- xpctxt->node = oldXPContextNode;
- xpctxt->contextSize = oldXPContextSize;
- xpctxt->proximityPosition = oldXPProximityPosition;
- xpctxt->nsNr = oldXPNsNr;
- xpctxt->namespaces = oldXPNamespaces;
+ res = xsltPreCompEval(ctxt, node, comp);
if (res != NULL) {
if (res->type == XPATH_NODESET) {
@@ -4472,11 +4522,6 @@ xsltValueOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
#endif
xmlXPathObjectPtr res = NULL;
xmlChar *value = NULL;
- xmlDocPtr oldXPContextDoc;
- xmlNsPtr *oldXPNamespaces;
- xmlNodePtr oldXPContextNode;
- int oldXPProximityPosition, oldXPContextSize, oldXPNsNr;
- xmlXPathContextPtr xpctxt;
if ((ctxt == NULL) || (node == NULL) || (inst == NULL))
return;
@@ -4493,42 +4538,7 @@ xsltValueOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
"xsltValueOf: select %s\n", comp->select));
#endif
- xpctxt = ctxt->xpathCtxt;
- oldXPContextDoc = xpctxt->doc;
- oldXPContextNode = xpctxt->node;
- oldXPProximityPosition = xpctxt->proximityPosition;
- oldXPContextSize = xpctxt->contextSize;
- oldXPNsNr = xpctxt->nsNr;
- oldXPNamespaces = xpctxt->namespaces;
-
- xpctxt->node = node;
- if (comp != NULL) {
-
-#ifdef XSLT_REFACTORED
- if (comp->inScopeNs != NULL) {
- xpctxt->namespaces = comp->inScopeNs->list;
- xpctxt->nsNr = comp->inScopeNs->xpathNumber;
- } else {
- xpctxt->namespaces = NULL;
- xpctxt->nsNr = 0;
- }
-#else
- xpctxt->namespaces = comp->nsList;
- xpctxt->nsNr = comp->nsNr;
-#endif
- } else {
- xpctxt->namespaces = NULL;
- xpctxt->nsNr = 0;
- }
-
- res = xmlXPathCompiledEval(comp->comp, xpctxt);
-
- xpctxt->doc = oldXPContextDoc;
- xpctxt->node = oldXPContextNode;
- xpctxt->contextSize = oldXPContextSize;
- xpctxt->proximityPosition = oldXPProximityPosition;
- xpctxt->nsNr = oldXPNsNr;
- xpctxt->namespaces = oldXPNamespaces;
+ res = xsltPreCompEval(ctxt, node, comp);
/*
* Cast the XPath object to string.
@@ -4790,12 +4800,11 @@ xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlNodePtr cur, delNode = NULL, oldContextNode;
xmlNodeSetPtr list = NULL, oldList;
xsltStackElemPtr withParams = NULL;
- int oldXPProximityPosition, oldXPContextSize, oldXPNsNr;
+ int oldXPProximityPosition, oldXPContextSize;
const xmlChar *oldMode, *oldModeURI;
xmlDocPtr oldXPDoc;
xsltDocumentPtr oldDocInfo;
xmlXPathContextPtr xpctxt;
- xmlNsPtr *oldXPNamespaces;
if (comp == NULL) {
xsltTransformError(ctxt, NULL, inst,
@@ -4829,8 +4838,6 @@ xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node,
oldXPContextSize = xpctxt->contextSize;
oldXPProximityPosition = xpctxt->proximityPosition;
oldXPDoc = xpctxt->doc;
- oldXPNsNr = xpctxt->nsNr;
- oldXPNamespaces = xpctxt->namespaces;
/*
* Set up contexts.
@@ -4851,26 +4858,8 @@ xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node,
"xsltApplyTemplates: select %s\n", comp->select));
#endif
- /*
- * Set up XPath.
- */
- xpctxt->node = node; /* Set the "context node" */
-#ifdef XSLT_REFACTORED
- if (comp->inScopeNs != NULL) {
- xpctxt->namespaces = comp->inScopeNs->list;
- xpctxt->nsNr = comp->inScopeNs->xpathNumber;
- } else {
- xpctxt->namespaces = NULL;
- xpctxt->nsNr = 0;
- }
-#else
- xpctxt->namespaces = comp->nsList;
- xpctxt->nsNr = comp->nsNr;
-#endif
- res = xmlXPathCompiledEval(comp->comp, xpctxt);
+ res = xsltPreCompEval(ctxt, node, comp);
- xpctxt->contextSize = oldXPContextSize;
- xpctxt->proximityPosition = oldXPProximityPosition;
if (res != NULL) {
if (res->type == XPATH_NODESET) {
list = res->nodesetval; /* consume the node set */
@@ -5153,8 +5142,6 @@ error:
/*
* Restore context states.
*/
- xpctxt->nsNr = oldXPNsNr;
- xpctxt->namespaces = oldXPNamespaces;
xpctxt->doc = oldXPDoc;
xpctxt->contextSize = oldXPContextSize;
xpctxt->proximityPosition = oldXPProximityPosition;
@@ -5210,12 +5197,6 @@ xsltChoose(xsltTransformContextPtr ctxt, xmlNodePtr contextNode,
{
int testRes = 0, res = 0;
- xmlXPathContextPtr xpctxt = ctxt->xpathCtxt;
- xmlDocPtr oldXPContextDoc = xpctxt->doc;
- int oldXPProximityPosition = xpctxt->proximityPosition;
- int oldXPContextSize = xpctxt->contextSize;
- xmlNsPtr *oldXPNamespaces = xpctxt->namespaces;
- int oldXPNsNr = xpctxt->nsNr;
#ifdef XSLT_REFACTORED
xsltStyleItemWhenPtr wcomp = NULL;
@@ -5252,27 +5233,8 @@ xsltChoose(xsltTransformContextPtr ctxt, xmlNodePtr contextNode,
"xsltChoose: test %s\n", wcomp->test));
#endif
- xpctxt->node = contextNode;
- xpctxt->doc = oldXPContextDoc;
- xpctxt->proximityPosition = oldXPProximityPosition;
- xpctxt->contextSize = oldXPContextSize;
-
-#ifdef XSLT_REFACTORED
- if (wcomp->inScopeNs != NULL) {
- xpctxt->namespaces = wcomp->inScopeNs->list;
- xpctxt->nsNr = wcomp->inScopeNs->xpathNumber;
- } else {
- xpctxt->namespaces = NULL;
- xpctxt->nsNr = 0;
- }
-#else
- xpctxt->namespaces = wcomp->nsList;
- xpctxt->nsNr = wcomp->nsNr;
-#endif
-
-
#ifdef XSLT_FAST_IF
- res = xmlXPathCompiledEvalToBoolean(wcomp->comp, xpctxt);
+ res = xsltPreCompEvalToBoolean(ctxt, contextNode, wcomp);
if (res == -1) {
ctxt->state = XSLT_STATE_STOPPED;
@@ -5282,7 +5244,7 @@ xsltChoose(xsltTransformContextPtr ctxt, xmlNodePtr contextNode,
#else /* XSLT_FAST_IF */
- res = xmlXPathCompiledEval(wcomp->comp, xpctxt);
+ res = xsltPreCompEval(ctxt, cotextNode, wcomp);
if (res != NULL) {
if (res->type != XPATH_BOOLEAN)
@@ -5331,22 +5293,10 @@ xsltChoose(xsltTransformContextPtr ctxt, xmlNodePtr contextNode,
#endif
goto test_is_true;
}
- xpctxt->node = contextNode;
- xpctxt->doc = oldXPContextDoc;
- xpctxt->proximityPosition = oldXPProximityPosition;
- xpctxt->contextSize = oldXPContextSize;
- xpctxt->namespaces = oldXPNamespaces;
- xpctxt->nsNr = oldXPNsNr;
goto exit;
test_is_true:
- xpctxt->node = contextNode;
- xpctxt->doc = oldXPContextDoc;
- xpctxt->proximityPosition = oldXPProximityPosition;
- xpctxt->contextSize = oldXPContextSize;
- xpctxt->namespaces = oldXPNamespaces;
- xpctxt->nsNr = oldXPNsNr;
goto process_sequence;
}
@@ -5400,38 +5350,9 @@ xsltIf(xsltTransformContextPtr ctxt, xmlNodePtr contextNode,
#ifdef XSLT_FAST_IF
{
- xmlXPathContextPtr xpctxt = ctxt->xpathCtxt;
- xmlDocPtr oldXPContextDoc = xpctxt->doc;
- xmlNsPtr *oldXPNamespaces = xpctxt->namespaces;
- xmlNodePtr oldXPContextNode = xpctxt->node;
- int oldXPProximityPosition = xpctxt->proximityPosition;
- int oldXPContextSize = xpctxt->contextSize;
- int oldXPNsNr = xpctxt->nsNr;
xmlDocPtr oldLocalFragmentTop = ctxt->localRVT;
- xpctxt->node = contextNode;
- if (comp != NULL) {
-
-#ifdef XSLT_REFACTORED
- if (comp->inScopeNs != NULL) {
- xpctxt->namespaces = comp->inScopeNs->list;
- xpctxt->nsNr = comp->inScopeNs->xpathNumber;
- } else {
- xpctxt->namespaces = NULL;
- xpctxt->nsNr = 0;
- }
-#else
- xpctxt->namespaces = comp->nsList;
- xpctxt->nsNr = comp->nsNr;
-#endif
- } else {
- xpctxt->namespaces = NULL;
- xpctxt->nsNr = 0;
- }
- /*
- * This XPath function is optimized for boolean results.
- */
- res = xmlXPathCompiledEvalToBoolean(comp->comp, xpctxt);
+ res = xsltPreCompEvalToBoolean(ctxt, contextNode, comp);
/*
* Cleanup fragments created during evaluation of the
@@ -5439,13 +5360,6 @@ xsltIf(xsltTransformContextPtr ctxt, xmlNodePtr contextNode,
*/
if (oldLocalFragmentTop != ctxt->localRVT)
xsltReleaseLocalRVTs(ctxt, oldLocalFragmentTop);
-
- xpctxt->doc = oldXPContextDoc;
- xpctxt->node = oldXPContextNode;
- xpctxt->contextSize = oldXPContextSize;
- xpctxt->proximityPosition = oldXPProximityPosition;
- xpctxt->nsNr = oldXPNsNr;
- xpctxt->namespaces = oldXPNamespaces;
}
#ifdef WITH_XSLT_DEBUG_PROCESS
@@ -5467,51 +5381,10 @@ xsltIf(xsltTransformContextPtr ctxt, xmlNodePtr contextNode,
#else /* XSLT_FAST_IF */
{
- xmlXPathObjectPtr xpobj = NULL;
/*
* OLD CODE:
*/
- {
- xmlXPathContextPtr xpctxt = ctxt->xpathCtxt;
- xmlDocPtr oldXPContextDoc = xpctxt->doc;
- xmlNsPtr *oldXPNamespaces = xpctxt->namespaces;
- xmlNodePtr oldXPContextNode = xpctxt->node;
- int oldXPProximityPosition = xpctxt->proximityPosition;
- int oldXPContextSize = xpctxt->contextSize;
- int oldXPNsNr = xpctxt->nsNr;
-
- xpctxt->node = contextNode;
- if (comp != NULL) {
-
-#ifdef XSLT_REFACTORED
- if (comp->inScopeNs != NULL) {
- xpctxt->namespaces = comp->inScopeNs->list;
- xpctxt->nsNr = comp->inScopeNs->xpathNumber;
- } else {
- xpctxt->namespaces = NULL;
- xpctxt->nsNr = 0;
- }
-#else
- xpctxt->namespaces = comp->nsList;
- xpctxt->nsNr = comp->nsNr;
-#endif
- } else {
- xpctxt->namespaces = NULL;
- xpctxt->nsNr = 0;
- }
-
- /*
- * This XPath function is optimized for boolean results.
- */
- xpobj = xmlXPathCompiledEval(comp->comp, xpctxt);
-
- xpctxt->doc = oldXPContextDoc;
- xpctxt->node = oldXPContextNode;
- xpctxt->contextSize = oldXPContextSize;
- xpctxt->proximityPosition = oldXPProximityPosition;
- xpctxt->nsNr = oldXPNsNr;
- xpctxt->namespaces = oldXPNamespaces;
- }
+ xmlXPathObjectPtr xpobj = xsltPreCompEval(ctxt, contextNode, comp);
if (xpobj != NULL) {
if (xpobj->type != XPATH_BOOLEAN)
xpobj = xmlXPathConvertBoolean(xpobj);
@@ -5618,27 +5491,11 @@ xsltForEach(xsltTransformContextPtr ctxt, xmlNodePtr contextNode,
oldXPDoc = xpctxt->doc;
oldXPProximityPosition = xpctxt->proximityPosition;
oldXPContextSize = xpctxt->contextSize;
- /*
- * Set up XPath.
- */
- xpctxt->node = contextNode;
-#ifdef XSLT_REFACTORED
- if (comp->inScopeNs != NULL) {
- xpctxt->namespaces = comp->inScopeNs->list;
- xpctxt->nsNr = comp->inScopeNs->xpathNumber;
- } else {
- xpctxt->namespaces = NULL;
- xpctxt->nsNr = 0;
- }
-#else
- xpctxt->namespaces = comp->nsList;
- xpctxt->nsNr = comp->nsNr;
-#endif
/*
* Evaluate the 'select' expression.
*/
- res = xmlXPathCompiledEval(comp->comp, ctxt->xpathCtxt);
+ res = xsltPreCompEval(ctxt, contextNode, comp);
if (res != NULL) {
if (res->type == XPATH_NODESET)
@@ -5669,13 +5526,6 @@ xsltForEach(xsltTransformContextPtr ctxt, xmlNodePtr contextNode,
#endif
/*
- * Restore XPath states for the "current node".
- */
- xpctxt->contextSize = oldXPContextSize;
- xpctxt->proximityPosition = oldXPProximityPosition;
- xpctxt->node = contextNode;
-
- /*
* Set the list; this has to be done already here for xsltDoSortFunction().
*/
ctxt->nodeList = list;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]