Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / reactos / dll / 3rdparty / libxslt / variables.c
diff --git a/reactos/dll/3rdparty/libxslt/variables.c b/reactos/dll/3rdparty/libxslt/variables.c
deleted file mode 100644 (file)
index fcd201d..0000000
+++ /dev/null
@@ -1,2314 +0,0 @@
-/*
- * variables.c: Implementation of the variable storage and lookup
- *
- * Reference:
- *   http://www.w3.org/TR/1999/REC-xslt-19991116
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-#include "precomp.h"
-
-#ifdef WITH_XSLT_DEBUG
- #define WITH_XSLT_DEBUG_VARIABLE
-#endif
-
-#ifdef XSLT_REFACTORED
-const xmlChar *xsltDocFragFake = (const xmlChar *) " fake node libxslt";
-#endif
-
-const xmlChar *xsltComputingGlobalVarMarker =
- (const xmlChar *) " var/param being computed";
-
-#define XSLT_VAR_GLOBAL 1<<0
-#define XSLT_VAR_IN_SELECT 1<<1
-#define XSLT_TCTXT_VARIABLE(c) ((xsltStackElemPtr) (c)->contextVariable)
-
-/************************************************************************
- *                                                                     *
- *  Result Value Tree (Result Tree Fragment) interfaces                        *
- *                                                                     *
- ************************************************************************/
-/**
- * xsltCreateRVT:
- * @ctxt:  an XSLT transformation context
- *
- * Creates a Result Value Tree
- * (the XSLT 1.0 term for this is "Result Tree Fragment")
- *
- * Returns the result value tree or NULL in case of API or internal errors.
- */
-xmlDocPtr
-xsltCreateRVT(xsltTransformContextPtr ctxt)
-{
-    xmlDocPtr container;
-
-    /*
-    * Question: Why is this function public?
-    * Answer: It is called by the EXSLT module.
-    */
-    if (ctxt == NULL)
-       return(NULL);
-
-    /*
-    * Reuse a RTF from the cache if available.
-    */
-    if (ctxt->cache->RVT) {
-       container = ctxt->cache->RVT;
-       ctxt->cache->RVT = (xmlDocPtr) container->next;
-       /* clear the internal pointers */
-       container->next = NULL;
-       container->prev = NULL;
-       if (ctxt->cache->nbRVT > 0)
-           ctxt->cache->nbRVT--;
-#ifdef XSLT_DEBUG_PROFILE_CACHE
-       ctxt->cache->dbgReusedRVTs++;
-#endif
-       return(container);
-    }
-
-    container = xmlNewDoc(NULL);
-    if (container == NULL)
-       return(NULL);
-    container->dict = ctxt->dict;
-    xmlDictReference(container->dict);
-    XSLT_MARK_RES_TREE_FRAG(container);
-    container->doc = container;
-    container->parent = NULL;
-    return(container);
-}
-
-/**
- * xsltRegisterTmpRVT:
- * @ctxt:  an XSLT transformation context
- * @RVT:  a result value tree (Result Tree Fragment)
- *
- * Registers the result value tree (XSLT 1.0 term: Result Tree Fragment)
- * in the garbage collector.
- * The fragment will be freed at the exit of the currently
- * instantiated xsl:template.
- * Obsolete; this function might produce massive memory overhead,
- * since the fragment is only freed when the current xsl:template
- * exits. Use xsltRegisterLocalRVT() instead.
- *
- * Returns 0 in case of success and -1 in case of API or internal errors.
- */
-int
-xsltRegisterTmpRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT)
-{
-    if ((ctxt == NULL) || (RVT == NULL))
-       return(-1);
-
-    /*
-    * We'll restrict the lifetime of user-created fragments
-    * insinde an xsl:variable and xsl:param to the lifetime of the
-    * var/param itself.
-    */
-    if (ctxt->contextVariable != NULL) {
-       RVT->next = (xmlNodePtr) XSLT_TCTXT_VARIABLE(ctxt)->fragment;
-       XSLT_TCTXT_VARIABLE(ctxt)->fragment = RVT;
-       return(0);
-    }
-
-    RVT->next = (xmlNodePtr) ctxt->tmpRVT;
-    if (ctxt->tmpRVT != NULL)
-       ctxt->tmpRVT->prev = (xmlNodePtr) RVT;
-    ctxt->tmpRVT = RVT;
-    return(0);
-}
-
-/**
- * xsltRegisterLocalRVT:
- * @ctxt:  an XSLT transformation context
- * @RVT:  a result value tree (Result Tree Fragment; xmlDocPtr)
- *
- * Registers a result value tree (XSLT 1.0 term: Result Tree Fragment)
- * in the RVT garbage collector.
- * The fragment will be freed when the instruction which created the
- * fragment exits.
- *
- * Returns 0 in case of success and -1 in case of API or internal errors.
- */
-int
-xsltRegisterLocalRVT(xsltTransformContextPtr ctxt,
-                    xmlDocPtr RVT)
-{
-    if ((ctxt == NULL) || (RVT == NULL))
-       return(-1);
-
-    /*
-    * When evaluating "select" expressions of xsl:variable
-    * and xsl:param, we need to bind newly created tree fragments
-    * to the variable itself; otherwise the tragment will be
-    * freed before we leave the scope of a var.
-    */
-    if ((ctxt->contextVariable != NULL) &&
-       (XSLT_TCTXT_VARIABLE(ctxt)->flags & XSLT_VAR_IN_SELECT))
-    {
-       RVT->next = (xmlNodePtr) XSLT_TCTXT_VARIABLE(ctxt)->fragment;
-       XSLT_TCTXT_VARIABLE(ctxt)->fragment = RVT;
-       return(0);
-    }
-    /*
-    * Store the fragment in the scope of the current instruction.
-    * If not reference by a returning instruction (like EXSLT's function),
-    * then this fragment will be freed, when the instruction exits.
-    */
-    RVT->next = (xmlNodePtr) ctxt->localRVT;
-    if (ctxt->localRVT != NULL)
-       ctxt->localRVT->prev = (xmlNodePtr) RVT;
-    ctxt->localRVT = RVT;
-    /*
-    * We need to keep track of the first registered fragment
-    * for extension instructions which return fragments
-    * (e.g. EXSLT'S function), in order to let
-    * xsltExtensionInstructionResultFinalize() clear the
-    * preserving flag on the fragments.
-    */
-    if (ctxt->localRVTBase == NULL)
-       ctxt->localRVTBase = RVT;
-    return(0);
-}
-
-/**
- * xsltExtensionInstructionResultFinalize:
- * @ctxt:  an XSLT transformation context
- *
- * Finalizes the data (e.g. result tree fragments) created
- * within a value-returning process (e.g. EXSLT's function).
- * Tree fragments marked as being returned by a function are
- * set to normal state, which means that the fragment garbage
- * collector will free them after the function-calling process exits.
- *
- * Returns 0 in case of success and -1 in case of API or internal errors.
- */
-int
-xsltExtensionInstructionResultFinalize(xsltTransformContextPtr ctxt)
-{
-    xmlDocPtr cur;
-
-    if (ctxt == NULL)
-       return(-1);
-    if (ctxt->localRVTBase == NULL)
-       return(0);
-    /*
-    * Enable remaining local tree fragments to be freed
-    * by the fragment garbage collector.
-    */
-    cur = ctxt->localRVTBase;
-    do {
-       cur->psvi = NULL;
-       cur = (xmlDocPtr) cur->next;
-    } while (cur != NULL);
-    return(0);
-}
-
-/**
- * xsltExtensionInstructionResultRegister:
- * @ctxt: an XSLT transformation context
- * @obj: an XPath object to be inspected for result tree fragments
- *
- * Marks the result of a value-returning extension instruction
- * in order to avoid it being garbage collected before the
- * extension instruction exits.
- * Note that one still has to additionally register any newly created
- * tree fragments (via xsltCreateRVT()) with xsltRegisterLocalRVT().
- *
- * Returns 0 in case of success and -1 in case of error.
- */
-int
-xsltExtensionInstructionResultRegister(xsltTransformContextPtr ctxt,
-                                      xmlXPathObjectPtr obj)
-{
-    int i;
-    xmlNodePtr cur;
-    xmlDocPtr doc;
-
-    if ((ctxt == NULL) || (obj == NULL))
-       return(-1);
-
-    /*
-    * OPTIMIZE TODO: If no local variables/params and no local tree
-    * fragments were created, then we don't need to analyse the XPath
-    * objects for tree fragments.
-    */
-
-    if ((obj->type != XPATH_NODESET) && (obj->type != XPATH_XSLT_TREE))
-       return(0);
-    if ((obj->nodesetval == NULL) || (obj->nodesetval->nodeNr == 0))
-       return(0);
-
-    for (i = 0; i < obj->nodesetval->nodeNr; i++) {
-       cur = obj->nodesetval->nodeTab[i];
-       if (cur->type == XML_NAMESPACE_DECL) {
-           /*
-           * The XPath module sets the owner element of a ns-node on
-           * the ns->next field.
-           */
-           if ((((xmlNsPtr) cur)->next != NULL) &&
-               (((xmlNsPtr) cur)->next->type == XML_ELEMENT_NODE))
-           {
-               cur = (xmlNodePtr) ((xmlNsPtr) cur)->next;
-               doc = cur->doc;
-           } else {
-               xsltTransformError(ctxt, NULL, ctxt->inst,
-                   "Internal error in "
-                   "xsltExtensionInstructionResultRegister(): "
-                   "Cannot retrieve the doc of a namespace node.\n");
-               goto error;
-           }
-       } else {
-           doc = cur->doc;
-       }
-       if (doc == NULL) {
-           xsltTransformError(ctxt, NULL, ctxt->inst,
-               "Internal error in "
-               "xsltExtensionInstructionResultRegister(): "
-               "Cannot retrieve the doc of a node.\n");
-           goto error;
-       }
-       if (doc->name && (doc->name[0] == ' ')) {
-           /*
-           * This is a result tree fragment.
-           * We'll use the @psvi field for reference counting.
-           * TODO: How do we know if this is a value of a
-           *  global variable or a doc acquired via the
-           *  document() function?
-           */
-           doc->psvi = (void *) ((long) 1);
-       }
-    }
-
-    return(0);
-error:
-    return(-1);
-}
-
-/**
- * xsltReleaseRVT:
- * @ctxt:  an XSLT transformation context
- * @RVT:  a result value tree (Result Tree Fragment)
- *
- * Either frees the RVT (which is an xmlDoc) or stores
- * it in the context's cache for later reuse.
- */
-void
-xsltReleaseRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT)
-{
-    if (RVT == NULL)
-       return;
-
-    if (ctxt && (ctxt->cache->nbRVT < 40)) {
-       /*
-       * Store the Result Tree Fragment.
-       * Free the document info.
-       */
-       if (RVT->_private != NULL) {
-           xsltFreeDocumentKeys((xsltDocumentPtr) RVT->_private);
-           xmlFree(RVT->_private);
-           RVT->_private = NULL;
-       }
-       /*
-       * Clear the document tree.
-       * REVISIT TODO: Do we expect ID/IDREF tables to be existent?
-       */
-       if (RVT->children != NULL) {
-           xmlFreeNodeList(RVT->children);
-           RVT->children = NULL;
-           RVT->last = NULL;
-       }
-       if (RVT->ids != NULL) {
-           xmlFreeIDTable((xmlIDTablePtr) RVT->ids);
-           RVT->ids = NULL;
-       }
-       if (RVT->refs != NULL) {
-           xmlFreeRefTable((xmlRefTablePtr) RVT->refs);
-           RVT->refs = NULL;
-       }
-
-       /*
-       * Reset the reference counter.
-       */
-       RVT->psvi = 0;
-
-       RVT->next = (xmlNodePtr) ctxt->cache->RVT;
-       ctxt->cache->RVT = RVT;
-
-       ctxt->cache->nbRVT++;
-
-#ifdef XSLT_DEBUG_PROFILE_CACHE
-       ctxt->cache->dbgCachedRVTs++;
-#endif
-       return;
-    }
-    /*
-    * Free it.
-    */
-    if (RVT->_private != NULL) {
-       xsltFreeDocumentKeys((xsltDocumentPtr) RVT->_private);
-       xmlFree(RVT->_private);
-    }
-    xmlFreeDoc(RVT);
-}
-
-/**
- * xsltRegisterPersistRVT:
- * @ctxt:  an XSLT transformation context
- * @RVT:  a result value tree (Result Tree Fragment)
- *
- * Register the result value tree (XSLT 1.0 term: Result Tree Fragment)
- * in the fragment garbage collector.
- * The fragment will be freed when the transformation context is
- * freed.
- *
- * Returns 0 in case of success and -1 in case of error.
- */
-int
-xsltRegisterPersistRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT)
-{
-    if ((ctxt == NULL) || (RVT == NULL)) return(-1);
-
-    RVT->next = (xmlNodePtr) ctxt->persistRVT;
-    if (ctxt->persistRVT != NULL)
-       ctxt->persistRVT->prev = (xmlNodePtr) RVT;
-    ctxt->persistRVT = RVT;
-    return(0);
-}
-
-/**
- * xsltFreeRVTs:
- * @ctxt:  an XSLT transformation context
- *
- * Frees all registered result value trees (Result Tree Fragments)
- * of the transformation. Internal function; should not be called
- * by user-code.
- */
-void
-xsltFreeRVTs(xsltTransformContextPtr ctxt)
-{
-    xmlDocPtr cur, next;
-
-    if (ctxt == NULL)
-       return;
-    /*
-    * Local fragments.
-    */
-    cur = ctxt->localRVT;
-    while (cur != NULL) {
-        next = (xmlDocPtr) cur->next;
-       if (cur->_private != NULL) {
-           xsltFreeDocumentKeys(cur->_private);
-           xmlFree(cur->_private);
-       }
-       xmlFreeDoc(cur);
-       cur = next;
-    }
-    ctxt->localRVT = NULL;
-    /*
-    * User-created per-template fragments.
-    */
-    cur = ctxt->tmpRVT;
-    while (cur != NULL) {
-        next = (xmlDocPtr) cur->next;
-       if (cur->_private != NULL) {
-           xsltFreeDocumentKeys(cur->_private);
-           xmlFree(cur->_private);
-       }
-       xmlFreeDoc(cur);
-       cur = next;
-    }
-    ctxt->tmpRVT = NULL;
-    /*
-    * Global fragments.
-    */
-    cur = ctxt->persistRVT;
-    while (cur != NULL) {
-        next = (xmlDocPtr) cur->next;
-       if (cur->_private != NULL) {
-           xsltFreeDocumentKeys(cur->_private);
-           xmlFree(cur->_private);
-       }
-       xmlFreeDoc(cur);
-       cur = next;
-    }
-    ctxt->persistRVT = NULL;
-}
-
-/************************************************************************
- *                                                                     *
- *                     Module interfaces                               *
- *                                                                     *
- ************************************************************************/
-
-/**
- * xsltNewStackElem:
- *
- * Create a new XSLT ParserContext
- *
- * Returns the newly allocated xsltParserStackElem or NULL in case of error
- */
-static xsltStackElemPtr
-xsltNewStackElem(xsltTransformContextPtr ctxt)
-{
-    xsltStackElemPtr ret;
-    /*
-    * Reuse a stack item from the cache if available.
-    */
-    if (ctxt && ctxt->cache->stackItems) {
-       ret = ctxt->cache->stackItems;
-       ctxt->cache->stackItems = ret->next;
-       ret->next = NULL;
-       ctxt->cache->nbStackItems--;
-#ifdef XSLT_DEBUG_PROFILE_CACHE
-       ctxt->cache->dbgReusedVars++;
-#endif
-       return(ret);
-    }
-    ret = (xsltStackElemPtr) xmlMalloc(sizeof(xsltStackElem));
-    if (ret == NULL) {
-       xsltTransformError(NULL, NULL, NULL,
-               "xsltNewStackElem : malloc failed\n");
-       return(NULL);
-    }
-    memset(ret, 0, sizeof(xsltStackElem));
-    ret->context = ctxt;
-    return(ret);
-}
-
-/**
- * xsltCopyStackElem:
- * @elem:  an XSLT stack element
- *
- * Makes a copy of the stack element
- *
- * Returns the copy of NULL
- */
-static xsltStackElemPtr
-xsltCopyStackElem(xsltStackElemPtr elem) {
-    xsltStackElemPtr cur;
-
-    cur = (xsltStackElemPtr) xmlMalloc(sizeof(xsltStackElem));
-    if (cur == NULL) {
-       xsltTransformError(NULL, NULL, NULL,
-               "xsltCopyStackElem : malloc failed\n");
-       return(NULL);
-    }
-    memset(cur, 0, sizeof(xsltStackElem));
-    cur->context = elem->context;
-    cur->name = elem->name;
-    cur->nameURI = elem->nameURI;
-    cur->select = elem->select;
-    cur->tree = elem->tree;
-    cur->comp = elem->comp;
-    return(cur);
-}
-
-/**
- * xsltFreeStackElem:
- * @elem:  an XSLT stack element
- *
- * Free up the memory allocated by @elem
- */
-static void
-xsltFreeStackElem(xsltStackElemPtr elem) {
-    if (elem == NULL)
-       return;
-    if (elem->value != NULL)
-       xmlXPathFreeObject(elem->value);
-    /*
-    * Release the list of temporary Result Tree Fragments.
-    */
-    if (elem->fragment) {
-       xmlDocPtr cur;
-
-       while (elem->fragment != NULL) {
-           cur = elem->fragment;
-           elem->fragment = (xmlDocPtr) cur->next;
-
-           if (elem->context &&
-               (cur->psvi == (void *) ((long) 1)))
-           {
-               /*
-               * This fragment is a result of an extension instruction
-               * (e.g. XSLT's function) and needs to be preserved until
-               * the instruction exits.
-               * Example: The fragment of the variable must not be freed
-               *  since it is returned by the EXSLT function:
-               *  <f:function name="foo">
-               *   <xsl:variable name="bar">
-               *     <bar/>
-               *   </xsl:variable>
-               *   <f:result select="$bar"/>
-               *  </f:function>
-               *
-               */
-               xsltRegisterLocalRVT(elem->context, cur);
-           } else {
-               xsltReleaseRVT((xsltTransformContextPtr) elem->context,
-                   cur);
-           }
-       }
-    }
-    /*
-    * Cache or free the variable structure.
-    */
-    if (elem->context && (elem->context->cache->nbStackItems < 50)) {
-       /*
-       * Store the item in the cache.
-       */
-       xsltTransformContextPtr ctxt = elem->context;
-       memset(elem, 0, sizeof(xsltStackElem));
-       elem->context = ctxt;
-       elem->next = ctxt->cache->stackItems;
-       ctxt->cache->stackItems = elem;
-       ctxt->cache->nbStackItems++;
-#ifdef XSLT_DEBUG_PROFILE_CACHE
-       ctxt->cache->dbgCachedVars++;
-#endif
-       return;
-    }
-    xmlFree(elem);
-}
-
-/**
- * xsltFreeStackElemList:
- * @elem:  an XSLT stack element
- *
- * Free up the memory allocated by @elem
- */
-void
-xsltFreeStackElemList(xsltStackElemPtr elem) {
-    xsltStackElemPtr next;
-
-    while (elem != NULL) {
-       next = elem->next;
-       xsltFreeStackElem(elem);
-       elem = next;
-    }
-}
-
-/**
- * xsltStackLookup:
- * @ctxt:  an XSLT transformation context
- * @name:  the local part of the name
- * @nameURI:  the URI part of the name
- *
- * Locate an element in the stack based on its name.
- */
-#if 0 /* TODO: Those seem to have been used for debugging. */
-static int stack_addr = 0;
-static int stack_cmp = 0;
-#endif
-
-static xsltStackElemPtr
-xsltStackLookup(xsltTransformContextPtr ctxt, const xmlChar *name,
-               const xmlChar *nameURI) {
-    int i;
-    xsltStackElemPtr cur;
-
-    if ((ctxt == NULL) || (name == NULL) || (ctxt->varsNr == 0))
-       return(NULL);
-
-    /*
-     * Do the lookup from the top of the stack, but
-     * don't use params being computed in a call-param
-     * First lookup expects the variable name and URI to
-     * come from the disctionnary and hence pointer comparison.
-     */
-    for (i = ctxt->varsNr; i > ctxt->varsBase; i--) {
-       cur = ctxt->varsTab[i-1];
-       while (cur != NULL) {
-           if ((cur->name == name) && (cur->nameURI == nameURI)) {
-#if 0
-               stack_addr++;
-#endif
-               return(cur);
-           }
-           cur = cur->next;
-       }
-    }
-
-    /*
-     * Redo the lookup with interned string compares
-     * to avoid string compares.
-     */
-    name = xmlDictLookup(ctxt->dict, name, -1);
-    if (nameURI != NULL)
-        nameURI = xmlDictLookup(ctxt->dict, nameURI, -1);
-
-    for (i = ctxt->varsNr; i > ctxt->varsBase; i--) {
-       cur = ctxt->varsTab[i-1];
-       while (cur != NULL) {
-           if ((cur->name == name) && (cur->nameURI == nameURI)) {
-#if 0
-               stack_cmp++;
-#endif
-               return(cur);
-           }
-           cur = cur->next;
-       }
-    }
-
-    return(NULL);
-}
-
-#ifdef XSLT_REFACTORED
-#else
-
-/**
- * xsltCheckStackElem:
- * @ctxt:  xn XSLT transformation context
- * @name:  the variable name
- * @nameURI:  the variable namespace URI
- *
- * Checks whether a variable or param is already defined.
- *
- * URGENT TODO: Checks for redefinition of vars/params should be
- *  done only at compilation time.
- *
- * Returns 1 if variable is present, 2 if param is present, 3 if this
- *         is an inherited param, 0 if not found, -1 in case of failure.
- */
-static int
-xsltCheckStackElem(xsltTransformContextPtr ctxt, const xmlChar *name,
-                  const xmlChar *nameURI) {
-    xsltStackElemPtr cur;
-
-    if ((ctxt == NULL) || (name == NULL))
-       return(-1);
-
-    cur = xsltStackLookup(ctxt, name, nameURI);
-    if (cur == NULL)
-        return(0);
-    if (cur->comp != NULL) {
-        if (cur->comp->type == XSLT_FUNC_WITHPARAM)
-           return(3);
-       else if (cur->comp->type == XSLT_FUNC_PARAM)
-           return(2);
-    }
-
-    return(1);
-}
-
-#endif /* XSLT_REFACTORED */
-
-/**
- * xsltAddStackElem:
- * @ctxt:  xn XSLT transformation context
- * @elem:  a stack element
- *
- * Push an element (or list) onto the stack.
- * In case of a list, each member will be pushed into
- * a seperate slot; i.e. there's always 1 stack entry for
- * 1 stack element.
- *
- * Returns 0 in case of success, -1 in case of failure.
- */
-static int
-xsltAddStackElem(xsltTransformContextPtr ctxt, xsltStackElemPtr elem)
-{
-    if ((ctxt == NULL) || (elem == NULL))
-       return(-1);
-
-    do {
-       if (ctxt->varsMax == 0) {
-           ctxt->varsMax = 10;
-           ctxt->varsTab =
-               (xsltStackElemPtr *) xmlMalloc(ctxt->varsMax *
-               sizeof(ctxt->varsTab[0]));
-           if (ctxt->varsTab == NULL) {
-               xmlGenericError(xmlGenericErrorContext, "malloc failed !\n");
-               return (-1);
-           }
-       }
-       if (ctxt->varsNr >= ctxt->varsMax) {
-           ctxt->varsMax *= 2;
-           ctxt->varsTab =
-               (xsltStackElemPtr *) xmlRealloc(ctxt->varsTab,
-               ctxt->varsMax *
-               sizeof(ctxt->varsTab[0]));
-           if (ctxt->varsTab == NULL) {
-               xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");
-               return (-1);
-           }
-       }
-       ctxt->varsTab[ctxt->varsNr++] = elem;
-       ctxt->vars = elem;
-
-       elem = elem->next;
-    } while (elem != NULL);
-
-    return(0);
-}
-
-/**
- * xsltAddStackElemList:
- * @ctxt:  xn XSLT transformation context
- * @elems:  a stack element list
- *
- * Push an element list onto the stack.
- *
- * Returns 0 in case of success, -1 in case of failure.
- */
-int
-xsltAddStackElemList(xsltTransformContextPtr ctxt, xsltStackElemPtr elems)
-{
-    return(xsltAddStackElem(ctxt, elems));
-}
-
-/************************************************************************
- *                                                                     *
- *                     Module interfaces                               *
- *                                                                     *
- ************************************************************************/
-
-/**
- * xsltEvalVariable:
- * @ctxt:  the XSLT transformation context
- * @variable:  the variable or parameter item
- * @comp: the compiled XSLT instruction
- *
- * Evaluate a variable value.
- *
- * Returns the XPath Object value or NULL in case of error
- */
-static xmlXPathObjectPtr
-xsltEvalVariable(xsltTransformContextPtr ctxt, xsltStackElemPtr variable,
-                xsltStylePreCompPtr castedComp)
-{
-#ifdef XSLT_REFACTORED
-    xsltStyleItemVariablePtr comp =
-       (xsltStyleItemVariablePtr) castedComp;
-#else
-    xsltStylePreCompPtr comp = castedComp;
-#endif
-    xmlXPathObjectPtr result = NULL;
-    xmlNodePtr oldInst;
-
-    if ((ctxt == NULL) || (variable == NULL))
-       return(NULL);
-
-    /*
-    * A variable or parameter are evaluated on demand; thus the
-    * context (of XSLT and XPath) need to be temporarily adjusted and
-    * restored on exit.
-    */
-    oldInst = ctxt->inst;
-
-#ifdef WITH_XSLT_DEBUG_VARIABLE
-    XSLT_TRACE(ctxt,XSLT_TRACE_VARIABLES,xsltGenericDebug(xsltGenericDebugContext,
-       "Evaluating variable '%s'\n", variable->name));
-#endif
-    if (variable->select != NULL) {
-       xmlXPathCompExprPtr xpExpr = NULL;
-       xmlDocPtr oldXPDoc;
-       xmlNodePtr oldXPContextNode;
-       int oldXPProximityPosition, oldXPContextSize, oldXPNsNr;
-       xmlNsPtr *oldXPNamespaces;
-       xmlXPathContextPtr xpctxt = ctxt->xpathCtxt;
-       xsltStackElemPtr oldVar = ctxt->contextVariable;
-
-       if ((comp != NULL) && (comp->comp != NULL)) {
-           xpExpr = comp->comp;
-       } else {
-           xpExpr = xmlXPathCompile(variable->select);
-       }
-       if (xpExpr == NULL)
-           return(NULL);
-       /*
-       * Save context states.
-       */
-       oldXPDoc = xpctxt->doc;
-       oldXPContextNode = xpctxt->node;
-       oldXPProximityPosition = xpctxt->proximityPosition;
-       oldXPContextSize = xpctxt->contextSize;
-       oldXPNamespaces = xpctxt->namespaces;
-       oldXPNsNr = xpctxt->nsNr;
-
-       xpctxt->node = ctxt->node;
-       /*
-       * OPTIMIZE TODO: Lame try to set the context doc.
-       *   Get rid of this somehow in xpath.c.
-       */
-       if ((ctxt->node->type != XML_NAMESPACE_DECL) &&
-           ctxt->node->doc)
-           xpctxt->doc = ctxt->node->doc;
-       /*
-       * BUG TODO: The proximity position and the context size will
-       *  potentially be wrong.
-       *  Example:
-       *  <xsl:template select="foo">
-       *    <xsl:variable name="pos" select="position()"/>
-       *    <xsl:for-each select="bar">
-       *      <xsl:value-of select="$pos"/>
-       *    </xsl:for-each>
-       *  </xsl:template>
-       *  Here the proximity position and context size are changed
-       *  to the context of <xsl:for-each select="bar">, but
-       *  the variable needs to be evaluated in the context of
-       *  <xsl:template select="foo">.
-       */
-       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;
-       }
-
-       /*
-       * We need to mark that we are "selecting" a var's value;
-       * if any tree fragments are created inside the expression,
-       * then those need to be stored inside the variable; otherwise
-       * we'll eventually free still referenced fragments, before
-       * we leave the scope of the variable.
-       */
-       ctxt->contextVariable = variable;
-       variable->flags |= XSLT_VAR_IN_SELECT;
-
-       result = xmlXPathCompiledEval(xpExpr, xpctxt);
-
-       variable->flags ^= XSLT_VAR_IN_SELECT;
-       /*
-       * Restore Context states.
-       */
-       ctxt->contextVariable = oldVar;
-
-       xpctxt->doc = oldXPDoc;
-       xpctxt->node = oldXPContextNode;
-       xpctxt->contextSize = oldXPContextSize;
-       xpctxt->proximityPosition = oldXPProximityPosition;
-       xpctxt->namespaces = oldXPNamespaces;
-       xpctxt->nsNr = oldXPNsNr;
-
-       if ((comp == NULL) || (comp->comp == NULL))
-           xmlXPathFreeCompExpr(xpExpr);
-       if (result == NULL) {
-           xsltTransformError(ctxt, NULL,
-               (comp != NULL) ? comp->inst : NULL,
-               "Failed to evaluate the expression of variable '%s'.\n",
-               variable->name);
-           ctxt->state = XSLT_STATE_STOPPED;
-
-#ifdef WITH_XSLT_DEBUG_VARIABLE
-#ifdef LIBXML_DEBUG_ENABLED
-       } else {
-           if ((xsltGenericDebugContext == stdout) ||
-               (xsltGenericDebugContext == stderr))
-               xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext,
-                                       result, 0);
-#endif
-#endif
-       }
-    } else {
-       if (variable->tree == NULL) {
-           result = xmlXPathNewCString("");
-       } else {
-           if (variable->tree) {
-               xmlDocPtr container;
-               xmlNodePtr oldInsert;
-               xmlDocPtr  oldOutput;
-               xsltStackElemPtr oldVar = ctxt->contextVariable;
-
-               /*
-               * Generate a result tree fragment.
-               */
-               container = xsltCreateRVT(ctxt);
-               if (container == NULL)
-                   goto error;
-               /*
-               * NOTE: Local Result Tree Fragments of params/variables
-               * are not registered globally anymore; the life-time
-               * is not directly dependant of the param/variable itself.
-               *
-               * OLD: xsltRegisterTmpRVT(ctxt, container);
-               */
-               /*
-               * Attach the Result Tree Fragment to the variable;
-               * when the variable is freed, it will also free
-               * the Result Tree Fragment.
-               */
-               variable->fragment = container;
-
-               oldOutput = ctxt->output;
-               oldInsert = ctxt->insert;
-
-               ctxt->output = container;
-               ctxt->insert = (xmlNodePtr) container;
-               ctxt->contextVariable = variable;
-               /*
-               * Process the sequence constructor (variable->tree).
-               * The resulting tree will be held by @container.
-               */
-               xsltApplyOneTemplate(ctxt, ctxt->node, variable->tree,
-                   NULL, NULL);
-
-               ctxt->contextVariable = oldVar;
-               ctxt->insert = oldInsert;
-               ctxt->output = oldOutput;
-
-               result = xmlXPathNewValueTree((xmlNodePtr) container);
-           }
-           if (result == NULL) {
-               result = xmlXPathNewCString("");
-           } else {
-               /*
-               * Freeing is not handled there anymore.
-               * QUESTION TODO: What does the above comment mean?
-               */
-               result->boolval = 0;
-           }
-#ifdef WITH_XSLT_DEBUG_VARIABLE
-#ifdef LIBXML_DEBUG_ENABLED
-
-           if ((xsltGenericDebugContext == stdout) ||
-               (xsltGenericDebugContext == stderr))
-               xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext,
-                                       result, 0);
-#endif
-#endif
-       }
-    }
-
-error:
-    ctxt->inst = oldInst;
-    return(result);
-}
-
-/**
- * xsltEvalGlobalVariable:
- * @elem:  the variable or parameter
- * @ctxt:  the XSLT transformation context
- *
- * Evaluates a the value of a global xsl:variable or
- * xsl:param declaration.
- *
- * Returns the XPath Object value or NULL in case of error
- */
-static xmlXPathObjectPtr
-xsltEvalGlobalVariable(xsltStackElemPtr elem, xsltTransformContextPtr ctxt)
-{
-    xmlXPathObjectPtr result = NULL;
-    xmlNodePtr oldInst;
-    const xmlChar* oldVarName;
-
-#ifdef XSLT_REFACTORED
-    xsltStyleBasicItemVariablePtr comp;
-#else
-    xsltStylePreCompPtr comp;
-#endif
-
-    if ((ctxt == NULL) || (elem == NULL))
-       return(NULL);
-    if (elem->computed)
-       return(elem->value);
-
-
-#ifdef WITH_XSLT_DEBUG_VARIABLE
-    XSLT_TRACE(ctxt,XSLT_TRACE_VARIABLES,xsltGenericDebug(xsltGenericDebugContext,
-       "Evaluating global variable %s\n", elem->name));
-#endif
-
-#ifdef WITH_DEBUGGER
-    if ((ctxt->debugStatus != XSLT_DEBUG_NONE) &&
-        elem->comp && elem->comp->inst)
-        xslHandleDebugger(elem->comp->inst, NULL, NULL, ctxt);
-#endif
-
-    oldInst = ctxt->inst;
-#ifdef XSLT_REFACTORED
-    comp = (xsltStyleBasicItemVariablePtr) elem->comp;
-#else
-    comp = elem->comp;
-#endif
-    oldVarName = elem->name;
-    elem->name = xsltComputingGlobalVarMarker;
-    /*
-    * OPTIMIZE TODO: We should consider instantiating global vars/params
-    *  on-demand. The vars/params don't need to be evaluated if never
-    *  called; and in the case of global params, if values for such params
-    *  are provided by the user.
-    */
-    if (elem->select != NULL) {
-       xmlXPathCompExprPtr xpExpr = NULL;
-       xmlDocPtr oldXPDoc;
-       xmlNodePtr oldXPContextNode;
-       int oldXPProximityPosition, oldXPContextSize, oldXPNsNr;
-       xmlNsPtr *oldXPNamespaces;
-       xmlXPathContextPtr xpctxt = ctxt->xpathCtxt;
-
-       if ((comp != NULL) && (comp->comp != NULL)) {
-           xpExpr = comp->comp;
-       } else {
-           xpExpr = xmlXPathCompile(elem->select);
-       }
-       if (xpExpr == NULL)
-           goto error;
-
-
-       if (comp != NULL)
-           ctxt->inst = comp->inst;
-       else
-           ctxt->inst = NULL;
-       /*
-       * SPEC XSLT 1.0:
-       * "At top-level, the expression or template specifying the
-       *  variable value is evaluated with the same context as that used
-       *  to process the root node of the source document: the current
-       *  node is the root node of the source document and the current
-       *  node list is a list containing just the root node of the source
-       *  document."
-       */
-       /*
-       * Save context states.
-       */
-       oldXPDoc = xpctxt->doc;
-       oldXPContextNode = xpctxt->node;
-       oldXPProximityPosition = xpctxt->proximityPosition;
-       oldXPContextSize = xpctxt->contextSize;
-       oldXPNamespaces = xpctxt->namespaces;
-       oldXPNsNr = xpctxt->nsNr;
-
-       xpctxt->node = ctxt->initialContextNode;
-       xpctxt->doc = ctxt->initialContextDoc;
-       xpctxt->contextSize = 1;
-       xpctxt->proximityPosition = 1;
-
-       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;
-       }
-
-       result = xmlXPathCompiledEval(xpExpr, xpctxt);
-
-       /*
-       * Restore Context states.
-       */
-       xpctxt->doc = oldXPDoc;
-       xpctxt->node = oldXPContextNode;
-       xpctxt->contextSize = oldXPContextSize;
-       xpctxt->proximityPosition = oldXPProximityPosition;
-       xpctxt->namespaces = oldXPNamespaces;
-       xpctxt->nsNr = oldXPNsNr;
-
-       if ((comp == NULL) || (comp->comp == NULL))
-           xmlXPathFreeCompExpr(xpExpr);
-       if (result == NULL) {
-           if (comp == NULL)
-               xsltTransformError(ctxt, NULL, NULL,
-                   "Evaluating global variable %s failed\n", elem->name);
-           else
-               xsltTransformError(ctxt, NULL, comp->inst,
-                   "Evaluating global variable %s failed\n", elem->name);
-           ctxt->state = XSLT_STATE_STOPPED;
-#ifdef WITH_XSLT_DEBUG_VARIABLE
-#ifdef LIBXML_DEBUG_ENABLED
-       } else {
-           if ((xsltGenericDebugContext == stdout) ||
-               (xsltGenericDebugContext == stderr))
-               xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext,
-                                       result, 0);
-#endif
-#endif
-       }
-    } else {
-       if (elem->tree == NULL) {
-           result = xmlXPathNewCString("");
-       } else {
-           xmlDocPtr container;
-           xmlNodePtr oldInsert;
-           xmlDocPtr  oldOutput, oldXPDoc;
-           /*
-           * Generate a result tree fragment.
-           */
-           container = xsltCreateRVT(ctxt);
-           if (container == NULL)
-               goto error;
-           /*
-           * Let the lifetime of the tree fragment be handled by
-           * the Libxslt's garbage collector.
-           */
-           xsltRegisterPersistRVT(ctxt, container);
-
-           oldOutput = ctxt->output;
-           oldInsert = ctxt->insert;
-
-           oldXPDoc = ctxt->xpathCtxt->doc;
-
-           ctxt->output = container;
-           ctxt->insert = (xmlNodePtr) container;
-
-           ctxt->xpathCtxt->doc = ctxt->initialContextDoc;
-           /*
-           * Process the sequence constructor.
-           */
-           xsltApplyOneTemplate(ctxt, ctxt->node, elem->tree, NULL, NULL);
-
-           ctxt->xpathCtxt->doc = oldXPDoc;
-
-           ctxt->insert = oldInsert;
-           ctxt->output = oldOutput;
-
-           result = xmlXPathNewValueTree((xmlNodePtr) container);
-           if (result == NULL) {
-               result = xmlXPathNewCString("");
-           } else {
-               result->boolval = 0; /* Freeing is not handled there anymore */
-           }
-#ifdef WITH_XSLT_DEBUG_VARIABLE
-#ifdef LIBXML_DEBUG_ENABLED
-           if ((xsltGenericDebugContext == stdout) ||
-               (xsltGenericDebugContext == stderr))
-               xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext,
-                                       result, 0);
-#endif
-#endif
-       }
-    }
-
-error:
-    elem->name = oldVarName;
-    ctxt->inst = oldInst;
-    if (result != NULL) {
-       elem->value = result;
-       elem->computed = 1;
-    }
-    return(result);
-}
-
-/**
- * xsltEvalGlobalVariables:
- * @ctxt:  the XSLT transformation context
- *
- * Evaluates all global variables and parameters of a stylesheet.
- * For internal use only. This is called at start of a transformation.
- *
- * Returns 0 in case of success, -1 in case of error
- */
-int
-xsltEvalGlobalVariables(xsltTransformContextPtr ctxt) {
-    xsltStackElemPtr elem;
-    xsltStylesheetPtr style;
-
-    if ((ctxt == NULL) || (ctxt->document == NULL))
-       return(-1);
-
-#ifdef WITH_XSLT_DEBUG_VARIABLE
-    XSLT_TRACE(ctxt,XSLT_TRACE_VARIABLES,xsltGenericDebug(xsltGenericDebugContext,
-       "Registering global variables\n"));
-#endif
-    /*
-     * Walk the list from the stylesheets and populate the hash table
-     */
-    style = ctxt->style;
-    while (style != NULL) {
-       elem = style->variables;
-
-#ifdef WITH_XSLT_DEBUG_VARIABLE
-       if ((style->doc != NULL) && (style->doc->URL != NULL)) {
-           XSLT_TRACE(ctxt,XSLT_TRACE_VARIABLES,xsltGenericDebug(xsltGenericDebugContext,
-                            "Registering global variables from %s\n",
-                            style->doc->URL));
-       }
-#endif
-
-       while (elem != NULL) {
-           xsltStackElemPtr def;
-
-           /*
-            * Global variables are stored in the variables pool.
-            */
-           def = (xsltStackElemPtr)
-                   xmlHashLookup2(ctxt->globalVars,
-                                elem->name, elem->nameURI);
-           if (def == NULL) {
-
-               def = xsltCopyStackElem(elem);
-               xmlHashAddEntry2(ctxt->globalVars,
-                                elem->name, elem->nameURI, def);
-           } else if ((elem->comp != NULL) &&
-                      (elem->comp->type == XSLT_FUNC_VARIABLE)) {
-               /*
-                * Redefinition of variables from a different stylesheet
-                * should not generate a message.
-                */
-               if ((elem->comp->inst != NULL) &&
-                   (def->comp != NULL) && (def->comp->inst != NULL) &&
-                   (elem->comp->inst->doc == def->comp->inst->doc))
-               {
-                   xsltTransformError(ctxt, style, elem->comp->inst,
-                       "Global variable %s already defined\n", elem->name);
-                   if (style != NULL) style->errors++;
-               }
-           }
-           elem = elem->next;
-       }
-
-       style = xsltNextImport(style);
-    }
-
-    /*
-     * This part does the actual evaluation
-     */
-    xmlHashScan(ctxt->globalVars,
-               (xmlHashScanner) xsltEvalGlobalVariable, ctxt);
-
-    return(0);
-}
-
-/**
- * xsltRegisterGlobalVariable:
- * @style:  the XSLT transformation context
- * @name:  the variable name
- * @ns_uri:  the variable namespace URI
- * @sel:  the expression which need to be evaluated to generate a value
- * @tree:  the subtree if sel is NULL
- * @comp:  the precompiled value
- * @value:  the string value if available
- *
- * Register a new variable value. If @value is NULL it unregisters
- * the variable
- *
- * Returns 0 in case of success, -1 in case of error
- */
-static int
-xsltRegisterGlobalVariable(xsltStylesheetPtr style, const xmlChar *name,
-                    const xmlChar *ns_uri, const xmlChar *sel,
-                    xmlNodePtr tree, xsltStylePreCompPtr comp,
-                    const xmlChar *value) {
-    xsltStackElemPtr elem, tmp;
-    if (style == NULL)
-       return(-1);
-    if (name == NULL)
-       return(-1);
-    if (comp == NULL)
-       return(-1);
-
-#ifdef WITH_XSLT_DEBUG_VARIABLE
-    if (comp->type == XSLT_FUNC_PARAM)
-       xsltGenericDebug(xsltGenericDebugContext,
-                        "Defining global param %s\n", name);
-    else
-       xsltGenericDebug(xsltGenericDebugContext,
-                        "Defining global variable %s\n", name);
-#endif
-
-    elem = xsltNewStackElem(NULL);
-    if (elem == NULL)
-       return(-1);
-    elem->comp = comp;
-    elem->name = xmlDictLookup(style->dict, name, -1);
-    elem->select = xmlDictLookup(style->dict, sel, -1);
-    if (ns_uri)
-       elem->nameURI = xmlDictLookup(style->dict, ns_uri, -1);
-    elem->tree = tree;
-    tmp = style->variables;
-    if (tmp == NULL) {
-       elem->next = NULL;
-       style->variables = elem;
-    } else {
-       while (tmp != NULL) {
-           if ((elem->comp->type == XSLT_FUNC_VARIABLE) &&
-               (tmp->comp->type == XSLT_FUNC_VARIABLE) &&
-               (xmlStrEqual(elem->name, tmp->name)) &&
-               ((elem->nameURI == tmp->nameURI) ||
-                (xmlStrEqual(elem->nameURI, tmp->nameURI))))
-           {
-               xsltTransformError(NULL, style, comp->inst,
-               "redefinition of global variable %s\n", elem->name);
-               style->errors++;
-           }
-           if (tmp->next == NULL)
-               break;
-           tmp = tmp->next;
-       }
-       elem->next = NULL;
-       tmp->next = elem;
-    }
-    if (value != NULL) {
-       elem->computed = 1;
-       elem->value = xmlXPathNewString(value);
-    }
-    return(0);
-}
-
-/**
- * xsltProcessUserParamInternal
- *
- * @ctxt:  the XSLT transformation context
- * @name:  a null terminated parameter name
- * @value: a null terminated value (may be an XPath expression)
- * @eval:  0 to treat the value literally, else evaluate as XPath expression
- *
- * If @eval is 0 then @value is treated literally and is stored in the global
- * parameter/variable table without any change.
- *
- * Uf @eval is 1 then @value is treated as an XPath expression and is
- * evaluated.  In this case, if you want to pass a string which will be
- * interpreted literally then it must be enclosed in single or double quotes.
- * If the string contains single quotes (double quotes) then it cannot be
- * enclosed single quotes (double quotes).  If the string which you want to
- * be treated literally contains both single and double quotes (e.g. Meet
- * at Joe's for "Twelfth Night" at 7 o'clock) then there is no suitable
- * quoting character.  You cannot use &apos; or &quot; inside the string
- * because the replacement of character entities with their equivalents is
- * done at a different stage of processing.  The solution is to call
- * xsltQuoteUserParams or xsltQuoteOneUserParam.
- *
- * This needs to be done on parsed stylesheets before starting to apply
- * transformations.  Normally this will be called (directly or indirectly)
- * only from xsltEvalUserParams, xsltEvalOneUserParam, xsltQuoteUserParams,
- * or xsltQuoteOneUserParam.
- *
- * Returns 0 in case of success, -1 in case of error
- */
-
-static
-int
-xsltProcessUserParamInternal(xsltTransformContextPtr ctxt,
-                            const xmlChar * name,
-                            const xmlChar * value,
-                            int eval) {
-
-    xsltStylesheetPtr style;
-    const xmlChar *prefix;
-    const xmlChar *href;
-    xmlXPathCompExprPtr xpExpr;
-    xmlXPathObjectPtr result;
-
-    xsltStackElemPtr elem;
-    int res;
-    void *res_ptr;
-
-    if (ctxt == NULL)
-       return(-1);
-    if (name == NULL)
-       return(0);
-    if (value == NULL)
-       return(0);
-
-    style = ctxt->style;
-
-#ifdef WITH_XSLT_DEBUG_VARIABLE
-    XSLT_TRACE(ctxt,XSLT_TRACE_VARIABLES,xsltGenericDebug(xsltGenericDebugContext,
-           "Evaluating user parameter %s=%s\n", name, value));
-#endif
-
-    /*
-     * Name lookup
-     */
-    href = NULL;
-
-    if (name[0] == '{') {
-        int len = 0;
-
-        while ((name[len] != 0) && (name[len] != '}')) len++;
-        if (name[len] == 0) {
-           xsltTransformError(ctxt, style, NULL,
-           "user param : malformed parameter name : %s\n", name);
-        } else {
-           href = xmlDictLookup(ctxt->dict, &name[1], len-1);
-           name = xmlDictLookup(ctxt->dict, &name[len + 1], -1);
-       }
-    }
-    else {
-        name = xsltSplitQName(ctxt->dict, name, &prefix);
-        if (prefix != NULL) {
-            xmlNsPtr ns;
-
-            ns = xmlSearchNs(style->doc, xmlDocGetRootElement(style->doc),
-                             prefix);
-            if (ns == NULL) {
-                xsltTransformError(ctxt, style, NULL,
-                "user param : no namespace bound to prefix %s\n", prefix);
-                href = NULL;
-            } else {
-                href = ns->href;
-            }
-        }
-    }
-
-    if (name == NULL)
-       return (-1);
-
-    res_ptr = xmlHashLookup2(ctxt->globalVars, name, href);
-    if (res_ptr != 0) {
-       xsltTransformError(ctxt, style, NULL,
-           "Global parameter %s already defined\n", name);
-    }
-    if (ctxt->globalVars == NULL)
-       ctxt->globalVars = xmlHashCreate(20);
-
-    /*
-     * do not overwrite variables with parameters from the command line
-     */
-    while (style != NULL) {
-        elem = ctxt->style->variables;
-       while (elem != NULL) {
-           if ((elem->comp != NULL) &&
-               (elem->comp->type == XSLT_FUNC_VARIABLE) &&
-               (xmlStrEqual(elem->name, name)) &&
-               (xmlStrEqual(elem->nameURI, href))) {
-               return(0);
-           }
-            elem = elem->next;
-       }
-        style = xsltNextImport(style);
-    }
-    style = ctxt->style;
-    elem = NULL;
-
-    /*
-     * Do the evaluation if @eval is non-zero.
-     */
-
-    result = NULL;
-    if (eval != 0) {
-        xpExpr = xmlXPathCompile(value);
-       if (xpExpr != NULL) {
-           xmlDocPtr oldXPDoc;
-           xmlNodePtr oldXPContextNode;
-           int oldXPProximityPosition, oldXPContextSize, oldXPNsNr;
-           xmlNsPtr *oldXPNamespaces;
-           xmlXPathContextPtr xpctxt = ctxt->xpathCtxt;
-
-           /*
-           * Save context states.
-           */
-           oldXPDoc = xpctxt->doc;
-           oldXPContextNode = xpctxt->node;
-           oldXPProximityPosition = xpctxt->proximityPosition;
-           oldXPContextSize = xpctxt->contextSize;
-           oldXPNamespaces = xpctxt->namespaces;
-           oldXPNsNr = xpctxt->nsNr;
-
-           /*
-           * SPEC XSLT 1.0:
-           * "At top-level, the expression or template specifying the
-           *  variable value is evaluated with the same context as that used
-           *  to process the root node of the source document: the current
-           *  node is the root node of the source document and the current
-           *  node list is a list containing just the root node of the source
-           *  document."
-           */
-           xpctxt->doc = ctxt->initialContextDoc;
-           xpctxt->node = ctxt->initialContextNode;
-           xpctxt->contextSize = 1;
-           xpctxt->proximityPosition = 1;
-           /*
-           * There is really no in scope namespace for parameters on the
-           * command line.
-           */
-           xpctxt->namespaces = NULL;
-           xpctxt->nsNr = 0;
-
-           result = xmlXPathCompiledEval(xpExpr, xpctxt);
-
-           /*
-           * Restore Context states.
-           */
-           xpctxt->doc = oldXPDoc;
-           xpctxt->node = oldXPContextNode;
-           xpctxt->contextSize = oldXPContextSize;
-           xpctxt->proximityPosition = oldXPProximityPosition;
-           xpctxt->namespaces = oldXPNamespaces;
-           xpctxt->nsNr = oldXPNsNr;
-
-           xmlXPathFreeCompExpr(xpExpr);
-       }
-       if (result == NULL) {
-           xsltTransformError(ctxt, style, NULL,
-               "Evaluating user parameter %s failed\n", name);
-           ctxt->state = XSLT_STATE_STOPPED;
-           return(-1);
-       }
-    }
-
-    /*
-     * If @eval is 0 then @value is to be taken literally and result is NULL
-     *
-     * If @eval is not 0, then @value is an XPath expression and has been
-     * successfully evaluated and result contains the resulting value and
-     * is not NULL.
-     *
-     * Now create an xsltStackElemPtr for insertion into the context's
-     * global variable/parameter hash table.
-     */
-
-#ifdef WITH_XSLT_DEBUG_VARIABLE
-#ifdef LIBXML_DEBUG_ENABLED
-    if ((xsltGenericDebugContext == stdout) ||
-        (xsltGenericDebugContext == stderr))
-           xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext,
-                                   result, 0);
-#endif
-#endif
-
-    elem = xsltNewStackElem(NULL);
-    if (elem != NULL) {
-       elem->name = name;
-       elem->select = xmlDictLookup(ctxt->dict, value, -1);
-       if (href != NULL)
-           elem->nameURI = xmlDictLookup(ctxt->dict, href, -1);
-       elem->tree = NULL;
-       elem->computed = 1;
-       if (eval == 0) {
-           elem->value = xmlXPathNewString(value);
-       }
-       else {
-           elem->value = result;
-       }
-    }
-
-    /*
-     * Global parameters are stored in the XPath context variables pool.
-     */
-
-    res = xmlHashAddEntry2(ctxt->globalVars, name, href, elem);
-    if (res != 0) {
-       xsltFreeStackElem(elem);
-       xsltTransformError(ctxt, style, NULL,
-           "Global parameter %s already defined\n", name);
-    }
-    return(0);
-}
-
-/**
- * xsltEvalUserParams:
- *
- * @ctxt:  the XSLT transformation context
- * @params:  a NULL terminated array of parameters name/value tuples
- *
- * Evaluate the global variables of a stylesheet. This needs to be
- * done on parsed stylesheets before starting to apply transformations.
- * Each of the parameters is evaluated as an XPath expression and stored
- * in the global variables/parameter hash table.  If you want your
- * parameter used literally, use xsltQuoteUserParams.
- *
- * Returns 0 in case of success, -1 in case of error
- */
-
-int
-xsltEvalUserParams(xsltTransformContextPtr ctxt, const char **params) {
-    int indx = 0;
-    const xmlChar *name;
-    const xmlChar *value;
-
-    if (params == NULL)
-       return(0);
-    while (params[indx] != NULL) {
-       name = (const xmlChar *) params[indx++];
-       value = (const xmlChar *) params[indx++];
-       if (xsltEvalOneUserParam(ctxt, name, value) != 0)
-           return(-1);
-    }
-    return 0;
-}
-
-/**
- * xsltQuoteUserParams:
- *
- * @ctxt:  the XSLT transformation context
- * @params:  a NULL terminated arry of parameters names/values tuples
- *
- * Similar to xsltEvalUserParams, but the values are treated literally and
- * are * *not* evaluated as XPath expressions. This should be done on parsed
- * stylesheets before starting to apply transformations.
- *
- * Returns 0 in case of success, -1 in case of error.
- */
-
-int
-xsltQuoteUserParams(xsltTransformContextPtr ctxt, const char **params) {
-    int indx = 0;
-    const xmlChar *name;
-    const xmlChar *value;
-
-    if (params == NULL)
-       return(0);
-    while (params[indx] != NULL) {
-       name = (const xmlChar *) params[indx++];
-       value = (const xmlChar *) params[indx++];
-       if (xsltQuoteOneUserParam(ctxt, name, value) != 0)
-           return(-1);
-    }
-    return 0;
-}
-
-/**
- * xsltEvalOneUserParam:
- * @ctxt:  the XSLT transformation context
- * @name:  a null terminated string giving the name of the parameter
- * @value:  a null terminated string giving the XPath expression to be evaluated
- *
- * This is normally called from xsltEvalUserParams to process a single
- * parameter from a list of parameters.  The @value is evaluated as an
- * XPath expression and the result is stored in the context's global
- * variable/parameter hash table.
- *
- * To have a parameter treated literally (not as an XPath expression)
- * use xsltQuoteUserParams (or xsltQuoteOneUserParam).  For more
- * details see description of xsltProcessOneUserParamInternal.
- *
- * Returns 0 in case of success, -1 in case of error.
- */
-
-int
-xsltEvalOneUserParam(xsltTransformContextPtr ctxt,
-                    const xmlChar * name,
-                    const xmlChar * value) {
-    return xsltProcessUserParamInternal(ctxt, name, value,
-                                       1 /* xpath eval ? */);
-}
-
-/**
- * xsltQuoteOneUserParam:
- * @ctxt:  the XSLT transformation context
- * @name:  a null terminated string giving the name of the parameter
- * @value:  a null terminated string giving the parameter value
- *
- * This is normally called from xsltQuoteUserParams to process a single
- * parameter from a list of parameters.  The @value is stored in the
- * context's global variable/parameter hash table.
- *
- * Returns 0 in case of success, -1 in case of error.
- */
-
-int
-xsltQuoteOneUserParam(xsltTransformContextPtr ctxt,
-                        const xmlChar * name,
-                        const xmlChar * value) {
-    return xsltProcessUserParamInternal(ctxt, name, value,
-                                       0 /* xpath eval ? */);
-}
-
-/**
- * xsltBuildVariable:
- * @ctxt:  the XSLT transformation context
- * @comp:  the precompiled form
- * @tree:  the tree if select is NULL
- *
- * Computes a new variable value.
- *
- * Returns the xsltStackElemPtr or NULL in case of error
- */
-static xsltStackElemPtr
-xsltBuildVariable(xsltTransformContextPtr ctxt,
-                 xsltStylePreCompPtr castedComp,
-                 xmlNodePtr tree)
-{
-#ifdef XSLT_REFACTORED
-    xsltStyleBasicItemVariablePtr comp =
-       (xsltStyleBasicItemVariablePtr) castedComp;
-#else
-    xsltStylePreCompPtr comp = castedComp;
-#endif
-    xsltStackElemPtr elem;
-
-#ifdef WITH_XSLT_DEBUG_VARIABLE
-    XSLT_TRACE(ctxt,XSLT_TRACE_VARIABLES,xsltGenericDebug(xsltGenericDebugContext,
-                    "Building variable %s", comp->name));
-    if (comp->select != NULL)
-       XSLT_TRACE(ctxt,XSLT_TRACE_VARIABLES,xsltGenericDebug(xsltGenericDebugContext,
-                        " select %s", comp->select));
-    XSLT_TRACE(ctxt,XSLT_TRACE_VARIABLES,xsltGenericDebug(xsltGenericDebugContext, "\n"));
-#endif
-
-    elem = xsltNewStackElem(ctxt);
-    if (elem == NULL)
-       return(NULL);
-    elem->comp = (xsltStylePreCompPtr) comp;
-    elem->name = comp->name;
-    elem->select = comp->select;
-    elem->nameURI = comp->ns;
-    elem->tree = tree;
-    elem->value = xsltEvalVariable(ctxt, elem,
-       (xsltStylePreCompPtr) comp);
-    if (elem->value != NULL)
-       elem->computed = 1;
-    return(elem);
-}
-
-/**
- * xsltRegisterVariable:
- * @ctxt:  the XSLT transformation context
- * @comp: the compiled XSLT-variable (or param) instruction
- * @tree:  the tree if select is NULL
- * @isParam:  indicates if this is a parameter
- *
- * Computes and registers a new variable.
- *
- * Returns 0 in case of success, -1 in case of error
- */
-static int
-xsltRegisterVariable(xsltTransformContextPtr ctxt,
-                    xsltStylePreCompPtr castedComp,
-                    xmlNodePtr tree, int isParam)
-{
-#ifdef XSLT_REFACTORED
-    xsltStyleBasicItemVariablePtr comp =
-       (xsltStyleBasicItemVariablePtr) castedComp;
-#else
-    xsltStylePreCompPtr comp = castedComp;
-    int present;
-#endif
-    xsltStackElemPtr variable;
-
-#ifdef XSLT_REFACTORED
-    /*
-    * REFACTORED NOTE: Redefinitions of vars/params are checked
-    *  at compilation time in the refactored code.
-    * xsl:with-param parameters are checked in xsltApplyXSLTTemplate().
-    */
-#else
-    present = xsltCheckStackElem(ctxt, comp->name, comp->ns);
-    if (isParam == 0) {
-       if ((present != 0) && (present != 3)) {
-           /* TODO: report QName. */
-           xsltTransformError(ctxt, NULL, comp->inst,
-               "XSLT-variable: Redefinition of variable '%s'.\n", comp->name);
-           return(0);
-       }
-    } else if (present != 0) {
-       if ((present == 1) || (present == 2)) {
-           /* TODO: report QName. */
-           xsltTransformError(ctxt, NULL, comp->inst,
-               "XSLT-param: Redefinition of parameter '%s'.\n", comp->name);
-           return(0);
-       }
-#ifdef WITH_XSLT_DEBUG_VARIABLE
-       XSLT_TRACE(ctxt,XSLT_TRACE_VARIABLES,xsltGenericDebug(xsltGenericDebugContext,
-                "param %s defined by caller\n", comp->name));
-#endif
-       return(0);
-    }
-#endif /* else of XSLT_REFACTORED */
-
-    variable = xsltBuildVariable(ctxt, (xsltStylePreCompPtr) comp, tree);
-    xsltAddStackElem(ctxt, variable);
-    return(0);
-}
-
-/**
- * xsltGlobalVariableLookup:
- * @ctxt:  the XSLT transformation context
- * @name:  the variable name
- * @ns_uri:  the variable namespace URI
- *
- * Search in the Variable array of the context for the given
- * variable value.
- *
- * Returns the value or NULL if not found
- */
-static xmlXPathObjectPtr
-xsltGlobalVariableLookup(xsltTransformContextPtr ctxt, const xmlChar *name,
-                        const xmlChar *ns_uri) {
-    xsltStackElemPtr elem;
-    xmlXPathObjectPtr ret = NULL;
-
-    /*
-     * Lookup the global variables in XPath global variable hash table
-     */
-    if ((ctxt->xpathCtxt == NULL) || (ctxt->globalVars == NULL))
-       return(NULL);
-    elem = (xsltStackElemPtr)
-           xmlHashLookup2(ctxt->globalVars, name, ns_uri);
-    if (elem == NULL) {
-#ifdef WITH_XSLT_DEBUG_VARIABLE
-       XSLT_TRACE(ctxt,XSLT_TRACE_VARIABLES,xsltGenericDebug(xsltGenericDebugContext,
-                        "global variable not found %s\n", name));
-#endif
-       return(NULL);
-    }
-    /*
-    * URGENT TODO: Move the detection of recursive definitions
-    * to compile-time.
-    */
-    if (elem->computed == 0) {
-       if (elem->name == xsltComputingGlobalVarMarker) {
-           xsltTransformError(ctxt, NULL, elem->comp->inst,
-               "Recursive definition of %s\n", name);
-           return(NULL);
-       }
-       ret = xsltEvalGlobalVariable(elem, ctxt);
-    } else
-       ret = elem->value;
-    return(xmlXPathObjectCopy(ret));
-}
-
-/**
- * xsltVariableLookup:
- * @ctxt:  the XSLT transformation context
- * @name:  the variable name
- * @ns_uri:  the variable namespace URI
- *
- * Search in the Variable array of the context for the given
- * variable value.
- *
- * Returns the value or NULL if not found
- */
-xmlXPathObjectPtr
-xsltVariableLookup(xsltTransformContextPtr ctxt, const xmlChar *name,
-                  const xmlChar *ns_uri) {
-    xsltStackElemPtr elem;
-
-    if (ctxt == NULL)
-       return(NULL);
-
-    elem = xsltStackLookup(ctxt, name, ns_uri);
-    if (elem == NULL) {
-       return(xsltGlobalVariableLookup(ctxt, name, ns_uri));
-    }
-    if (elem->computed == 0) {
-#ifdef WITH_XSLT_DEBUG_VARIABLE
-       XSLT_TRACE(ctxt,XSLT_TRACE_VARIABLES,xsltGenericDebug(xsltGenericDebugContext,
-                        "uncomputed variable %s\n", name));
-#endif
-        elem->value = xsltEvalVariable(ctxt, elem, NULL);
-       elem->computed = 1;
-    }
-    if (elem->value != NULL)
-       return(xmlXPathObjectCopy(elem->value));
-#ifdef WITH_XSLT_DEBUG_VARIABLE
-    XSLT_TRACE(ctxt,XSLT_TRACE_VARIABLES,xsltGenericDebug(xsltGenericDebugContext,
-                    "variable not found %s\n", name));
-#endif
-    return(NULL);
-}
-
-/**
- * xsltParseStylesheetCallerParam:
- * @ctxt:  the XSLT transformation context
- * @inst:  the xsl:with-param instruction element
- *
- * Processes an xsl:with-param instruction at transformation time.
- * The value is compute, but not recorded.
- * NOTE that this is also called with an *xsl:param* element
- * from exsltFuncFunctionFunction().
- *
- * Returns the new xsltStackElemPtr or NULL
- */
-
-xsltStackElemPtr
-xsltParseStylesheetCallerParam(xsltTransformContextPtr ctxt, xmlNodePtr inst)
-{
-#ifdef XSLT_REFACTORED
-    xsltStyleBasicItemVariablePtr comp;
-#else
-    xsltStylePreCompPtr comp;
-#endif
-    xmlNodePtr tree = NULL; /* The first child node of the instruction or
-                               the instruction itself. */
-    xsltStackElemPtr param = NULL;
-
-    if ((ctxt == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
-       return(NULL);
-
-#ifdef XSLT_REFACTORED
-    comp = (xsltStyleBasicItemVariablePtr) inst->psvi;
-#else
-    comp = (xsltStylePreCompPtr) inst->psvi;
-#endif
-
-    if (comp == NULL) {
-        xsltTransformError(ctxt, NULL, inst,
-           "Internal error in xsltParseStylesheetCallerParam(): "
-           "The XSLT 'with-param' instruction was not compiled.\n");
-        return(NULL);
-    }
-    if (comp->name == NULL) {
-       xsltTransformError(ctxt, NULL, inst,
-           "Internal error in xsltParseStylesheetCallerParam(): "
-           "XSLT 'with-param': The attribute 'name' was not compiled.\n");
-       return(NULL);
-    }
-
-#ifdef WITH_XSLT_DEBUG_VARIABLE
-    XSLT_TRACE(ctxt,XSLT_TRACE_VARIABLES,xsltGenericDebug(xsltGenericDebugContext,
-           "Handling xsl:with-param %s\n", comp->name));
-#endif
-
-    if (comp->select == NULL) {
-       tree = inst->children;
-    } else {
-#ifdef WITH_XSLT_DEBUG_VARIABLE
-       XSLT_TRACE(ctxt,XSLT_TRACE_VARIABLES,xsltGenericDebug(xsltGenericDebugContext,
-           "        select %s\n", comp->select));
-#endif
-       tree = inst;
-    }
-
-    param = xsltBuildVariable(ctxt, (xsltStylePreCompPtr) comp, tree);
-
-    return(param);
-}
-
-/**
- * xsltParseGlobalVariable:
- * @style:  the XSLT stylesheet
- * @cur:  the "variable" element
- *
- * Parses a global XSLT 'variable' declaration at compilation time
- * and registers it
- */
-void
-xsltParseGlobalVariable(xsltStylesheetPtr style, xmlNodePtr cur)
-{
-#ifdef XSLT_REFACTORED
-    xsltStyleItemVariablePtr comp;
-#else
-    xsltStylePreCompPtr comp;
-#endif
-
-    if ((cur == NULL) || (style == NULL) || (cur->type != XML_ELEMENT_NODE))
-       return;
-
-#ifdef XSLT_REFACTORED
-    /*
-    * Note that xsltStylePreCompute() will be called from
-    * xslt.c only.
-    */
-    comp = (xsltStyleItemVariablePtr) cur->psvi;
-#else
-    xsltStylePreCompute(style, cur);
-    comp = (xsltStylePreCompPtr) cur->psvi;
-#endif
-    if (comp == NULL) {
-       xsltTransformError(NULL, style, cur,
-            "xsl:variable : compilation failed\n");
-       return;
-    }
-
-    if (comp->name == NULL) {
-       xsltTransformError(NULL, style, cur,
-           "xsl:variable : missing name attribute\n");
-       return;
-    }
-
-    /*
-    * Parse the content (a sequence constructor) of xsl:variable.
-    */
-    if (cur->children != NULL) {
-#ifdef XSLT_REFACTORED
-        xsltParseSequenceConstructor(XSLT_CCTXT(style), cur->children);
-#else
-        xsltParseTemplateContent(style, cur);
-#endif
-    }
-#ifdef WITH_XSLT_DEBUG_VARIABLE
-    xsltGenericDebug(xsltGenericDebugContext,
-       "Registering global variable %s\n", comp->name);
-#endif
-
-    xsltRegisterGlobalVariable(style, comp->name, comp->ns,
-       comp->select, cur->children, (xsltStylePreCompPtr) comp,
-       NULL);
-}
-
-/**
- * xsltParseGlobalParam:
- * @style:  the XSLT stylesheet
- * @cur:  the "param" element
- *
- * parse an XSLT transformation param declaration and record
- * its value.
- */
-
-void
-xsltParseGlobalParam(xsltStylesheetPtr style, xmlNodePtr cur) {
-#ifdef XSLT_REFACTORED
-    xsltStyleItemParamPtr comp;
-#else
-    xsltStylePreCompPtr comp;
-#endif
-
-    if ((cur == NULL) || (style == NULL) || (cur->type != XML_ELEMENT_NODE))
-       return;
-
-#ifdef XSLT_REFACTORED
-    /*
-    * Note that xsltStylePreCompute() will be called from
-    * xslt.c only.
-    */
-    comp = (xsltStyleItemParamPtr) cur->psvi;
-#else
-    xsltStylePreCompute(style, cur);
-    comp = (xsltStylePreCompPtr) cur->psvi;
-#endif
-    if (comp == NULL) {
-       xsltTransformError(NULL, style, cur,
-            "xsl:param : compilation failed\n");
-       return;
-    }
-
-    if (comp->name == NULL) {
-       xsltTransformError(NULL, style, cur,
-           "xsl:param : missing name attribute\n");
-       return;
-    }
-
-    /*
-    * Parse the content (a sequence constructor) of xsl:param.
-    */
-    if (cur->children != NULL) {
-#ifdef XSLT_REFACTORED
-        xsltParseSequenceConstructor(XSLT_CCTXT(style), cur->children);
-#else
-        xsltParseTemplateContent(style, cur);
-#endif
-    }
-
-#ifdef WITH_XSLT_DEBUG_VARIABLE
-    xsltGenericDebug(xsltGenericDebugContext,
-       "Registering global param %s\n", comp->name);
-#endif
-
-    xsltRegisterGlobalVariable(style, comp->name, comp->ns,
-       comp->select, cur->children, (xsltStylePreCompPtr) comp,
-       NULL);
-}
-
-/**
- * xsltParseStylesheetVariable:
- * @ctxt:  the XSLT transformation context
- * @inst:  the xsl:variable instruction element
- *
- * Registers a local XSLT 'variable' instruction at transformation time
- * and evaluates its value.
- */
-void
-xsltParseStylesheetVariable(xsltTransformContextPtr ctxt, xmlNodePtr inst)
-{
-#ifdef XSLT_REFACTORED
-    xsltStyleItemVariablePtr comp;
-#else
-    xsltStylePreCompPtr comp;
-#endif
-
-    if ((inst == NULL) || (ctxt == NULL) || (inst->type != XML_ELEMENT_NODE))
-       return;
-
-    comp = inst->psvi;
-    if (comp == NULL) {
-        xsltTransformError(ctxt, NULL, inst,
-           "Internal error in xsltParseStylesheetVariable(): "
-           "The XSLT 'variable' instruction was not compiled.\n");
-        return;
-    }
-    if (comp->name == NULL) {
-       xsltTransformError(ctxt, NULL, inst,
-           "Internal error in xsltParseStylesheetVariable(): "
-           "The attribute 'name' was not compiled.\n");
-       return;
-    }
-
-#ifdef WITH_XSLT_DEBUG_VARIABLE
-    XSLT_TRACE(ctxt,XSLT_TRACE_VARIABLES,xsltGenericDebug(xsltGenericDebugContext,
-       "Registering variable '%s'\n", comp->name));
-#endif
-
-    xsltRegisterVariable(ctxt, (xsltStylePreCompPtr) comp, inst->children, 0);
-}
-
-/**
- * xsltParseStylesheetParam:
- * @ctxt:  the XSLT transformation context
- * @cur:  the XSLT 'param' element
- *
- * Registers a local XSLT 'param' declaration at transformation time and
- * evaluates its value.
- */
-void
-xsltParseStylesheetParam(xsltTransformContextPtr ctxt, xmlNodePtr cur)
-{
-#ifdef XSLT_REFACTORED
-    xsltStyleItemParamPtr comp;
-#else
-    xsltStylePreCompPtr comp;
-#endif
-
-    if ((cur == NULL) || (ctxt == NULL) || (cur->type != XML_ELEMENT_NODE))
-       return;
-
-    comp = cur->psvi;
-    if ((comp == NULL) || (comp->name == NULL)) {
-       xsltTransformError(ctxt, NULL, cur,
-           "Internal error in xsltParseStylesheetParam(): "
-           "The XSLT 'param' declaration was not compiled correctly.\n");
-       return;
-    }
-
-#ifdef WITH_XSLT_DEBUG_VARIABLE
-    XSLT_TRACE(ctxt,XSLT_TRACE_VARIABLES,xsltGenericDebug(xsltGenericDebugContext,
-       "Registering param %s\n", comp->name));
-#endif
-
-    xsltRegisterVariable(ctxt, (xsltStylePreCompPtr) comp, cur->children, 1);
-}
-
-/**
- * xsltFreeGlobalVariables:
- * @ctxt:  the XSLT transformation context
- *
- * Free up the data associated to the global variables
- * its value.
- */
-
-void
-xsltFreeGlobalVariables(xsltTransformContextPtr ctxt) {
-    xmlHashFree(ctxt->globalVars, (xmlHashDeallocator) xsltFreeStackElem);
-}
-
-/**
- * xsltXPathVariableLookup:
- * @ctxt:  a void * but the the XSLT transformation context actually
- * @name:  the variable name
- * @ns_uri:  the variable namespace URI
- *
- * This is the entry point when a varibale is needed by the XPath
- * interpretor.
- *
- * Returns the value or NULL if not found
- */
-xmlXPathObjectPtr
-xsltXPathVariableLookup(void *ctxt, const xmlChar *name,
-                       const xmlChar *ns_uri) {
-    xsltTransformContextPtr tctxt;
-    xmlXPathObjectPtr valueObj = NULL;
-
-    if ((ctxt == NULL) || (name == NULL))
-       return(NULL);
-
-#ifdef WITH_XSLT_DEBUG_VARIABLE
-    XSLT_TRACE(((xsltTransformContextPtr)ctxt),XSLT_TRACE_VARIABLES,xsltGenericDebug(xsltGenericDebugContext,
-           "Lookup variable '%s'\n", name));
-#endif
-
-    tctxt = (xsltTransformContextPtr) ctxt;
-    /*
-    * Local variables/params ---------------------------------------------
-    *
-    * Do the lookup from the top of the stack, but
-    * don't use params being computed in a call-param
-    * First lookup expects the variable name and URI to
-    * come from the disctionnary and hence pointer comparison.
-    */
-    if (tctxt->varsNr != 0) {
-       int i;
-       xsltStackElemPtr variable = NULL, cur;
-
-       for (i = tctxt->varsNr; i > tctxt->varsBase; i--) {
-           cur = tctxt->varsTab[i-1];
-           if ((cur->name == name) && (cur->nameURI == ns_uri)) {
-#if 0
-               stack_addr++;
-#endif
-               variable = cur;
-               goto local_variable_found;
-           }
-           cur = cur->next;
-       }
-       /*
-       * Redo the lookup with interned strings to avoid string comparison.
-       *
-       * OPTIMIZE TODO: The problem here is, that if we request a
-       *  global variable, then this will be also executed.
-       */
-       {
-           const xmlChar *tmpName = name, *tmpNsName = ns_uri;
-
-           name = xmlDictLookup(tctxt->dict, name, -1);
-           if (ns_uri)
-               ns_uri = xmlDictLookup(tctxt->dict, ns_uri, -1);
-           if ((tmpName != name) || (tmpNsName != ns_uri)) {
-               for (i = tctxt->varsNr; i > tctxt->varsBase; i--) {
-                   cur = tctxt->varsTab[i-1];
-                   if ((cur->name == name) && (cur->nameURI == ns_uri)) {
-#if 0
-                       stack_cmp++;
-#endif
-                       variable = cur;
-                       goto local_variable_found;
-                   }
-               }
-           }
-       }
-
-local_variable_found:
-
-       if (variable) {
-           if (variable->computed == 0) {
-
-#ifdef WITH_XSLT_DEBUG_VARIABLE
-               XSLT_TRACE(tctxt,XSLT_TRACE_VARIABLES,xsltGenericDebug(xsltGenericDebugContext,
-                   "uncomputed variable '%s'\n", name));
-#endif
-               variable->value = xsltEvalVariable(tctxt, variable, NULL);
-               variable->computed = 1;
-           }
-           if (variable->value != NULL) {
-               valueObj = xmlXPathObjectCopy(variable->value);
-           }
-           return(valueObj);
-       }
-    }
-    /*
-    * Global variables/params --------------------------------------------
-    */
-    if (tctxt->globalVars) {
-       valueObj = xsltGlobalVariableLookup(tctxt, name, ns_uri);
-    }
-
-    if (valueObj == NULL) {
-
-#ifdef WITH_XSLT_DEBUG_VARIABLE
-    XSLT_TRACE(tctxt,XSLT_TRACE_VARIABLES,xsltGenericDebug(xsltGenericDebugContext,
-                    "variable not found '%s'\n", name));
-#endif
-
-       if (ns_uri) {
-           xsltTransformError(tctxt, NULL, tctxt->inst,
-               "Variable '{%s}%s' has not been declared.\n", ns_uri, name);
-       } else {
-           xsltTransformError(tctxt, NULL, tctxt->inst,
-               "Variable '%s' has not been declared.\n", name);
-       }
-    } else {
-
-#ifdef WITH_XSLT_DEBUG_VARIABLE
-       XSLT_TRACE(tctxt,XSLT_TRACE_VARIABLES,xsltGenericDebug(xsltGenericDebugContext,
-           "found variable '%s'\n", name));
-#endif
-    }
-
-    return(valueObj);
-}
-
-