Index: third_party/libxslt/libxslt/functions.c |
diff --git a/third_party/libxslt/libxslt/functions.c b/third_party/libxslt/libxslt/functions.c |
deleted file mode 100644 |
index 5cc9da59244e6e49f56fb9fbb4537fe5eda7d7d7..0000000000000000000000000000000000000000 |
--- a/third_party/libxslt/libxslt/functions.c |
+++ /dev/null |
@@ -1,1005 +0,0 @@ |
-/* |
- * functions.c: Implementation of the XSLT extra functions |
- * |
- * Reference: |
- * http://www.w3.org/TR/1999/REC-xslt-19991116 |
- * |
- * See Copyright for the status of this software. |
- * |
- * daniel@veillard.com |
- * Bjorn Reese <breese@users.sourceforge.net> for number formatting |
- */ |
- |
-#define IN_LIBXSLT |
-#include "libxslt.h" |
- |
-#include <string.h> |
- |
-#ifdef HAVE_SYS_TYPES_H |
-#include <sys/types.h> |
-#endif |
-#ifdef HAVE_CTYPE_H |
-#include <ctype.h> |
-#endif |
- |
-#include <libxml/xmlmemory.h> |
-#include <libxml/parser.h> |
-#include <libxml/tree.h> |
-#include <libxml/valid.h> |
-#include <libxml/hash.h> |
-#include <libxml/xmlerror.h> |
-#include <libxml/xpath.h> |
-#include <libxml/xpathInternals.h> |
-#include <libxml/parserInternals.h> |
-#include <libxml/uri.h> |
-#include <libxml/xpointer.h> |
-#include "xslt.h" |
-#include "xsltInternals.h" |
-#include "xsltutils.h" |
-#include "functions.h" |
-#include "extensions.h" |
-#include "numbersInternals.h" |
-#include "keys.h" |
-#include "documents.h" |
- |
-#ifdef WITH_XSLT_DEBUG |
-#define WITH_XSLT_DEBUG_FUNCTION |
-#endif |
- |
-/* |
- * Some versions of DocBook XSL use the vendor string to detect |
- * supporting chunking, this is a workaround to be considered |
- * in the list of decent XSLT processors <grin/> |
- */ |
-#define DOCBOOK_XSL_HACK |
- |
-/** |
- * xsltXPathFunctionLookup: |
- * @ctxt: a void * but the XSLT transformation context actually |
- * @name: the function name |
- * @ns_uri: the function namespace URI |
- * |
- * This is the entry point when a function is needed by the XPath |
- * interpretor. |
- * |
- * Returns the callback function or NULL if not found |
- */ |
-xmlXPathFunction |
-xsltXPathFunctionLookup (xmlXPathContextPtr ctxt, |
- const xmlChar *name, const xmlChar *ns_uri) { |
- xmlXPathFunction ret; |
- |
- if ((ctxt == NULL) || (name == NULL) || (ns_uri == NULL)) |
- return (NULL); |
- |
-#ifdef WITH_XSLT_DEBUG_FUNCTION |
- xsltGenericDebug(xsltGenericDebugContext, |
- "Lookup function {%s}%s\n", ns_uri, name); |
-#endif |
- |
- /* give priority to context-level functions */ |
- /* |
- ret = (xmlXPathFunction) xmlHashLookup2(ctxt->funcHash, name, ns_uri); |
- */ |
- XML_CAST_FPTR(ret) = xmlHashLookup2(ctxt->funcHash, name, ns_uri); |
- |
- if (ret == NULL) |
- ret = xsltExtModuleFunctionLookup(name, ns_uri); |
- |
-#ifdef WITH_XSLT_DEBUG_FUNCTION |
- if (ret != NULL) |
- xsltGenericDebug(xsltGenericDebugContext, |
- "found function %s\n", name); |
-#endif |
- return(ret); |
-} |
- |
- |
-/************************************************************************ |
- * * |
- * Module interfaces * |
- * * |
- ************************************************************************/ |
- |
-static void |
-xsltDocumentFunctionLoadDocument(xmlXPathParserContextPtr ctxt, xmlChar* URI) |
-{ |
- xsltTransformContextPtr tctxt; |
- xmlURIPtr uri; |
- xmlChar *fragment; |
- xsltDocumentPtr idoc; /* document info */ |
- xmlDocPtr doc; |
- xmlXPathContextPtr xptrctxt = NULL; |
- xmlXPathObjectPtr resObj = NULL; |
- |
- tctxt = xsltXPathGetTransformContext(ctxt); |
- if (tctxt == NULL) { |
- xsltTransformError(NULL, NULL, NULL, |
- "document() : internal error tctxt == NULL\n"); |
- valuePush(ctxt, xmlXPathNewNodeSet(NULL)); |
- return; |
- } |
- |
- uri = xmlParseURI((const char *) URI); |
- if (uri == NULL) { |
- xsltTransformError(tctxt, NULL, NULL, |
- "document() : failed to parse URI\n"); |
- valuePush(ctxt, xmlXPathNewNodeSet(NULL)); |
- return; |
- } |
- |
- /* |
- * check for and remove fragment identifier |
- */ |
- fragment = (xmlChar *)uri->fragment; |
- if (fragment != NULL) { |
- xmlChar *newURI; |
- uri->fragment = NULL; |
- newURI = xmlSaveUri(uri); |
- idoc = xsltLoadDocument(tctxt, newURI); |
- xmlFree(newURI); |
- } else |
- idoc = xsltLoadDocument(tctxt, URI); |
- xmlFreeURI(uri); |
- |
- if (idoc == NULL) { |
- if ((URI == NULL) || |
- (URI[0] == '#') || |
- ((tctxt->style->doc != NULL) && |
- (xmlStrEqual(tctxt->style->doc->URL, URI)))) |
- { |
- /* |
- * This selects the stylesheet's doc itself. |
- */ |
- doc = tctxt->style->doc; |
- } else { |
- valuePush(ctxt, xmlXPathNewNodeSet(NULL)); |
- |
- if (fragment != NULL) |
- xmlFree(fragment); |
- |
- return; |
- } |
- } else |
- doc = idoc->doc; |
- |
- if (fragment == NULL) { |
- valuePush(ctxt, xmlXPathNewNodeSet((xmlNodePtr) doc)); |
- return; |
- } |
- |
- /* use XPointer of HTML location for fragment ID */ |
-#ifdef LIBXML_XPTR_ENABLED |
- xptrctxt = xmlXPtrNewContext(doc, NULL, NULL); |
- if (xptrctxt == NULL) { |
- xsltTransformError(tctxt, NULL, NULL, |
- "document() : internal error xptrctxt == NULL\n"); |
- goto out_fragment; |
- } |
- |
- resObj = xmlXPtrEval(fragment, xptrctxt); |
- xmlXPathFreeContext(xptrctxt); |
-#endif |
- |
- if (resObj == NULL) |
- goto out_fragment; |
- |
- switch (resObj->type) { |
- case XPATH_NODESET: |
- break; |
- case XPATH_UNDEFINED: |
- case XPATH_BOOLEAN: |
- case XPATH_NUMBER: |
- case XPATH_STRING: |
- case XPATH_POINT: |
- case XPATH_USERS: |
- case XPATH_XSLT_TREE: |
- case XPATH_RANGE: |
- case XPATH_LOCATIONSET: |
- xsltTransformError(tctxt, NULL, NULL, |
- "document() : XPointer does not select a node set: #%s\n", |
- fragment); |
- goto out_object; |
- } |
- |
- valuePush(ctxt, resObj); |
- xmlFree(fragment); |
- return; |
- |
-out_object: |
- xmlXPathFreeObject(resObj); |
- |
-out_fragment: |
- valuePush(ctxt, xmlXPathNewNodeSet(NULL)); |
- xmlFree(fragment); |
-} |
- |
-/** |
- * xsltDocumentFunction: |
- * @ctxt: the XPath Parser context |
- * @nargs: the number of arguments |
- * |
- * Implement the document() XSLT function |
- * node-set document(object, node-set?) |
- */ |
-void |
-xsltDocumentFunction(xmlXPathParserContextPtr ctxt, int nargs) |
-{ |
- xmlXPathObjectPtr obj, obj2 = NULL; |
- xmlChar *base = NULL, *URI; |
- |
- |
- if ((nargs < 1) || (nargs > 2)) { |
- xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, |
- "document() : invalid number of args %d\n", |
- nargs); |
- ctxt->error = XPATH_INVALID_ARITY; |
- return; |
- } |
- if (ctxt->value == NULL) { |
- xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, |
- "document() : invalid arg value\n"); |
- ctxt->error = XPATH_INVALID_TYPE; |
- return; |
- } |
- |
- if (nargs == 2) { |
- if (ctxt->value->type != XPATH_NODESET) { |
- xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, |
- "document() : invalid arg expecting a nodeset\n"); |
- ctxt->error = XPATH_INVALID_TYPE; |
- return; |
- } |
- |
- obj2 = valuePop(ctxt); |
- } |
- |
- if (ctxt->value->type == XPATH_NODESET) { |
- int i; |
- xmlXPathObjectPtr newobj, ret; |
- |
- obj = valuePop(ctxt); |
- ret = xmlXPathNewNodeSet(NULL); |
- |
- if ((obj != NULL) && obj->nodesetval) { |
- for (i = 0; i < obj->nodesetval->nodeNr; i++) { |
- valuePush(ctxt, |
- xmlXPathNewNodeSet(obj->nodesetval->nodeTab[i])); |
- xmlXPathStringFunction(ctxt, 1); |
- if (nargs == 2) { |
- valuePush(ctxt, xmlXPathObjectCopy(obj2)); |
- } else { |
- valuePush(ctxt, |
- xmlXPathNewNodeSet(obj->nodesetval-> |
- nodeTab[i])); |
- } |
- xsltDocumentFunction(ctxt, 2); |
- newobj = valuePop(ctxt); |
- ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval, |
- newobj->nodesetval); |
- xmlXPathFreeObject(newobj); |
- } |
- } |
- |
- if (obj != NULL) |
- xmlXPathFreeObject(obj); |
- if (obj2 != NULL) |
- xmlXPathFreeObject(obj2); |
- valuePush(ctxt, ret); |
- return; |
- } |
- /* |
- * Make sure it's converted to a string |
- */ |
- xmlXPathStringFunction(ctxt, 1); |
- if (ctxt->value->type != XPATH_STRING) { |
- xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, |
- "document() : invalid arg expecting a string\n"); |
- ctxt->error = XPATH_INVALID_TYPE; |
- if (obj2 != NULL) |
- xmlXPathFreeObject(obj2); |
- return; |
- } |
- obj = valuePop(ctxt); |
- if (obj->stringval == NULL) { |
- valuePush(ctxt, xmlXPathNewNodeSet(NULL)); |
- } else { |
- xsltTransformContextPtr tctxt; |
- tctxt = xsltXPathGetTransformContext(ctxt); |
- if ((obj2 != NULL) && (obj2->nodesetval != NULL) && |
- (obj2->nodesetval->nodeNr > 0) && |
- IS_XSLT_REAL_NODE(obj2->nodesetval->nodeTab[0])) { |
- xmlNodePtr target; |
- |
- target = obj2->nodesetval->nodeTab[0]; |
- if ((target->type == XML_ATTRIBUTE_NODE) || |
- (target->type == XML_PI_NODE)) { |
- target = ((xmlAttrPtr) target)->parent; |
- } |
- base = xmlNodeGetBase(target->doc, target); |
- } else { |
- if ((tctxt != NULL) && (tctxt->inst != NULL)) { |
- base = xmlNodeGetBase(tctxt->inst->doc, tctxt->inst); |
- } else if ((tctxt != NULL) && (tctxt->style != NULL) && |
- (tctxt->style->doc != NULL)) { |
- base = xmlNodeGetBase(tctxt->style->doc, |
- (xmlNodePtr) tctxt->style->doc); |
- } |
- } |
- URI = xmlBuildURI(obj->stringval, base); |
- if (base != NULL) |
- xmlFree(base); |
- if (URI == NULL) { |
- if ((tctxt != NULL) && (tctxt->style != NULL) && |
- (tctxt->style->doc != NULL) && |
- (xmlStrEqual(URI, tctxt->style->doc->URL))) { |
- /* This selects the stylesheet's doc itself. */ |
- valuePush(ctxt, xmlXPathNewNodeSet((xmlNodePtr) tctxt->style->doc)); |
- } else { |
- valuePush(ctxt, xmlXPathNewNodeSet(NULL)); |
- } |
- } else { |
- xsltDocumentFunctionLoadDocument( ctxt, URI ); |
- xmlFree(URI); |
- } |
- } |
- xmlXPathFreeObject(obj); |
- if (obj2 != NULL) |
- xmlXPathFreeObject(obj2); |
-} |
- |
-/** |
- * xsltKeyFunction: |
- * @ctxt: the XPath Parser context |
- * @nargs: the number of arguments |
- * |
- * Implement the key() XSLT function |
- * node-set key(string, object) |
- */ |
-void |
-xsltKeyFunction(xmlXPathParserContextPtr ctxt, int nargs){ |
- xmlXPathObjectPtr obj1, obj2; |
- |
- if (nargs != 2) { |
- xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, |
- "key() : expects two arguments\n"); |
- ctxt->error = XPATH_INVALID_ARITY; |
- return; |
- } |
- |
- /* |
- * Get the key's value. |
- */ |
- obj2 = valuePop(ctxt); |
- xmlXPathStringFunction(ctxt, 1); |
- if ((obj2 == NULL) || |
- (ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { |
- xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, |
- "key() : invalid arg expecting a string\n"); |
- ctxt->error = XPATH_INVALID_TYPE; |
- xmlXPathFreeObject(obj2); |
- |
- return; |
- } |
- /* |
- * Get the key's name. |
- */ |
- obj1 = valuePop(ctxt); |
- |
- if ((obj2->type == XPATH_NODESET) || (obj2->type == XPATH_XSLT_TREE)) { |
- int i; |
- xmlXPathObjectPtr newobj, ret; |
- |
- ret = xmlXPathNewNodeSet(NULL); |
- |
- if (obj2->nodesetval != NULL) { |
- for (i = 0; i < obj2->nodesetval->nodeNr; i++) { |
- valuePush(ctxt, xmlXPathObjectCopy(obj1)); |
- valuePush(ctxt, |
- xmlXPathNewNodeSet(obj2->nodesetval->nodeTab[i])); |
- xmlXPathStringFunction(ctxt, 1); |
- xsltKeyFunction(ctxt, 2); |
- newobj = valuePop(ctxt); |
- ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval, |
- newobj->nodesetval); |
- xmlXPathFreeObject(newobj); |
- } |
- } |
- valuePush(ctxt, ret); |
- } else { |
- xmlNodeSetPtr nodelist = NULL; |
- xmlChar *key = NULL, *value; |
- const xmlChar *keyURI; |
- xsltTransformContextPtr tctxt; |
- xmlChar *qname, *prefix; |
- xmlXPathContextPtr xpctxt = ctxt->context; |
- xmlNodePtr tmpNode = NULL; |
- xsltDocumentPtr oldDocInfo; |
- |
- tctxt = xsltXPathGetTransformContext(ctxt); |
- |
- oldDocInfo = tctxt->document; |
- |
- if (xpctxt->node == NULL) { |
- xsltTransformError(tctxt, NULL, tctxt->inst, |
- "Internal error in xsltKeyFunction(): " |
- "The context node is not set on the XPath context.\n"); |
- tctxt->state = XSLT_STATE_STOPPED; |
- goto error; |
- } |
- /* |
- * Get the associated namespace URI if qualified name |
- */ |
- qname = obj1->stringval; |
- key = xmlSplitQName2(qname, &prefix); |
- if (key == NULL) { |
- key = xmlStrdup(obj1->stringval); |
- keyURI = NULL; |
- if (prefix != NULL) |
- xmlFree(prefix); |
- } else { |
- if (prefix != NULL) { |
- keyURI = xmlXPathNsLookup(xpctxt, prefix); |
- if (keyURI == NULL) { |
- xsltTransformError(tctxt, NULL, tctxt->inst, |
- "key() : prefix %s is not bound\n", prefix); |
- /* |
- * TODO: Shouldn't we stop here? |
- */ |
- } |
- xmlFree(prefix); |
- } else { |
- keyURI = NULL; |
- } |
- } |
- |
- /* |
- * Force conversion of first arg to string |
- */ |
- valuePush(ctxt, obj2); |
- xmlXPathStringFunction(ctxt, 1); |
- if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { |
- xsltTransformError(tctxt, NULL, tctxt->inst, |
- "key() : invalid arg expecting a string\n"); |
- ctxt->error = XPATH_INVALID_TYPE; |
- goto error; |
- } |
- obj2 = valuePop(ctxt); |
- value = obj2->stringval; |
- |
- /* |
- * We need to ensure that ctxt->document is available for |
- * xsltGetKey(). |
- * First find the relevant doc, which is the context node's |
- * owner doc; using context->doc is not safe, since |
- * the doc could have been acquired via the document() function, |
- * or the doc might be a Result Tree Fragment. |
- * FUTURE INFO: In XSLT 2.0 the key() function takes an additional |
- * argument indicating the doc to use. |
- */ |
- if (xpctxt->node->type == XML_NAMESPACE_DECL) { |
- /* |
- * REVISIT: This is a libxml hack! Check xpath.c for details. |
- * The XPath module sets the owner element of a ns-node on |
- * the ns->next field. |
- */ |
- if ((((xmlNsPtr) xpctxt->node)->next != NULL) && |
- (((xmlNsPtr) xpctxt->node)->next->type == XML_ELEMENT_NODE)) |
- { |
- tmpNode = (xmlNodePtr) ((xmlNsPtr) xpctxt->node)->next; |
- } |
- } else |
- tmpNode = xpctxt->node; |
- |
- if ((tmpNode == NULL) || (tmpNode->doc == NULL)) { |
- xsltTransformError(tctxt, NULL, tctxt->inst, |
- "Internal error in xsltKeyFunction(): " |
- "Couldn't get the doc of the XPath context node.\n"); |
- goto error; |
- } |
- |
- if ((tctxt->document == NULL) || |
- (tctxt->document->doc != tmpNode->doc)) |
- { |
- if (tmpNode->doc->name && (tmpNode->doc->name[0] == ' ')) { |
- /* |
- * This is a Result Tree Fragment. |
- */ |
- if (tmpNode->doc->_private == NULL) { |
- tmpNode->doc->_private = xsltNewDocument(tctxt, tmpNode->doc); |
- if (tmpNode->doc->_private == NULL) |
- goto error; |
- } |
- tctxt->document = (xsltDocumentPtr) tmpNode->doc->_private; |
- } else { |
- /* |
- * May be the initial source doc or a doc acquired via the |
- * document() function. |
- */ |
- tctxt->document = xsltFindDocument(tctxt, tmpNode->doc); |
- } |
- if (tctxt->document == NULL) { |
- xsltTransformError(tctxt, NULL, tctxt->inst, |
- "Internal error in xsltKeyFunction(): " |
- "Could not get the document info of a context doc.\n"); |
- tctxt->state = XSLT_STATE_STOPPED; |
- goto error; |
- } |
- } |
- /* |
- * Get/compute the key value. |
- */ |
- nodelist = xsltGetKey(tctxt, key, keyURI, value); |
- |
-error: |
- tctxt->document = oldDocInfo; |
- valuePush(ctxt, xmlXPathWrapNodeSet( |
- xmlXPathNodeSetMerge(NULL, nodelist))); |
- if (key != NULL) |
- xmlFree(key); |
- } |
- |
- if (obj1 != NULL) |
- xmlXPathFreeObject(obj1); |
- if (obj2 != NULL) |
- xmlXPathFreeObject(obj2); |
-} |
- |
-/** |
- * xsltUnparsedEntityURIFunction: |
- * @ctxt: the XPath Parser context |
- * @nargs: the number of arguments |
- * |
- * Implement the unparsed-entity-uri() XSLT function |
- * string unparsed-entity-uri(string) |
- */ |
-void |
-xsltUnparsedEntityURIFunction(xmlXPathParserContextPtr ctxt, int nargs){ |
- xmlXPathObjectPtr obj; |
- xmlChar *str; |
- |
- if ((nargs != 1) || (ctxt->value == NULL)) { |
- xsltGenericError(xsltGenericErrorContext, |
- "unparsed-entity-uri() : expects one string arg\n"); |
- ctxt->error = XPATH_INVALID_ARITY; |
- return; |
- } |
- obj = valuePop(ctxt); |
- if (obj->type != XPATH_STRING) { |
- obj = xmlXPathConvertString(obj); |
- } |
- |
- str = obj->stringval; |
- if (str == NULL) { |
- valuePush(ctxt, xmlXPathNewString((const xmlChar *)"")); |
- } else { |
- xmlEntityPtr entity; |
- |
- entity = xmlGetDocEntity(ctxt->context->doc, str); |
- if (entity == NULL) { |
- valuePush(ctxt, xmlXPathNewString((const xmlChar *)"")); |
- } else { |
- if (entity->URI != NULL) |
- valuePush(ctxt, xmlXPathNewString(entity->URI)); |
- else |
- valuePush(ctxt, xmlXPathNewString((const xmlChar *)"")); |
- } |
- } |
- xmlXPathFreeObject(obj); |
-} |
- |
-/** |
- * xsltFormatNumberFunction: |
- * @ctxt: the XPath Parser context |
- * @nargs: the number of arguments |
- * |
- * Implement the format-number() XSLT function |
- * string format-number(number, string, string?) |
- */ |
-void |
-xsltFormatNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) |
-{ |
- xmlXPathObjectPtr numberObj = NULL; |
- xmlXPathObjectPtr formatObj = NULL; |
- xmlXPathObjectPtr decimalObj = NULL; |
- xsltStylesheetPtr sheet; |
- xsltDecimalFormatPtr formatValues = NULL; |
- xmlChar *result; |
- const xmlChar *ncname; |
- const xmlChar *prefix = NULL; |
- const xmlChar *nsUri = NULL; |
- xsltTransformContextPtr tctxt; |
- |
- tctxt = xsltXPathGetTransformContext(ctxt); |
- if ((tctxt == NULL) || (tctxt->inst == NULL)) |
- return; |
- sheet = tctxt->style; |
- if (sheet == NULL) |
- return; |
- formatValues = sheet->decimalFormat; |
- |
- switch (nargs) { |
- case 3: |
- CAST_TO_STRING; |
- decimalObj = valuePop(ctxt); |
- ncname = xsltSplitQName(sheet->dict, decimalObj->stringval, &prefix); |
- if (prefix != NULL) { |
- xmlNsPtr ns = xmlSearchNs(tctxt->inst->doc, tctxt->inst, prefix); |
- if (ns == NULL) { |
- xsltTransformError(tctxt, NULL, NULL, |
- "format-number : No namespace found for QName '%s:%s'\n", |
- prefix, ncname); |
- sheet->errors++; |
- ncname = NULL; |
- } |
- nsUri = ns->href; |
- } |
- if (ncname != NULL) { |
- formatValues = xsltDecimalFormatGetByQName(sheet, nsUri, ncname); |
- } |
- if (formatValues == NULL) { |
- xsltTransformError(tctxt, NULL, NULL, |
- "format-number() : undeclared decimal format '%s'\n", |
- decimalObj->stringval); |
- } |
- /* Intentional fall-through */ |
- case 2: |
- CAST_TO_STRING; |
- formatObj = valuePop(ctxt); |
- CAST_TO_NUMBER; |
- numberObj = valuePop(ctxt); |
- break; |
- default: |
- XP_ERROR(XPATH_INVALID_ARITY); |
- } |
- |
- if (formatValues != NULL) { |
- if (xsltFormatNumberConversion(formatValues, |
- formatObj->stringval, |
- numberObj->floatval, |
- &result) == XPATH_EXPRESSION_OK) { |
- valuePush(ctxt, xmlXPathNewString(result)); |
- xmlFree(result); |
- } |
- } |
- |
- xmlXPathFreeObject(numberObj); |
- xmlXPathFreeObject(formatObj); |
- xmlXPathFreeObject(decimalObj); |
-} |
- |
-/** |
- * xsltGenerateIdFunction: |
- * @ctxt: the XPath Parser context |
- * @nargs: the number of arguments |
- * |
- * Implement the generate-id() XSLT function |
- * string generate-id(node-set?) |
- */ |
-void |
-xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){ |
- static char base_address; |
- xmlNodePtr cur = NULL; |
- xmlXPathObjectPtr obj = NULL; |
- long val; |
- xmlChar str[30]; |
- |
- if (nargs == 0) { |
- cur = ctxt->context->node; |
- } else if (nargs == 1) { |
- xmlNodeSetPtr nodelist; |
- int i, ret; |
- |
- if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_NODESET)) { |
- ctxt->error = XPATH_INVALID_TYPE; |
- xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, |
- "generate-id() : invalid arg expecting a node-set\n"); |
- return; |
- } |
- obj = valuePop(ctxt); |
- nodelist = obj->nodesetval; |
- if ((nodelist == NULL) || (nodelist->nodeNr <= 0)) { |
- xmlXPathFreeObject(obj); |
- valuePush(ctxt, xmlXPathNewCString("")); |
- return; |
- } |
- cur = nodelist->nodeTab[0]; |
- for (i = 1;i < nodelist->nodeNr;i++) { |
- ret = xmlXPathCmpNodes(cur, nodelist->nodeTab[i]); |
- if (ret == -1) |
- cur = nodelist->nodeTab[i]; |
- } |
- } else { |
- xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, |
- "generate-id() : invalid number of args %d\n", nargs); |
- ctxt->error = XPATH_INVALID_ARITY; |
- return; |
- } |
- |
- if (obj) |
- xmlXPathFreeObject(obj); |
- |
- val = (long)((char *)cur - (char *)&base_address); |
- if (val >= 0) { |
- snprintf((char *)str, sizeof(str), "idp%ld", val); |
- } else { |
- snprintf((char *)str, sizeof(str), "idm%ld", -val); |
- } |
- valuePush(ctxt, xmlXPathNewString(str)); |
-} |
- |
-/** |
- * xsltSystemPropertyFunction: |
- * @ctxt: the XPath Parser context |
- * @nargs: the number of arguments |
- * |
- * Implement the system-property() XSLT function |
- * object system-property(string) |
- */ |
-void |
-xsltSystemPropertyFunction(xmlXPathParserContextPtr ctxt, int nargs){ |
- xmlXPathObjectPtr obj; |
- xmlChar *prefix, *name; |
- const xmlChar *nsURI = NULL; |
- |
- if (nargs != 1) { |
- xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, |
- "system-property() : expects one string arg\n"); |
- ctxt->error = XPATH_INVALID_ARITY; |
- return; |
- } |
- if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { |
- xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, |
- "system-property() : invalid arg expecting a string\n"); |
- ctxt->error = XPATH_INVALID_TYPE; |
- return; |
- } |
- obj = valuePop(ctxt); |
- if (obj->stringval == NULL) { |
- valuePush(ctxt, xmlXPathNewString((const xmlChar *)"")); |
- } else { |
- name = xmlSplitQName2(obj->stringval, &prefix); |
- if (name == NULL) { |
- name = xmlStrdup(obj->stringval); |
- } else { |
- nsURI = xmlXPathNsLookup(ctxt->context, prefix); |
- if (nsURI == NULL) { |
- xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, |
- "system-property() : prefix %s is not bound\n", prefix); |
- } |
- } |
- |
- if (xmlStrEqual(nsURI, XSLT_NAMESPACE)) { |
-#ifdef DOCBOOK_XSL_HACK |
- if (xmlStrEqual(name, (const xmlChar *)"vendor")) { |
- xsltStylesheetPtr sheet; |
- xsltTransformContextPtr tctxt; |
- |
- tctxt = xsltXPathGetTransformContext(ctxt); |
- if ((tctxt != NULL) && (tctxt->inst != NULL) && |
- (xmlStrEqual(tctxt->inst->name, BAD_CAST "variable")) && |
- (tctxt->inst->parent != NULL) && |
- (xmlStrEqual(tctxt->inst->parent->name, |
- BAD_CAST "template"))) |
- sheet = tctxt->style; |
- else |
- sheet = NULL; |
- if ((sheet != NULL) && (sheet->doc != NULL) && |
- (sheet->doc->URL != NULL) && |
- (xmlStrstr(sheet->doc->URL, |
- (const xmlChar *)"chunk") != NULL)) { |
- valuePush(ctxt, xmlXPathNewString( |
- (const xmlChar *)"libxslt (SAXON 6.2 compatible)")); |
- |
- } else { |
- valuePush(ctxt, xmlXPathNewString( |
- (const xmlChar *)XSLT_DEFAULT_VENDOR)); |
- } |
- } else |
-#else |
- if (xmlStrEqual(name, (const xmlChar *)"vendor")) { |
- valuePush(ctxt, xmlXPathNewString( |
- (const xmlChar *)XSLT_DEFAULT_VENDOR)); |
- } else |
-#endif |
- if (xmlStrEqual(name, (const xmlChar *)"version")) { |
- valuePush(ctxt, xmlXPathNewString( |
- (const xmlChar *)XSLT_DEFAULT_VERSION)); |
- } else if (xmlStrEqual(name, (const xmlChar *)"vendor-url")) { |
- valuePush(ctxt, xmlXPathNewString( |
- (const xmlChar *)XSLT_DEFAULT_URL)); |
- } else { |
- valuePush(ctxt, xmlXPathNewString((const xmlChar *)"")); |
- } |
- } else { |
- valuePush(ctxt, xmlXPathNewString((const xmlChar *)"")); |
- } |
- if (name != NULL) |
- xmlFree(name); |
- if (prefix != NULL) |
- xmlFree(prefix); |
- } |
- xmlXPathFreeObject(obj); |
-} |
- |
-/** |
- * xsltElementAvailableFunction: |
- * @ctxt: the XPath Parser context |
- * @nargs: the number of arguments |
- * |
- * Implement the element-available() XSLT function |
- * boolean element-available(string) |
- */ |
-void |
-xsltElementAvailableFunction(xmlXPathParserContextPtr ctxt, int nargs){ |
- xmlXPathObjectPtr obj; |
- xmlChar *prefix, *name; |
- const xmlChar *nsURI = NULL; |
- xsltTransformContextPtr tctxt; |
- |
- if (nargs != 1) { |
- xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, |
- "element-available() : expects one string arg\n"); |
- ctxt->error = XPATH_INVALID_ARITY; |
- return; |
- } |
- xmlXPathStringFunction(ctxt, 1); |
- if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { |
- xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, |
- "element-available() : invalid arg expecting a string\n"); |
- ctxt->error = XPATH_INVALID_TYPE; |
- return; |
- } |
- obj = valuePop(ctxt); |
- tctxt = xsltXPathGetTransformContext(ctxt); |
- if ((tctxt == NULL) || (tctxt->inst == NULL)) { |
- xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, |
- "element-available() : internal error tctxt == NULL\n"); |
- xmlXPathFreeObject(obj); |
- valuePush(ctxt, xmlXPathNewBoolean(0)); |
- return; |
- } |
- |
- |
- name = xmlSplitQName2(obj->stringval, &prefix); |
- if (name == NULL) { |
- xmlNsPtr ns; |
- |
- name = xmlStrdup(obj->stringval); |
- ns = xmlSearchNs(tctxt->inst->doc, tctxt->inst, NULL); |
- if (ns != NULL) nsURI = ns->href; |
- } else { |
- nsURI = xmlXPathNsLookup(ctxt->context, prefix); |
- if (nsURI == NULL) { |
- xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, |
- "element-available() : prefix %s is not bound\n", prefix); |
- } |
- } |
- |
- if (xsltExtElementLookup(tctxt, name, nsURI) != NULL) { |
- valuePush(ctxt, xmlXPathNewBoolean(1)); |
- } else { |
- valuePush(ctxt, xmlXPathNewBoolean(0)); |
- } |
- |
- xmlXPathFreeObject(obj); |
- if (name != NULL) |
- xmlFree(name); |
- if (prefix != NULL) |
- xmlFree(prefix); |
-} |
- |
-/** |
- * xsltFunctionAvailableFunction: |
- * @ctxt: the XPath Parser context |
- * @nargs: the number of arguments |
- * |
- * Implement the function-available() XSLT function |
- * boolean function-available(string) |
- */ |
-void |
-xsltFunctionAvailableFunction(xmlXPathParserContextPtr ctxt, int nargs){ |
- xmlXPathObjectPtr obj; |
- xmlChar *prefix, *name; |
- const xmlChar *nsURI = NULL; |
- |
- if (nargs != 1) { |
- xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, |
- "function-available() : expects one string arg\n"); |
- ctxt->error = XPATH_INVALID_ARITY; |
- return; |
- } |
- xmlXPathStringFunction(ctxt, 1); |
- if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { |
- xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, |
- "function-available() : invalid arg expecting a string\n"); |
- ctxt->error = XPATH_INVALID_TYPE; |
- return; |
- } |
- obj = valuePop(ctxt); |
- |
- name = xmlSplitQName2(obj->stringval, &prefix); |
- if (name == NULL) { |
- name = xmlStrdup(obj->stringval); |
- } else { |
- nsURI = xmlXPathNsLookup(ctxt->context, prefix); |
- if (nsURI == NULL) { |
- xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, |
- "function-available() : prefix %s is not bound\n", prefix); |
- } |
- } |
- |
- if (xmlXPathFunctionLookupNS(ctxt->context, name, nsURI) != NULL) { |
- valuePush(ctxt, xmlXPathNewBoolean(1)); |
- } else { |
- valuePush(ctxt, xmlXPathNewBoolean(0)); |
- } |
- |
- xmlXPathFreeObject(obj); |
- if (name != NULL) |
- xmlFree(name); |
- if (prefix != NULL) |
- xmlFree(prefix); |
-} |
- |
-/** |
- * xsltCurrentFunction: |
- * @ctxt: the XPath Parser context |
- * @nargs: the number of arguments |
- * |
- * Implement the current() XSLT function |
- * node-set current() |
- */ |
-static void |
-xsltCurrentFunction(xmlXPathParserContextPtr ctxt, int nargs){ |
- xsltTransformContextPtr tctxt; |
- |
- if (nargs != 0) { |
- xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, |
- "current() : function uses no argument\n"); |
- ctxt->error = XPATH_INVALID_ARITY; |
- return; |
- } |
- tctxt = xsltXPathGetTransformContext(ctxt); |
- if (tctxt == NULL) { |
- xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, |
- "current() : internal error tctxt == NULL\n"); |
- valuePush(ctxt, xmlXPathNewNodeSet(NULL)); |
- } else { |
- valuePush(ctxt, xmlXPathNewNodeSet(tctxt->node)); /* current */ |
- } |
-} |
- |
-/************************************************************************ |
- * * |
- * Registration of XSLT and libxslt functions * |
- * * |
- ************************************************************************/ |
- |
-/** |
- * xsltRegisterAllFunctions: |
- * @ctxt: the XPath context |
- * |
- * Registers all default XSLT functions in this context |
- */ |
-void |
-xsltRegisterAllFunctions(xmlXPathContextPtr ctxt) |
-{ |
- xmlXPathRegisterFunc(ctxt, (const xmlChar *) "current", |
- xsltCurrentFunction); |
- xmlXPathRegisterFunc(ctxt, (const xmlChar *) "document", |
- xsltDocumentFunction); |
- xmlXPathRegisterFunc(ctxt, (const xmlChar *) "key", xsltKeyFunction); |
- xmlXPathRegisterFunc(ctxt, (const xmlChar *) "unparsed-entity-uri", |
- xsltUnparsedEntityURIFunction); |
- xmlXPathRegisterFunc(ctxt, (const xmlChar *) "format-number", |
- xsltFormatNumberFunction); |
- xmlXPathRegisterFunc(ctxt, (const xmlChar *) "generate-id", |
- xsltGenerateIdFunction); |
- xmlXPathRegisterFunc(ctxt, (const xmlChar *) "system-property", |
- xsltSystemPropertyFunction); |
- xmlXPathRegisterFunc(ctxt, (const xmlChar *) "element-available", |
- xsltElementAvailableFunction); |
- xmlXPathRegisterFunc(ctxt, (const xmlChar *) "function-available", |
- xsltFunctionAvailableFunction); |
-} |