[libxslt] Helper functions to evaluate compiled XPath expressions



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]