Index: third_party/libxslt/libexslt/functions.c |
diff --git a/third_party/libxslt/libexslt/functions.c b/third_party/libxslt/libexslt/functions.c |
deleted file mode 100644 |
index c20ca16b48adfbe9ab4f17c7de226fdc29aeaea2..0000000000000000000000000000000000000000 |
--- a/third_party/libxslt/libexslt/functions.c |
+++ /dev/null |
@@ -1,795 +0,0 @@ |
-#define IN_LIBEXSLT |
-#include "libexslt/libexslt.h" |
- |
-#if defined(WIN32) && !defined (__CYGWIN__) && (!__MINGW32__) |
-#include <win32config.h> |
-#else |
-#include "config.h" |
-#endif |
- |
-#include <string.h> |
- |
-#include <libxml/tree.h> |
-#include <libxml/xpath.h> |
-#include <libxml/xpathInternals.h> |
-#include <libxml/hash.h> |
-#include <libxml/debugXML.h> |
- |
-#include <libxslt/xsltutils.h> |
-#include <libxslt/variables.h> |
-#include <libxslt/xsltInternals.h> |
-#include <libxslt/extensions.h> |
-#include <libxslt/transform.h> |
-#include <libxslt/imports.h> |
- |
-#include "exslt.h" |
- |
-typedef struct _exsltFuncFunctionData exsltFuncFunctionData; |
-struct _exsltFuncFunctionData { |
- int nargs; /* number of arguments to the function */ |
- xmlNodePtr content; /* the func:fuction template content */ |
-}; |
- |
-typedef struct _exsltFuncData exsltFuncData; |
-struct _exsltFuncData { |
- xmlHashTablePtr funcs; /* pointer to the stylesheet module data */ |
- xmlXPathObjectPtr result; /* returned by func:result */ |
- int error; /* did an error occur? */ |
-}; |
- |
-typedef struct _exsltFuncResultPreComp exsltFuncResultPreComp; |
-struct _exsltFuncResultPreComp { |
- xsltElemPreComp comp; |
- xmlXPathCompExprPtr select; |
- xmlNsPtr *nsList; |
- int nsNr; |
-}; |
- |
-/* Used for callback function in exsltInitFunc */ |
-typedef struct _exsltFuncImportRegData exsltFuncImportRegData; |
-struct _exsltFuncImportRegData { |
- xsltTransformContextPtr ctxt; |
- xmlHashTablePtr hash; |
-}; |
- |
-static void exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, |
- int nargs); |
-static exsltFuncFunctionData *exsltFuncNewFunctionData(void); |
- |
-/*static const xmlChar *exsltResultDataID = (const xmlChar *) "EXSLT Result";*/ |
- |
-/** |
- * exsltFuncRegisterFunc: |
- * @func: the #exsltFuncFunctionData for the function |
- * @ctxt: an XSLT transformation context |
- * @URI: the function namespace URI |
- * @name: the function name |
- * |
- * Registers a function declared by a func:function element |
- */ |
-static void |
-exsltFuncRegisterFunc (exsltFuncFunctionData *data, |
- xsltTransformContextPtr ctxt, |
- const xmlChar *URI, const xmlChar *name, |
- ATTRIBUTE_UNUSED const xmlChar *ignored) { |
- if ((data == NULL) || (ctxt == NULL) || (URI == NULL) || (name == NULL)) |
- return; |
- |
- xsltGenericDebug(xsltGenericDebugContext, |
- "exsltFuncRegisterFunc: register {%s}%s\n", |
- URI, name); |
- xsltRegisterExtFunction(ctxt, name, URI, |
- exsltFuncFunctionFunction); |
-} |
- |
-/* |
- * exsltFuncRegisterImportFunc |
- * @data: the exsltFuncFunctionData for the function |
- * @ch: structure containing context and hash table |
- * @URI: the function namespace URI |
- * @name: the function name |
- * |
- * Checks if imported function is already registered in top-level |
- * stylesheet. If not, copies function data and registers function |
- */ |
-static void |
-exsltFuncRegisterImportFunc (exsltFuncFunctionData *data, |
- exsltFuncImportRegData *ch, |
- const xmlChar *URI, const xmlChar *name, |
- ATTRIBUTE_UNUSED const xmlChar *ignored) { |
- exsltFuncFunctionData *func=NULL; |
- |
- if ((data == NULL) || (ch == NULL) || (URI == NULL) || (name == NULL)) |
- return; |
- |
- if (ch->ctxt == NULL || ch->hash == NULL) |
- return; |
- |
- /* Check if already present */ |
- func = (exsltFuncFunctionData*)xmlHashLookup2(ch->hash, URI, name); |
- if (func == NULL) { /* Not yet present - copy it in */ |
- func = exsltFuncNewFunctionData(); |
- if (func == NULL) |
- return; |
- memcpy(func, data, sizeof(exsltFuncFunctionData)); |
- if (xmlHashAddEntry2(ch->hash, URI, name, func) < 0) { |
- xsltGenericError(xsltGenericErrorContext, |
- "Failed to register function {%s}%s\n", |
- URI, name); |
- } else { /* Do the registration */ |
- xsltGenericDebug(xsltGenericDebugContext, |
- "exsltFuncRegisterImportFunc: register {%s}%s\n", |
- URI, name); |
- xsltRegisterExtFunction(ch->ctxt, name, URI, |
- exsltFuncFunctionFunction); |
- } |
- } |
-} |
- |
-/** |
- * exsltFuncInit: |
- * @ctxt: an XSLT transformation context |
- * @URI: the namespace URI for the extension |
- * |
- * Initializes the EXSLT - Functions module. |
- * Called at transformation-time; merges all |
- * functions declared in the import tree taking |
- * import precedence into account, i.e. overriding |
- * functions with lower import precedence. |
- * |
- * Returns the data for this transformation |
- */ |
-static exsltFuncData * |
-exsltFuncInit (xsltTransformContextPtr ctxt, const xmlChar *URI) { |
- exsltFuncData *ret; |
- xsltStylesheetPtr tmp; |
- exsltFuncImportRegData ch; |
- xmlHashTablePtr hash; |
- |
- ret = (exsltFuncData *) xmlMalloc (sizeof(exsltFuncData)); |
- if (ret == NULL) { |
- xsltGenericError(xsltGenericErrorContext, |
- "exsltFuncInit: not enough memory\n"); |
- return(NULL); |
- } |
- memset(ret, 0, sizeof(exsltFuncData)); |
- |
- ret->result = NULL; |
- ret->error = 0; |
- |
- ch.hash = (xmlHashTablePtr) xsltStyleGetExtData(ctxt->style, URI); |
- ret->funcs = ch.hash; |
- xmlHashScanFull(ch.hash, (xmlHashScannerFull) exsltFuncRegisterFunc, ctxt); |
- tmp = ctxt->style; |
- ch.ctxt = ctxt; |
- while ((tmp=xsltNextImport(tmp))!=NULL) { |
- hash = xsltGetExtInfo(tmp, URI); |
- if (hash != NULL) { |
- xmlHashScanFull(hash, |
- (xmlHashScannerFull) exsltFuncRegisterImportFunc, &ch); |
- } |
- } |
- |
- return(ret); |
-} |
- |
-/** |
- * exsltFuncShutdown: |
- * @ctxt: an XSLT transformation context |
- * @URI: the namespace URI for the extension |
- * @data: the module data to free up |
- * |
- * Shutdown the EXSLT - Functions module |
- * Called at transformation-time. |
- */ |
-static void |
-exsltFuncShutdown (xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED, |
- const xmlChar *URI ATTRIBUTE_UNUSED, |
- exsltFuncData *data) { |
- if (data->result != NULL) |
- xmlXPathFreeObject(data->result); |
- xmlFree(data); |
-} |
- |
-/** |
- * exsltFuncStyleInit: |
- * @style: an XSLT stylesheet |
- * @URI: the namespace URI for the extension |
- * |
- * Allocates the stylesheet data for EXSLT - Function |
- * Called at compile-time. |
- * |
- * Returns the allocated data |
- */ |
-static xmlHashTablePtr |
-exsltFuncStyleInit (xsltStylesheetPtr style ATTRIBUTE_UNUSED, |
- const xmlChar *URI ATTRIBUTE_UNUSED) { |
- return xmlHashCreate(1); |
-} |
- |
-/** |
- * exsltFuncStyleShutdown: |
- * @style: an XSLT stylesheet |
- * @URI: the namespace URI for the extension |
- * @data: the stylesheet data to free up |
- * |
- * Shutdown the EXSLT - Function module |
- * Called at compile-time. |
- */ |
-static void |
-exsltFuncStyleShutdown (xsltStylesheetPtr style ATTRIBUTE_UNUSED, |
- const xmlChar *URI ATTRIBUTE_UNUSED, |
- xmlHashTablePtr data) { |
- xmlHashFree(data, (xmlHashDeallocator) xmlFree); |
-} |
- |
-/** |
- * exsltFuncNewFunctionData: |
- * |
- * Allocates an #exslFuncFunctionData object |
- * |
- * Returns the new structure |
- */ |
-static exsltFuncFunctionData * |
-exsltFuncNewFunctionData (void) { |
- exsltFuncFunctionData *ret; |
- |
- ret = (exsltFuncFunctionData *) xmlMalloc (sizeof(exsltFuncFunctionData)); |
- if (ret == NULL) { |
- xsltGenericError(xsltGenericErrorContext, |
- "exsltFuncNewFunctionData: not enough memory\n"); |
- return (NULL); |
- } |
- memset(ret, 0, sizeof(exsltFuncFunctionData)); |
- |
- ret->nargs = 0; |
- ret->content = NULL; |
- |
- return(ret); |
-} |
- |
-/** |
- * exsltFreeFuncResultPreComp: |
- * @comp: the #exsltFuncResultPreComp to free up |
- * |
- * Deallocates an #exsltFuncResultPreComp |
- */ |
-static void |
-exsltFreeFuncResultPreComp (exsltFuncResultPreComp *comp) { |
- if (comp == NULL) |
- return; |
- |
- if (comp->select != NULL) |
- xmlXPathFreeCompExpr (comp->select); |
- if (comp->nsList != NULL) |
- xmlFree(comp->nsList); |
- xmlFree(comp); |
-} |
- |
-/** |
- * exsltFuncFunctionFunction: |
- * @ctxt: an XPath parser context |
- * @nargs: the number of arguments |
- * |
- * Evaluates the func:function element that defines the called function. |
- */ |
-static void |
-exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) { |
- xmlXPathObjectPtr oldResult, ret; |
- exsltFuncData *data; |
- exsltFuncFunctionData *func; |
- xmlNodePtr paramNode, oldInsert, fake; |
- int oldBase; |
- xsltStackElemPtr params = NULL, param; |
- xsltTransformContextPtr tctxt = xsltXPathGetTransformContext(ctxt); |
- int i, notSet; |
- struct objChain { |
- struct objChain *next; |
- xmlXPathObjectPtr obj; |
- }; |
- struct objChain *savedObjChain = NULL, *savedObj; |
- |
- /* |
- * retrieve func:function template |
- */ |
- data = (exsltFuncData *) xsltGetExtData (tctxt, |
- EXSLT_FUNCTIONS_NAMESPACE); |
- oldResult = data->result; |
- data->result = NULL; |
- |
- func = (exsltFuncFunctionData*) xmlHashLookup2 (data->funcs, |
- ctxt->context->functionURI, |
- ctxt->context->function); |
- if (func == NULL) { |
- /* Should never happen */ |
- xsltGenericError(xsltGenericErrorContext, |
- "{%s}%s: not found\n", |
- ctxt->context->functionURI, ctxt->context->function); |
- ctxt->error = XPATH_UNKNOWN_FUNC_ERROR; |
- return; |
- } |
- |
- /* |
- * params handling |
- */ |
- if (nargs > func->nargs) { |
- xsltGenericError(xsltGenericErrorContext, |
- "{%s}%s: called with too many arguments\n", |
- ctxt->context->functionURI, ctxt->context->function); |
- ctxt->error = XPATH_INVALID_ARITY; |
- return; |
- } |
- if (func->content != NULL) { |
- paramNode = func->content->prev; |
- } |
- else |
- paramNode = NULL; |
- if ((paramNode == NULL) && (func->nargs != 0)) { |
- xsltGenericError(xsltGenericErrorContext, |
- "exsltFuncFunctionFunction: nargs != 0 and " |
- "param == NULL\n"); |
- return; |
- } |
- |
- /* |
- * When a function is called recursively during evaluation of its |
- * arguments, the recursion check in xsltApplySequenceConstructor |
- * isn't reached. |
- */ |
- if (tctxt->depth >= tctxt->maxTemplateDepth) { |
- xsltTransformError(tctxt, NULL, NULL, |
- "exsltFuncFunctionFunction: Potentially infinite recursion " |
- "detected in function {%s}%s.\n", |
- ctxt->context->functionURI, ctxt->context->function); |
- tctxt->state = XSLT_STATE_STOPPED; |
- return; |
- } |
- tctxt->depth++; |
- |
- /* |
- * We have a problem with the evaluation of function parameters. |
- * The original library code did not evaluate XPath expressions until |
- * the last moment. After version 1.1.17 of the libxslt, the logic |
- * of other parts of the library was changed, and the evaluation of |
- * XPath expressions within parameters now takes place as soon as the |
- * parameter is parsed/evaluated (xsltParseStylesheetCallerParam). |
- * This means that the parameters need to be evaluated in lexical |
- * order (since a variable is "in scope" as soon as it is declared). |
- * However, on entry to this routine, the values (from the caller) are |
- * in reverse order (held on the XPath context variable stack). To |
- * accomplish what is required, I have added code to pop the XPath |
- * objects off of the stack at the beginning and save them, then use |
- * them (in the reverse order) as the params are evaluated. This |
- * requires an xmlMalloc/xmlFree for each param set by the caller, |
- * which is not very nice. There is probably a much better solution |
- * (like change other code to delay the evaluation). |
- */ |
- /* |
- * In order to give the function params and variables a new 'scope' |
- * we change varsBase in the context. |
- */ |
- oldBase = tctxt->varsBase; |
- tctxt->varsBase = tctxt->varsNr; |
- /* If there are any parameters */ |
- if (paramNode != NULL) { |
- /* Fetch the stored argument values from the caller */ |
- for (i = 0; i < nargs; i++) { |
- savedObj = xmlMalloc(sizeof(struct objChain)); |
- savedObj->next = savedObjChain; |
- savedObj->obj = valuePop(ctxt); |
- savedObjChain = savedObj; |
- } |
- |
- /* |
- * Prepare to process params in reverse order. First, go to |
- * the beginning of the param chain. |
- */ |
- for (i = 1; i <= func->nargs; i++) { |
- if (paramNode->prev == NULL) |
- break; |
- paramNode = paramNode->prev; |
- } |
- /* |
- * i has total # params found, nargs is number which are present |
- * as arguments from the caller |
- * Calculate the number of un-set parameters |
- */ |
- notSet = func->nargs - nargs; |
- for (; i > 0; i--) { |
- param = xsltParseStylesheetCallerParam (tctxt, paramNode); |
- if (i > notSet) { /* if parameter value set */ |
- param->computed = 1; |
- if (param->value != NULL) |
- xmlXPathFreeObject(param->value); |
- savedObj = savedObjChain; /* get next val from chain */ |
- param->value = savedObj->obj; |
- savedObjChain = savedObjChain->next; |
- xmlFree(savedObj); |
- } |
- xsltLocalVariablePush(tctxt, param, -1); |
- param->next = params; |
- params = param; |
- paramNode = paramNode->next; |
- } |
- } |
- /* |
- * actual processing |
- */ |
- fake = xmlNewDocNode(tctxt->output, NULL, |
- (const xmlChar *)"fake", NULL); |
- oldInsert = tctxt->insert; |
- tctxt->insert = fake; |
- xsltApplyOneTemplate (tctxt, xmlXPathGetContextNode(ctxt), |
- func->content, NULL, NULL); |
- xsltLocalVariablePop(tctxt, tctxt->varsBase, -2); |
- tctxt->insert = oldInsert; |
- tctxt->varsBase = oldBase; /* restore original scope */ |
- if (params != NULL) |
- xsltFreeStackElemList(params); |
- |
- if (data->error != 0) |
- goto error; |
- |
- if (data->result != NULL) { |
- ret = data->result; |
- /* |
- * IMPORTANT: This enables previously tree fragments marked as |
- * being results of a function, to be garbage-collected after |
- * the calling process exits. |
- */ |
- xsltFlagRVTs(tctxt, ret, XSLT_RVT_LOCAL); |
- } else |
- ret = xmlXPathNewCString(""); |
- |
- data->result = oldResult; |
- |
- /* |
- * It is an error if the instantiation of the template results in |
- * the generation of result nodes. |
- */ |
- if (fake->children != NULL) { |
-#ifdef LIBXML_DEBUG_ENABLED |
- xmlDebugDumpNode (stderr, fake, 1); |
-#endif |
- xsltGenericError(xsltGenericErrorContext, |
- "{%s}%s: cannot write to result tree while " |
- "executing a function\n", |
- ctxt->context->functionURI, ctxt->context->function); |
- xmlFreeNode(fake); |
- goto error; |
- } |
- xmlFreeNode(fake); |
- valuePush(ctxt, ret); |
- |
-error: |
- tctxt->depth--; |
-} |
- |
- |
-static void |
-exsltFuncFunctionComp (xsltStylesheetPtr style, xmlNodePtr inst) { |
- xmlChar *name, *prefix; |
- xmlNsPtr ns; |
- xmlHashTablePtr data; |
- exsltFuncFunctionData *func; |
- |
- if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE)) |
- return; |
- |
- { |
- xmlChar *qname; |
- |
- qname = xmlGetProp(inst, (const xmlChar *) "name"); |
- name = xmlSplitQName2 (qname, &prefix); |
- xmlFree(qname); |
- } |
- if ((name == NULL) || (prefix == NULL)) { |
- xsltGenericError(xsltGenericErrorContext, |
- "func:function: not a QName\n"); |
- if (name != NULL) |
- xmlFree(name); |
- return; |
- } |
- /* namespace lookup */ |
- ns = xmlSearchNs (inst->doc, inst, prefix); |
- if (ns == NULL) { |
- xsltGenericError(xsltGenericErrorContext, |
- "func:function: undeclared prefix %s\n", |
- prefix); |
- xmlFree(name); |
- xmlFree(prefix); |
- return; |
- } |
- xmlFree(prefix); |
- |
- xsltParseTemplateContent(style, inst); |
- |
- /* |
- * Create function data |
- */ |
- func = exsltFuncNewFunctionData(); |
- if (func == NULL) { |
- xmlFree(name); |
- return; |
- } |
- func->content = inst->children; |
- while (IS_XSLT_ELEM(func->content) && |
- IS_XSLT_NAME(func->content, "param")) { |
- func->content = func->content->next; |
- func->nargs++; |
- } |
- |
- /* |
- * Register the function data such that it can be retrieved |
- * by exslFuncFunctionFunction |
- */ |
-#ifdef XSLT_REFACTORED |
- /* |
- * Ensure that the hash table will be stored in the *current* |
- * stylesheet level in order to correctly evaluate the |
- * import precedence. |
- */ |
- data = (xmlHashTablePtr) |
- xsltStyleStylesheetLevelGetExtData(style, |
- EXSLT_FUNCTIONS_NAMESPACE); |
-#else |
- data = (xmlHashTablePtr) |
- xsltStyleGetExtData (style, EXSLT_FUNCTIONS_NAMESPACE); |
-#endif |
- if (data == NULL) { |
- xsltGenericError(xsltGenericErrorContext, |
- "exsltFuncFunctionComp: no stylesheet data\n"); |
- xmlFree(name); |
- return; |
- } |
- |
- if (xmlHashAddEntry2 (data, ns->href, name, func) < 0) { |
- xsltTransformError(NULL, style, inst, |
- "Failed to register function {%s}%s\n", |
- ns->href, name); |
- style->errors++; |
- } else { |
- xsltGenericDebug(xsltGenericDebugContext, |
- "exsltFuncFunctionComp: register {%s}%s\n", |
- ns->href, name); |
- } |
- xmlFree(name); |
-} |
- |
-static xsltElemPreCompPtr |
-exsltFuncResultComp (xsltStylesheetPtr style, xmlNodePtr inst, |
- xsltTransformFunction function) { |
- xmlNodePtr test; |
- xmlChar *sel; |
- exsltFuncResultPreComp *ret; |
- |
- if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE)) |
- return (NULL); |
- |
- /* |
- * "Validity" checking |
- */ |
- /* it is an error to have any following sibling elements aside |
- * from the xsl:fallback element. |
- */ |
- for (test = inst->next; test != NULL; test = test->next) { |
- if (test->type != XML_ELEMENT_NODE) |
- continue; |
- if (IS_XSLT_ELEM(test) && IS_XSLT_NAME(test, "fallback")) |
- continue; |
- xsltGenericError(xsltGenericErrorContext, |
- "exsltFuncResultElem: only xsl:fallback is " |
- "allowed to follow func:result\n"); |
- style->errors++; |
- return (NULL); |
- } |
- /* it is an error for a func:result element to not be a descendant |
- * of func:function. |
- * it is an error if a func:result occurs within a func:result |
- * element. |
- * it is an error if instanciating the content of a variable |
- * binding element (i.e. xsl:variable, xsl:param) results in the |
- * instanciation of a func:result element. |
- */ |
- for (test = inst->parent; test != NULL; test = test->parent) { |
- if (IS_XSLT_ELEM(test) && |
- IS_XSLT_NAME(test, "stylesheet")) { |
- xsltGenericError(xsltGenericErrorContext, |
- "func:result element not a descendant " |
- "of a func:function\n"); |
- style->errors++; |
- return (NULL); |
- } |
- if ((test->ns != NULL) && |
- (xmlStrEqual(test->ns->href, EXSLT_FUNCTIONS_NAMESPACE))) { |
- if (xmlStrEqual(test->name, (const xmlChar *) "function")) { |
- break; |
- } |
- if (xmlStrEqual(test->name, (const xmlChar *) "result")) { |
- xsltGenericError(xsltGenericErrorContext, |
- "func:result element not allowed within" |
- " another func:result element\n"); |
- style->errors++; |
- return (NULL); |
- } |
- } |
- if (IS_XSLT_ELEM(test) && |
- (IS_XSLT_NAME(test, "variable") || |
- IS_XSLT_NAME(test, "param"))) { |
- xsltGenericError(xsltGenericErrorContext, |
- "func:result element not allowed within" |
- " a variable binding element\n"); |
- style->errors++; |
- return (NULL); |
- } |
- } |
- |
- /* |
- * Precomputation |
- */ |
- ret = (exsltFuncResultPreComp *) |
- xmlMalloc (sizeof(exsltFuncResultPreComp)); |
- if (ret == NULL) { |
- xsltPrintErrorContext(NULL, NULL, NULL); |
- xsltGenericError(xsltGenericErrorContext, |
- "exsltFuncResultComp : malloc failed\n"); |
- style->errors++; |
- return (NULL); |
- } |
- memset(ret, 0, sizeof(exsltFuncResultPreComp)); |
- |
- xsltInitElemPreComp ((xsltElemPreCompPtr) ret, style, inst, function, |
- (xsltElemPreCompDeallocator) exsltFreeFuncResultPreComp); |
- ret->select = NULL; |
- |
- /* |
- * Precompute the select attribute |
- */ |
- sel = xmlGetNsProp(inst, (const xmlChar *) "select", NULL); |
- if (sel != NULL) { |
- ret->select = xmlXPathCompile (sel); |
- xmlFree(sel); |
- } |
- /* |
- * Precompute the namespace list |
- */ |
- ret->nsList = xmlGetNsList(inst->doc, inst); |
- if (ret->nsList != NULL) { |
- int i = 0; |
- while (ret->nsList[i] != NULL) |
- i++; |
- ret->nsNr = i; |
- } |
- return ((xsltElemPreCompPtr) ret); |
-} |
- |
-static void |
-exsltFuncResultElem (xsltTransformContextPtr ctxt, |
- xmlNodePtr node ATTRIBUTE_UNUSED, xmlNodePtr inst, |
- exsltFuncResultPreComp *comp) { |
- exsltFuncData *data; |
- xmlXPathObjectPtr ret; |
- |
- |
- /* It is an error if instantiating the content of the |
- * func:function element results in the instantiation of more than |
- * one func:result elements. |
- */ |
- data = (exsltFuncData *) xsltGetExtData (ctxt, EXSLT_FUNCTIONS_NAMESPACE); |
- if (data == NULL) { |
- xsltGenericError(xsltGenericErrorContext, |
- "exsltFuncReturnElem: data == NULL\n"); |
- return; |
- } |
- if (data->result != NULL) { |
- xsltGenericError(xsltGenericErrorContext, |
- "func:result already instanciated\n"); |
- data->error = 1; |
- return; |
- } |
- /* |
- * Processing |
- */ |
- if (comp->select != NULL) { |
- xmlNsPtr *oldXPNsList; |
- int oldXPNsNr; |
- xmlNodePtr oldXPContextNode; |
- /* If the func:result element has a select attribute, then the |
- * value of the attribute must be an expression and the |
- * returned value is the object that results from evaluating |
- * the expression. In this case, the content must be empty. |
- */ |
- if (inst->children != NULL) { |
- xsltGenericError(xsltGenericErrorContext, |
- "func:result content must be empty if" |
- " the function has a select attribute\n"); |
- data->error = 1; |
- return; |
- } |
- oldXPNsList = ctxt->xpathCtxt->namespaces; |
- oldXPNsNr = ctxt->xpathCtxt->nsNr; |
- oldXPContextNode = ctxt->xpathCtxt->node; |
- |
- ctxt->xpathCtxt->namespaces = comp->nsList; |
- ctxt->xpathCtxt->nsNr = comp->nsNr; |
- |
- ret = xmlXPathCompiledEval(comp->select, ctxt->xpathCtxt); |
- |
- ctxt->xpathCtxt->node = oldXPContextNode; |
- ctxt->xpathCtxt->nsNr = oldXPNsNr; |
- ctxt->xpathCtxt->namespaces = oldXPNsList; |
- |
- if (ret == NULL) { |
- xsltGenericError(xsltGenericErrorContext, |
- "exsltFuncResultElem: ret == NULL\n"); |
- return; |
- } |
- /* |
- * Mark it as a function result in order to avoid garbage |
- * collecting of tree fragments before the function exits. |
- */ |
- xsltFlagRVTs(ctxt, ret, XSLT_RVT_FUNC_RESULT); |
- } else if (inst->children != NULL) { |
- /* If the func:result element does not have a select attribute |
- * and has non-empty content (i.e. the func:result element has |
- * one or more child nodes), then the content of the |
- * func:result element specifies the value. |
- */ |
- xmlNodePtr oldInsert; |
- xmlDocPtr container; |
- |
- container = xsltCreateRVT(ctxt); |
- if (container == NULL) { |
- xsltGenericError(xsltGenericErrorContext, |
- "exsltFuncResultElem: out of memory\n"); |
- data->error = 1; |
- return; |
- } |
- /* Mark as function result. */ |
- container->psvi = XSLT_RVT_FUNC_RESULT; |
- |
- oldInsert = ctxt->insert; |
- ctxt->insert = (xmlNodePtr) container; |
- xsltApplyOneTemplate (ctxt, ctxt->xpathCtxt->node, |
- inst->children, NULL, NULL); |
- ctxt->insert = oldInsert; |
- |
- ret = xmlXPathNewValueTree((xmlNodePtr) container); |
- if (ret == NULL) { |
- xsltGenericError(xsltGenericErrorContext, |
- "exsltFuncResultElem: ret == NULL\n"); |
- data->error = 1; |
- } else { |
- ret->boolval = 0; /* Freeing is not handled there anymore */ |
- } |
- } else { |
- /* If the func:result element has empty content and does not |
- * have a select attribute, then the returned value is an |
- * empty string. |
- */ |
- ret = xmlXPathNewCString(""); |
- } |
- data->result = ret; |
-} |
- |
-/** |
- * exsltFuncRegister: |
- * |
- * Registers the EXSLT - Functions module |
- */ |
-void |
-exsltFuncRegister (void) { |
- xsltRegisterExtModuleFull (EXSLT_FUNCTIONS_NAMESPACE, |
- (xsltExtInitFunction) exsltFuncInit, |
- (xsltExtShutdownFunction) exsltFuncShutdown, |
- (xsltStyleExtInitFunction) exsltFuncStyleInit, |
- (xsltStyleExtShutdownFunction) exsltFuncStyleShutdown); |
- |
- xsltRegisterExtModuleTopLevel ((const xmlChar *) "function", |
- EXSLT_FUNCTIONS_NAMESPACE, |
- exsltFuncFunctionComp); |
- xsltRegisterExtModuleElement ((const xmlChar *) "result", |
- EXSLT_FUNCTIONS_NAMESPACE, |
- (xsltPreComputeFunction)exsltFuncResultComp, |
- (xsltTransformFunction) exsltFuncResultElem); |
-} |