Files correlati : cg0.exe cg0700a.msk cg0700b.msk cg3.exe cg4.exe Bug : Commento: Merge 1.0 libraries
321 lines
7.9 KiB
C
321 lines
7.9 KiB
C
#define IN_LIBEXSLT
|
|
#include "libexslt/libexslt.h"
|
|
|
|
#include <libxml/tree.h>
|
|
#include <libxml/xpath.h>
|
|
#include <libxml/xpathInternals.h>
|
|
|
|
#include <libxslt/xsltutils.h>
|
|
#include <libxslt/xsltInternals.h>
|
|
#include <libxslt/extensions.h>
|
|
|
|
#include "exslt.h"
|
|
|
|
/**
|
|
* exsltSetsDifferenceFunction:
|
|
* @ctxt: an XPath parser context
|
|
* @nargs: the number of arguments
|
|
*
|
|
* Wraps #xmlXPathDifference for use by the XPath processor
|
|
*/
|
|
static void
|
|
exsltSetsDifferenceFunction (xmlXPathParserContextPtr ctxt, int nargs) {
|
|
xmlNodeSetPtr arg1, arg2, ret;
|
|
|
|
if (nargs != 2) {
|
|
xmlXPathSetArityError(ctxt);
|
|
return;
|
|
}
|
|
|
|
arg2 = xmlXPathPopNodeSet(ctxt);
|
|
if (xmlXPathCheckError(ctxt))
|
|
return;
|
|
|
|
arg1 = xmlXPathPopNodeSet(ctxt);
|
|
if (xmlXPathCheckError(ctxt)) {
|
|
xmlXPathFreeNodeSet(arg2);
|
|
return;
|
|
}
|
|
|
|
ret = xmlXPathDifference(arg1, arg2);
|
|
|
|
if (ret != arg1)
|
|
xmlXPathFreeNodeSet(arg1);
|
|
xmlXPathFreeNodeSet(arg2);
|
|
|
|
xmlXPathReturnNodeSet(ctxt, ret);
|
|
}
|
|
|
|
/**
|
|
* exsltSetsIntersectionFunction:
|
|
* @ctxt: an XPath parser context
|
|
* @nargs: the number of arguments
|
|
*
|
|
* Wraps #xmlXPathIntersection for use by the XPath processor
|
|
*/
|
|
static void
|
|
exsltSetsIntersectionFunction (xmlXPathParserContextPtr ctxt, int nargs) {
|
|
xmlNodeSetPtr arg1, arg2, ret;
|
|
|
|
if (nargs != 2) {
|
|
xmlXPathSetArityError(ctxt);
|
|
return;
|
|
}
|
|
|
|
arg2 = xmlXPathPopNodeSet(ctxt);
|
|
if (xmlXPathCheckError(ctxt))
|
|
return;
|
|
|
|
arg1 = xmlXPathPopNodeSet(ctxt);
|
|
if (xmlXPathCheckError(ctxt)) {
|
|
xmlXPathFreeNodeSet(arg2);
|
|
return;
|
|
}
|
|
|
|
ret = xmlXPathIntersection(arg1, arg2);
|
|
|
|
xmlXPathFreeNodeSet(arg1);
|
|
xmlXPathFreeNodeSet(arg2);
|
|
|
|
xmlXPathReturnNodeSet(ctxt, ret);
|
|
}
|
|
|
|
/**
|
|
* exsltSetsDistinctFunction:
|
|
* @ctxt: an XPath parser context
|
|
* @nargs: the number of arguments
|
|
*
|
|
* Wraps #xmlXPathDistinct for use by the XPath processor
|
|
*/
|
|
static void
|
|
exsltSetsDistinctFunction (xmlXPathParserContextPtr ctxt, int nargs) {
|
|
xmlXPathObjectPtr obj;
|
|
xmlNodeSetPtr ns, ret;
|
|
int boolval = 0;
|
|
void *user = NULL;
|
|
|
|
if (nargs != 1) {
|
|
xmlXPathSetArityError(ctxt);
|
|
return;
|
|
}
|
|
|
|
if (ctxt->value != NULL) {
|
|
boolval = ctxt->value->boolval;
|
|
user = ctxt->value->user;
|
|
ctxt->value->boolval = 0;
|
|
ctxt->value->user = NULL;
|
|
}
|
|
ns = xmlXPathPopNodeSet(ctxt);
|
|
if (xmlXPathCheckError(ctxt))
|
|
return;
|
|
|
|
/* !!! must be sorted !!! */
|
|
ret = xmlXPathDistinctSorted(ns);
|
|
|
|
if (ret != ns)
|
|
xmlXPathFreeNodeSet(ns);
|
|
|
|
obj = xmlXPathWrapNodeSet(ret);
|
|
if (obj != NULL) {
|
|
obj->user = user;
|
|
obj->boolval = boolval;
|
|
}
|
|
valuePush(ctxt, obj);
|
|
}
|
|
|
|
/**
|
|
* exsltSetsHasSameNodesFunction:
|
|
* @ctxt: an XPath parser context
|
|
* @nargs: the number of arguments
|
|
*
|
|
* Wraps #xmlXPathHasSameNodes for use by the XPath processor
|
|
*/
|
|
static void
|
|
exsltSetsHasSameNodesFunction (xmlXPathParserContextPtr ctxt,
|
|
int nargs) {
|
|
xmlNodeSetPtr arg1, arg2;
|
|
int ret;
|
|
|
|
if (nargs != 2) {
|
|
xmlXPathSetArityError(ctxt);
|
|
return;
|
|
}
|
|
|
|
arg2 = xmlXPathPopNodeSet(ctxt);
|
|
if (xmlXPathCheckError(ctxt))
|
|
return;
|
|
|
|
arg1 = xmlXPathPopNodeSet(ctxt);
|
|
if (xmlXPathCheckError(ctxt)) {
|
|
xmlXPathFreeNodeSet(arg2);
|
|
return;
|
|
}
|
|
|
|
ret = xmlXPathHasSameNodes(arg1, arg2);
|
|
|
|
xmlXPathFreeNodeSet(arg1);
|
|
xmlXPathFreeNodeSet(arg2);
|
|
|
|
xmlXPathReturnBoolean(ctxt, ret);
|
|
}
|
|
|
|
/**
|
|
* exsltSetsLeadingFunction:
|
|
* @ctxt: an XPath parser context
|
|
* @nargs: the number of arguments
|
|
*
|
|
* Wraps #xmlXPathLeading for use by the XPath processor
|
|
*/
|
|
static void
|
|
exsltSetsLeadingFunction (xmlXPathParserContextPtr ctxt, int nargs) {
|
|
xmlNodeSetPtr arg1, arg2, ret;
|
|
|
|
if (nargs != 2) {
|
|
xmlXPathSetArityError(ctxt);
|
|
return;
|
|
}
|
|
|
|
arg2 = xmlXPathPopNodeSet(ctxt);
|
|
if (xmlXPathCheckError(ctxt))
|
|
return;
|
|
|
|
arg1 = xmlXPathPopNodeSet(ctxt);
|
|
if (xmlXPathCheckError(ctxt)) {
|
|
xmlXPathFreeNodeSet(arg2);
|
|
return;
|
|
}
|
|
|
|
/* If the second node set is empty, then the first node set is
|
|
* returned.
|
|
*/
|
|
if (xmlXPathNodeSetIsEmpty(arg2)) {
|
|
xmlXPathReturnNodeSet(ctxt, arg1);
|
|
|
|
xmlXPathFreeNodeSet(arg2);
|
|
|
|
return;
|
|
}
|
|
/* !!! must be sorted */
|
|
ret = xmlXPathNodeLeadingSorted(arg1, xmlXPathNodeSetItem(arg2, 0));
|
|
|
|
xmlXPathFreeNodeSet(arg1);
|
|
xmlXPathFreeNodeSet(arg2);
|
|
|
|
xmlXPathReturnNodeSet(ctxt, ret);
|
|
}
|
|
|
|
/**
|
|
* exsltSetsTrailingFunction:
|
|
* @ctxt: an XPath parser context
|
|
* @nargs: the number of arguments
|
|
*
|
|
* Wraps #xmlXPathTrailing for use by the XPath processor
|
|
*/
|
|
static void
|
|
exsltSetsTrailingFunction (xmlXPathParserContextPtr ctxt, int nargs) {
|
|
xmlNodeSetPtr arg1, arg2, ret;
|
|
|
|
if (nargs != 2) {
|
|
xmlXPathSetArityError(ctxt);
|
|
return;
|
|
}
|
|
|
|
arg2 = xmlXPathPopNodeSet(ctxt);
|
|
if (xmlXPathCheckError(ctxt))
|
|
return;
|
|
|
|
arg1 = xmlXPathPopNodeSet(ctxt);
|
|
if (xmlXPathCheckError(ctxt)) {
|
|
xmlXPathFreeNodeSet(arg2);
|
|
return;
|
|
}
|
|
|
|
/* If the second node set is empty, then the first node set is
|
|
* returned.
|
|
*/
|
|
if (xmlXPathNodeSetIsEmpty(arg2)) {
|
|
xmlXPathReturnNodeSet(ctxt, arg1);
|
|
|
|
xmlXPathFreeNodeSet(arg2);
|
|
|
|
return;
|
|
}
|
|
/* !!! mist be sorted */
|
|
ret = xmlXPathNodeTrailingSorted(arg1, xmlXPathNodeSetItem(arg2, 0));
|
|
|
|
xmlXPathFreeNodeSet(arg1);
|
|
xmlXPathFreeNodeSet(arg2);
|
|
|
|
xmlXPathReturnNodeSet(ctxt, ret);
|
|
}
|
|
|
|
/**
|
|
* exsltSetsRegister:
|
|
*
|
|
* Registers the EXSLT - Sets module
|
|
*/
|
|
|
|
void
|
|
exsltSetsRegister (void) {
|
|
xsltRegisterExtModuleFunction ((const xmlChar *) "difference",
|
|
EXSLT_SETS_NAMESPACE,
|
|
exsltSetsDifferenceFunction);
|
|
xsltRegisterExtModuleFunction ((const xmlChar *) "intersection",
|
|
EXSLT_SETS_NAMESPACE,
|
|
exsltSetsIntersectionFunction);
|
|
xsltRegisterExtModuleFunction ((const xmlChar *) "distinct",
|
|
EXSLT_SETS_NAMESPACE,
|
|
exsltSetsDistinctFunction);
|
|
xsltRegisterExtModuleFunction ((const xmlChar *) "has-same-node",
|
|
EXSLT_SETS_NAMESPACE,
|
|
exsltSetsHasSameNodesFunction);
|
|
xsltRegisterExtModuleFunction ((const xmlChar *) "leading",
|
|
EXSLT_SETS_NAMESPACE,
|
|
exsltSetsLeadingFunction);
|
|
xsltRegisterExtModuleFunction ((const xmlChar *) "trailing",
|
|
EXSLT_SETS_NAMESPACE,
|
|
exsltSetsTrailingFunction);
|
|
}
|
|
|
|
/**
|
|
* exsltSetsXpathCtxtRegister:
|
|
*
|
|
* Registers the EXSLT - Sets module for use outside XSLT
|
|
*/
|
|
int
|
|
exsltSetsXpathCtxtRegister (xmlXPathContextPtr ctxt, const xmlChar *prefix)
|
|
{
|
|
if (ctxt
|
|
&& prefix
|
|
&& !xmlXPathRegisterNs(ctxt,
|
|
prefix,
|
|
(const xmlChar *) EXSLT_SETS_NAMESPACE)
|
|
&& !xmlXPathRegisterFuncNS(ctxt,
|
|
(const xmlChar *) "difference",
|
|
(const xmlChar *) EXSLT_SETS_NAMESPACE,
|
|
exsltSetsDifferenceFunction)
|
|
&& !xmlXPathRegisterFuncNS(ctxt,
|
|
(const xmlChar *) "intersection",
|
|
(const xmlChar *) EXSLT_SETS_NAMESPACE,
|
|
exsltSetsIntersectionFunction)
|
|
&& !xmlXPathRegisterFuncNS(ctxt,
|
|
(const xmlChar *) "distinct",
|
|
(const xmlChar *) EXSLT_SETS_NAMESPACE,
|
|
exsltSetsDistinctFunction)
|
|
&& !xmlXPathRegisterFuncNS(ctxt,
|
|
(const xmlChar *) "has-same-node",
|
|
(const xmlChar *) EXSLT_SETS_NAMESPACE,
|
|
exsltSetsHasSameNodesFunction)
|
|
&& !xmlXPathRegisterFuncNS(ctxt,
|
|
(const xmlChar *) "leading",
|
|
(const xmlChar *) EXSLT_SETS_NAMESPACE,
|
|
exsltSetsLeadingFunction)
|
|
&& !xmlXPathRegisterFuncNS(ctxt,
|
|
(const xmlChar *) "trailing",
|
|
(const xmlChar *) EXSLT_SETS_NAMESPACE,
|
|
exsltSetsTrailingFunction)) {
|
|
return 0;
|
|
}
|
|
return -1;
|
|
}
|