mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-04 18:47:07 +00:00
xslt: Import upstream release 1.1.35.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
a279c2783c
commit
f3f7dd4dba
|
@ -1968,12 +1968,6 @@ xsltGetExtInfo(xsltStylesheetPtr style, const xmlChar * URI)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* *
|
||||
* Test module http://xmlsoft.org/XSLT/ *
|
||||
* *
|
||||
************************************************************************/
|
||||
|
||||
/************************************************************************
|
||||
* *
|
||||
* Test of the extension module API *
|
||||
|
|
|
@ -246,7 +246,7 @@ XSLTPUBFUN xmlHashTablePtr XSLTCALL
|
|||
const xmlChar *URI);
|
||||
|
||||
/**
|
||||
* Test module http://xmlsoft.org/XSLT/
|
||||
* Test of the extension module API
|
||||
*/
|
||||
XSLTPUBFUN void XSLTCALL
|
||||
xsltRegisterTestModule (void);
|
||||
|
|
|
@ -178,10 +178,22 @@ xsltDocumentFunctionLoadDocument(xmlXPathParserContextPtr ctxt, xmlChar* URI)
|
|||
goto out_fragment;
|
||||
}
|
||||
|
||||
#if LIBXML_VERSION >= 20911 || \
|
||||
defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
|
||||
xptrctxt->opLimit = ctxt->context->opLimit;
|
||||
xptrctxt->opCount = ctxt->context->opCount;
|
||||
xptrctxt->depth = ctxt->context->depth;
|
||||
|
||||
resObj = xmlXPtrEval(fragment, xptrctxt);
|
||||
|
||||
ctxt->context->opCount = xptrctxt->opCount;
|
||||
#else
|
||||
resObj = xmlXPtrEval(fragment, xptrctxt);
|
||||
xmlXPathFreeContext(xptrctxt);
|
||||
#endif
|
||||
|
||||
xmlXPathFreeContext(xptrctxt);
|
||||
#endif /* LIBXML_XPTR_ENABLED */
|
||||
|
||||
if (resObj == NULL)
|
||||
goto out_fragment;
|
||||
|
||||
|
|
|
@ -177,7 +177,7 @@ xsltNumberFormatDecimal(xmlBufferPtr buffer,
|
|||
i = -1;
|
||||
break;
|
||||
}
|
||||
*(--pointer) = val;
|
||||
*(--pointer) = (xmlChar)val;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
|
@ -960,7 +960,7 @@ xsltFormatNumberConversion(xsltDecimalFormatPtr self,
|
|||
xmlChar *nprefix, *nsuffix = NULL;
|
||||
int prefix_length, suffix_length = 0, nprefix_length, nsuffix_length;
|
||||
double scale;
|
||||
int j, len;
|
||||
int j, len = 0;
|
||||
int self_grouping_len;
|
||||
xsltFormatNumberInfo format_info;
|
||||
/*
|
||||
|
|
|
@ -452,14 +452,11 @@ xsltReverseCompMatch(xsltParserContextPtr ctxt, xsltCompMatchPtr comp) {
|
|||
xsltCompMatchAdd(ctxt, comp, XSLT_OP_END, NULL, NULL, 0);
|
||||
|
||||
/*
|
||||
* Detect consecutive XSLT_OP_PREDICATE and predicates on ops which
|
||||
* haven't been optimized yet indicating a direct matching should be done.
|
||||
* Detect consecutive XSLT_OP_PREDICATE indicating a direct matching
|
||||
* should be done.
|
||||
*/
|
||||
for (i = 0;i < comp->nbStep - 1;i++) {
|
||||
xsltOp op = comp->steps[i].op;
|
||||
|
||||
if ((op != XSLT_OP_ELEM) &&
|
||||
(op != XSLT_OP_ALL) &&
|
||||
if ((comp->steps[i].op == XSLT_OP_PREDICATE) &&
|
||||
(comp->steps[i + 1].op == XSLT_OP_PREDICATE)) {
|
||||
|
||||
comp->direct = 1;
|
||||
|
@ -629,6 +626,152 @@ xsltTestCompMatchDirect(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp,
|
|||
return(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* xsltTestStepMatch:
|
||||
* @ctxt: a XSLT process context
|
||||
* @node: a node
|
||||
* @step: the step
|
||||
*
|
||||
* Test whether the node matches the step.
|
||||
*
|
||||
* Returns 1 if it matches, 0 if it doesn't and -1 in case of failure
|
||||
*/
|
||||
static int
|
||||
xsltTestStepMatch(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
xsltStepOpPtr step) {
|
||||
switch (step->op) {
|
||||
case XSLT_OP_ROOT:
|
||||
if ((node->type == XML_DOCUMENT_NODE) ||
|
||||
#ifdef LIBXML_DOCB_ENABLED
|
||||
(node->type == XML_DOCB_DOCUMENT_NODE) ||
|
||||
#endif
|
||||
(node->type == XML_HTML_DOCUMENT_NODE))
|
||||
return(1);
|
||||
if ((node->type == XML_ELEMENT_NODE) && (node->name[0] == ' '))
|
||||
return(1);
|
||||
return(0);
|
||||
case XSLT_OP_ELEM:
|
||||
if (node->type != XML_ELEMENT_NODE)
|
||||
return(0);
|
||||
if (step->value == NULL)
|
||||
return(1);
|
||||
if (step->value[0] != node->name[0])
|
||||
return(0);
|
||||
if (!xmlStrEqual(step->value, node->name))
|
||||
return(0);
|
||||
|
||||
/* Namespace test */
|
||||
if (node->ns == NULL) {
|
||||
if (step->value2 != NULL)
|
||||
return(0);
|
||||
} else if (node->ns->href != NULL) {
|
||||
if (step->value2 == NULL)
|
||||
return(0);
|
||||
if (!xmlStrEqual(step->value2, node->ns->href))
|
||||
return(0);
|
||||
}
|
||||
return(1);
|
||||
case XSLT_OP_ATTR:
|
||||
if (node->type != XML_ATTRIBUTE_NODE)
|
||||
return(0);
|
||||
if (step->value != NULL) {
|
||||
if (step->value[0] != node->name[0])
|
||||
return(0);
|
||||
if (!xmlStrEqual(step->value, node->name))
|
||||
return(0);
|
||||
}
|
||||
/* Namespace test */
|
||||
if (node->ns == NULL) {
|
||||
if (step->value2 != NULL)
|
||||
return(0);
|
||||
} else if (step->value2 != NULL) {
|
||||
if (!xmlStrEqual(step->value2, node->ns->href))
|
||||
return(0);
|
||||
}
|
||||
return(1);
|
||||
case XSLT_OP_ID: {
|
||||
/* TODO Handle IDs decently, must be done differently */
|
||||
xmlAttrPtr id;
|
||||
|
||||
if (node->type != XML_ELEMENT_NODE)
|
||||
return(0);
|
||||
|
||||
id = xmlGetID(node->doc, step->value);
|
||||
if ((id == NULL) || (id->parent != node))
|
||||
return(0);
|
||||
break;
|
||||
}
|
||||
case XSLT_OP_KEY: {
|
||||
xmlNodeSetPtr list;
|
||||
int indx;
|
||||
|
||||
list = xsltGetKey(ctxt, step->value,
|
||||
step->value3, step->value2);
|
||||
if (list == NULL)
|
||||
return(0);
|
||||
for (indx = 0;indx < list->nodeNr;indx++)
|
||||
if (list->nodeTab[indx] == node)
|
||||
break;
|
||||
if (indx >= list->nodeNr)
|
||||
return(0);
|
||||
break;
|
||||
}
|
||||
case XSLT_OP_NS:
|
||||
if (node->type != XML_ELEMENT_NODE)
|
||||
return(0);
|
||||
if (node->ns == NULL) {
|
||||
if (step->value != NULL)
|
||||
return(0);
|
||||
} else if (node->ns->href != NULL) {
|
||||
if (step->value == NULL)
|
||||
return(0);
|
||||
if (!xmlStrEqual(step->value, node->ns->href))
|
||||
return(0);
|
||||
}
|
||||
break;
|
||||
case XSLT_OP_ALL:
|
||||
if (node->type != XML_ELEMENT_NODE)
|
||||
return(0);
|
||||
break;
|
||||
case XSLT_OP_PI:
|
||||
if (node->type != XML_PI_NODE)
|
||||
return(0);
|
||||
if (step->value != NULL) {
|
||||
if (!xmlStrEqual(step->value, node->name))
|
||||
return(0);
|
||||
}
|
||||
break;
|
||||
case XSLT_OP_COMMENT:
|
||||
if (node->type != XML_COMMENT_NODE)
|
||||
return(0);
|
||||
break;
|
||||
case XSLT_OP_TEXT:
|
||||
if ((node->type != XML_TEXT_NODE) &&
|
||||
(node->type != XML_CDATA_SECTION_NODE))
|
||||
return(0);
|
||||
break;
|
||||
case XSLT_OP_NODE:
|
||||
switch (node->type) {
|
||||
case XML_ELEMENT_NODE:
|
||||
case XML_CDATA_SECTION_NODE:
|
||||
case XML_PI_NODE:
|
||||
case XML_COMMENT_NODE:
|
||||
case XML_TEXT_NODE:
|
||||
break;
|
||||
default:
|
||||
return(0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
xsltTransformError(ctxt, NULL, node,
|
||||
"xsltTestStepMatch: unexpected step op %d\n",
|
||||
step->op);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* xsltTestPredicateMatch:
|
||||
* @ctxt: a XSLT process context
|
||||
|
@ -656,6 +799,8 @@ xsltTestPredicateMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp,
|
|||
return(0);
|
||||
if (step->comp == NULL)
|
||||
return(0);
|
||||
if (sel == NULL)
|
||||
return(0);
|
||||
|
||||
doc = node->doc;
|
||||
if (XSLT_IS_RES_TREE_FRAG(doc))
|
||||
|
@ -666,16 +811,16 @@ xsltTestPredicateMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp,
|
|||
/*
|
||||
* Recompute contextSize and proximityPosition.
|
||||
*
|
||||
* TODO: Make this work for additional ops. Currently, only XSLT_OP_ELEM
|
||||
* and XSLT_OP_ALL are supported.
|
||||
* This could be improved in the following ways:
|
||||
*
|
||||
* - Skip recomputation if predicates don't use position() or last()
|
||||
* - Keep data for multiple parents. This would require a hash table
|
||||
* or an unused member in xmlNode.
|
||||
* - Store node test results in a bitmap to avoid computing them twice.
|
||||
*/
|
||||
oldCS = ctxt->xpathCtxt->contextSize;
|
||||
oldCP = ctxt->xpathCtxt->proximityPosition;
|
||||
if ((sel != NULL) &&
|
||||
(sel->op == XSLT_OP_ELEM) &&
|
||||
(sel->value != NULL) &&
|
||||
(node->type == XML_ELEMENT_NODE) &&
|
||||
(node->parent != NULL)) {
|
||||
{
|
||||
xmlNodePtr previous;
|
||||
int nocache = 0;
|
||||
|
||||
|
@ -692,17 +837,8 @@ xsltTestPredicateMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp,
|
|||
while (sibling != NULL) {
|
||||
if (sibling == previous)
|
||||
break;
|
||||
if ((sibling->type == XML_ELEMENT_NODE) &&
|
||||
(previous->name != NULL) &&
|
||||
(sibling->name != NULL) &&
|
||||
(previous->name[0] == sibling->name[0]) &&
|
||||
(xmlStrEqual(previous->name, sibling->name)))
|
||||
{
|
||||
if ((sel->value2 == NULL) ||
|
||||
((sibling->ns != NULL) &&
|
||||
(xmlStrEqual(sel->value2, sibling->ns->href))))
|
||||
indx++;
|
||||
}
|
||||
if (xsltTestStepMatch(ctxt, sibling, sel))
|
||||
indx++;
|
||||
sibling = sibling->prev;
|
||||
}
|
||||
if (sibling == NULL) {
|
||||
|
@ -712,20 +848,8 @@ xsltTestPredicateMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp,
|
|||
while (sibling != NULL) {
|
||||
if (sibling == previous)
|
||||
break;
|
||||
if ((sibling->type == XML_ELEMENT_NODE) &&
|
||||
(previous->name != NULL) &&
|
||||
(sibling->name != NULL) &&
|
||||
(previous->name[0] == sibling->name[0]) &&
|
||||
(xmlStrEqual(previous->name, sibling->name)))
|
||||
{
|
||||
if ((sel->value2 == NULL) ||
|
||||
((sibling->ns != NULL) &&
|
||||
(xmlStrEqual(sel->value2,
|
||||
sibling->ns->href))))
|
||||
{
|
||||
indx--;
|
||||
}
|
||||
}
|
||||
if (xsltTestStepMatch(ctxt, sibling, sel))
|
||||
indx--;
|
||||
sibling = sibling->next;
|
||||
}
|
||||
}
|
||||
|
@ -756,19 +880,11 @@ xsltTestPredicateMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp,
|
|||
if (parent) siblings = parent->children;
|
||||
|
||||
while (siblings != NULL) {
|
||||
if (siblings->type == XML_ELEMENT_NODE) {
|
||||
if (siblings == node) {
|
||||
len++;
|
||||
pos = len;
|
||||
} else if ((node->name != NULL) &&
|
||||
(siblings->name != NULL) &&
|
||||
(node->name[0] == siblings->name[0]) &&
|
||||
(xmlStrEqual(node->name, siblings->name))) {
|
||||
if ((sel->value2 == NULL) ||
|
||||
((siblings->ns != NULL) &&
|
||||
(xmlStrEqual(sel->value2, siblings->ns->href))))
|
||||
len++;
|
||||
}
|
||||
if (siblings == node) {
|
||||
len++;
|
||||
pos = len;
|
||||
} else if (xsltTestStepMatch(ctxt, siblings, sel)) {
|
||||
len++;
|
||||
}
|
||||
siblings = siblings->next;
|
||||
}
|
||||
|
@ -797,96 +913,6 @@ xsltTestPredicateMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp,
|
|||
XSLT_RUNTIME_EXTRA(ctxt, sel->lenExtra, ival) = len;
|
||||
}
|
||||
}
|
||||
} else if ((sel != NULL) && (sel->op == XSLT_OP_ALL) &&
|
||||
(node->type == XML_ELEMENT_NODE)) {
|
||||
xmlNodePtr previous;
|
||||
int nocache = 0;
|
||||
|
||||
previous = (xmlNodePtr)
|
||||
XSLT_RUNTIME_EXTRA(ctxt, sel->previousExtra, ptr);
|
||||
if ((previous != NULL) &&
|
||||
(previous->parent == node->parent)) {
|
||||
/*
|
||||
* just walk back to adjust the index
|
||||
*/
|
||||
int indx = 0;
|
||||
xmlNodePtr sibling = node;
|
||||
|
||||
while (sibling != NULL) {
|
||||
if (sibling == previous)
|
||||
break;
|
||||
if (sibling->type == XML_ELEMENT_NODE)
|
||||
indx++;
|
||||
sibling = sibling->prev;
|
||||
}
|
||||
if (sibling == NULL) {
|
||||
/* hum going backward in document order ... */
|
||||
indx = 0;
|
||||
sibling = node;
|
||||
while (sibling != NULL) {
|
||||
if (sibling == previous)
|
||||
break;
|
||||
if (sibling->type == XML_ELEMENT_NODE)
|
||||
indx--;
|
||||
sibling = sibling->next;
|
||||
}
|
||||
}
|
||||
if (sibling != NULL) {
|
||||
pos = XSLT_RUNTIME_EXTRA(ctxt,
|
||||
sel->indexExtra, ival) + indx;
|
||||
/*
|
||||
* If the node is in a Value Tree we cannot
|
||||
* cache it !
|
||||
*/
|
||||
if ((node->doc != NULL) && !isRVT) {
|
||||
len = XSLT_RUNTIME_EXTRA(ctxt, sel->lenExtra, ival);
|
||||
XSLT_RUNTIME_EXTRA(ctxt, sel->previousExtra, ptr) = node;
|
||||
XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival) = pos;
|
||||
}
|
||||
} else
|
||||
pos = 0;
|
||||
} else {
|
||||
/*
|
||||
* recompute the index
|
||||
*/
|
||||
xmlNodePtr parent = node->parent;
|
||||
xmlNodePtr siblings = NULL;
|
||||
|
||||
if (parent) siblings = parent->children;
|
||||
|
||||
while (siblings != NULL) {
|
||||
if (siblings->type == XML_ELEMENT_NODE) {
|
||||
len++;
|
||||
if (siblings == node) {
|
||||
pos = len;
|
||||
}
|
||||
}
|
||||
siblings = siblings->next;
|
||||
}
|
||||
if ((parent == NULL) || (node->doc == NULL))
|
||||
nocache = 1;
|
||||
else {
|
||||
while (parent->parent != NULL)
|
||||
parent = parent->parent;
|
||||
if (((parent->type != XML_DOCUMENT_NODE) &&
|
||||
(parent->type != XML_HTML_DOCUMENT_NODE)) ||
|
||||
(parent != (xmlNodePtr) node->doc))
|
||||
nocache = 1;
|
||||
}
|
||||
}
|
||||
if (pos != 0) {
|
||||
ctxt->xpathCtxt->contextSize = len;
|
||||
ctxt->xpathCtxt->proximityPosition = pos;
|
||||
/*
|
||||
* If the node is in a Value Tree we cannot
|
||||
* cache it !
|
||||
*/
|
||||
if ((node->doc != NULL) && (nocache == 0) && !isRVT) {
|
||||
XSLT_RUNTIME_EXTRA(ctxt, sel->previousExtra, ptr) = node;
|
||||
XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival) = pos;
|
||||
XSLT_RUNTIME_EXTRA(ctxt, sel->lenExtra, ival) = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
oldNode = ctxt->node;
|
||||
|
@ -969,55 +995,6 @@ restart:
|
|||
switch (step->op) {
|
||||
case XSLT_OP_END:
|
||||
goto found;
|
||||
case XSLT_OP_ROOT:
|
||||
if ((node->type == XML_DOCUMENT_NODE) ||
|
||||
#ifdef LIBXML_DOCB_ENABLED
|
||||
(node->type == XML_DOCB_DOCUMENT_NODE) ||
|
||||
#endif
|
||||
(node->type == XML_HTML_DOCUMENT_NODE))
|
||||
continue;
|
||||
if ((node->type == XML_ELEMENT_NODE) && (node->name[0] == ' '))
|
||||
continue;
|
||||
goto rollback;
|
||||
case XSLT_OP_ELEM:
|
||||
if (node->type != XML_ELEMENT_NODE)
|
||||
goto rollback;
|
||||
if (step->value == NULL)
|
||||
continue;
|
||||
if (step->value[0] != node->name[0])
|
||||
goto rollback;
|
||||
if (!xmlStrEqual(step->value, node->name))
|
||||
goto rollback;
|
||||
|
||||
/* Namespace test */
|
||||
if (node->ns == NULL) {
|
||||
if (step->value2 != NULL)
|
||||
goto rollback;
|
||||
} else if (node->ns->href != NULL) {
|
||||
if (step->value2 == NULL)
|
||||
goto rollback;
|
||||
if (!xmlStrEqual(step->value2, node->ns->href))
|
||||
goto rollback;
|
||||
}
|
||||
continue;
|
||||
case XSLT_OP_ATTR:
|
||||
if (node->type != XML_ATTRIBUTE_NODE)
|
||||
goto rollback;
|
||||
if (step->value != NULL) {
|
||||
if (step->value[0] != node->name[0])
|
||||
goto rollback;
|
||||
if (!xmlStrEqual(step->value, node->name))
|
||||
goto rollback;
|
||||
}
|
||||
/* Namespace test */
|
||||
if (node->ns == NULL) {
|
||||
if (step->value2 != NULL)
|
||||
goto rollback;
|
||||
} else if (step->value2 != NULL) {
|
||||
if (!xmlStrEqual(step->value2, node->ns->href))
|
||||
goto rollback;
|
||||
}
|
||||
continue;
|
||||
case XSLT_OP_PARENT:
|
||||
if ((node->type == XML_DOCUMENT_NODE) ||
|
||||
(node->type == XML_HTML_DOCUMENT_NODE) ||
|
||||
|
@ -1075,6 +1052,7 @@ restart:
|
|||
continue;
|
||||
}
|
||||
i++;
|
||||
sel = step;
|
||||
if (step->value == NULL) {
|
||||
xsltPatPushState(ctxt, &states, i - 1, node);
|
||||
continue;
|
||||
|
@ -1099,50 +1077,6 @@ restart:
|
|||
goto rollback;
|
||||
xsltPatPushState(ctxt, &states, i - 1, node);
|
||||
continue;
|
||||
case XSLT_OP_ID: {
|
||||
/* TODO Handle IDs decently, must be done differently */
|
||||
xmlAttrPtr id;
|
||||
|
||||
if (node->type != XML_ELEMENT_NODE)
|
||||
goto rollback;
|
||||
|
||||
id = xmlGetID(node->doc, step->value);
|
||||
if ((id == NULL) || (id->parent != node))
|
||||
goto rollback;
|
||||
break;
|
||||
}
|
||||
case XSLT_OP_KEY: {
|
||||
xmlNodeSetPtr list;
|
||||
int indx;
|
||||
|
||||
list = xsltGetKey(ctxt, step->value,
|
||||
step->value3, step->value2);
|
||||
if (list == NULL)
|
||||
goto rollback;
|
||||
for (indx = 0;indx < list->nodeNr;indx++)
|
||||
if (list->nodeTab[indx] == node)
|
||||
break;
|
||||
if (indx >= list->nodeNr)
|
||||
goto rollback;
|
||||
break;
|
||||
}
|
||||
case XSLT_OP_NS:
|
||||
if (node->type != XML_ELEMENT_NODE)
|
||||
goto rollback;
|
||||
if (node->ns == NULL) {
|
||||
if (step->value != NULL)
|
||||
goto rollback;
|
||||
} else if (node->ns->href != NULL) {
|
||||
if (step->value == NULL)
|
||||
goto rollback;
|
||||
if (!xmlStrEqual(step->value, node->ns->href))
|
||||
goto rollback;
|
||||
}
|
||||
break;
|
||||
case XSLT_OP_ALL:
|
||||
if (node->type != XML_ELEMENT_NODE)
|
||||
goto rollback;
|
||||
break;
|
||||
case XSLT_OP_PREDICATE: {
|
||||
/*
|
||||
* When there is cascading XSLT_OP_PREDICATE or a predicate
|
||||
|
@ -1162,34 +1096,9 @@ restart:
|
|||
|
||||
break;
|
||||
}
|
||||
case XSLT_OP_PI:
|
||||
if (node->type != XML_PI_NODE)
|
||||
goto rollback;
|
||||
if (step->value != NULL) {
|
||||
if (!xmlStrEqual(step->value, node->name))
|
||||
goto rollback;
|
||||
}
|
||||
break;
|
||||
case XSLT_OP_COMMENT:
|
||||
if (node->type != XML_COMMENT_NODE)
|
||||
goto rollback;
|
||||
break;
|
||||
case XSLT_OP_TEXT:
|
||||
if ((node->type != XML_TEXT_NODE) &&
|
||||
(node->type != XML_CDATA_SECTION_NODE))
|
||||
goto rollback;
|
||||
break;
|
||||
case XSLT_OP_NODE:
|
||||
switch (node->type) {
|
||||
case XML_ELEMENT_NODE:
|
||||
case XML_CDATA_SECTION_NODE:
|
||||
case XML_PI_NODE:
|
||||
case XML_COMMENT_NODE:
|
||||
case XML_TEXT_NODE:
|
||||
break;
|
||||
default:
|
||||
goto rollback;
|
||||
}
|
||||
default:
|
||||
if (xsltTestStepMatch(ctxt, node, step) != 1)
|
||||
goto rollback;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1439,6 +1348,7 @@ xsltCompileIdKeyPattern(xsltParserContextPtr ctxt, xmlChar *name,
|
|||
if (ctxt->error) {
|
||||
xsltTransformError(NULL, NULL, NULL,
|
||||
"xsltCompileIdKeyPattern : Literal expected\n");
|
||||
xmlFree(lit);
|
||||
return;
|
||||
}
|
||||
SKIP_BLANKS;
|
||||
|
@ -1465,6 +1375,7 @@ xsltCompileIdKeyPattern(xsltParserContextPtr ctxt, xmlChar *name,
|
|||
if (ctxt->error) {
|
||||
xsltTransformError(NULL, NULL, NULL,
|
||||
"xsltCompileIdKeyPattern : Literal expected\n");
|
||||
xmlFree(lit);
|
||||
return;
|
||||
}
|
||||
SKIP_BLANKS;
|
||||
|
@ -1506,6 +1417,7 @@ xsltCompileIdKeyPattern(xsltParserContextPtr ctxt, xmlChar *name,
|
|||
if (ctxt->error) {
|
||||
xsltTransformError(NULL, NULL, NULL,
|
||||
"xsltCompileIdKeyPattern : Literal expected\n");
|
||||
xmlFree(lit);
|
||||
return;
|
||||
}
|
||||
SKIP_BLANKS;
|
||||
|
@ -2127,13 +2039,16 @@ xsltAddTemplate(xsltStylesheetPtr style, xsltTemplatePtr cur,
|
|||
* 'top' will point to style->xxxMatch ptr - declaring as 'void'
|
||||
* avoids gcc 'type-punned pointer' warning.
|
||||
*/
|
||||
void **top = NULL;
|
||||
xsltCompMatchPtr *top = NULL;
|
||||
const xmlChar *name = NULL;
|
||||
float priority; /* the priority */
|
||||
|
||||
if ((style == NULL) || (cur == NULL))
|
||||
return(-1);
|
||||
|
||||
if (cur->next != NULL)
|
||||
cur->position = cur->next->position + 1;
|
||||
|
||||
/* Register named template */
|
||||
if (cur->name != NULL) {
|
||||
if (style->namedTemplates == NULL) {
|
||||
|
@ -2495,7 +2410,10 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
|||
break;
|
||||
}
|
||||
while ((list != NULL) &&
|
||||
((ret == NULL) || (list->priority > priority))) {
|
||||
((ret == NULL) ||
|
||||
(list->priority > priority) ||
|
||||
((list->priority == priority) &&
|
||||
(list->template->position > ret->position)))) {
|
||||
if (xsltTestCompMatch(ctxt, list, node,
|
||||
ctxt->mode, ctxt->modeURI) == 1) {
|
||||
ret = list->template;
|
||||
|
@ -2512,7 +2430,10 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
|||
(node->type == XML_TEXT_NODE)) {
|
||||
list = curstyle->elemMatch;
|
||||
while ((list != NULL) &&
|
||||
((ret == NULL) || (list->priority > priority))) {
|
||||
((ret == NULL) ||
|
||||
(list->priority > priority) ||
|
||||
((list->priority == priority) &&
|
||||
(list->template->position > ret->position)))) {
|
||||
if (xsltTestCompMatch(ctxt, list, node,
|
||||
ctxt->mode, ctxt->modeURI) == 1) {
|
||||
ret = list->template;
|
||||
|
@ -2525,7 +2446,10 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
|||
(node->type == XML_COMMENT_NODE)) {
|
||||
list = curstyle->elemMatch;
|
||||
while ((list != NULL) &&
|
||||
((ret == NULL) || (list->priority > priority))) {
|
||||
((ret == NULL) ||
|
||||
(list->priority > priority) ||
|
||||
((list->priority == priority) &&
|
||||
(list->template->position > ret->position)))) {
|
||||
if (xsltTestCompMatch(ctxt, list, node,
|
||||
ctxt->mode, ctxt->modeURI) == 1) {
|
||||
ret = list->template;
|
||||
|
@ -2540,7 +2464,10 @@ keyed_match:
|
|||
if (keyed) {
|
||||
list = curstyle->keyMatch;
|
||||
while ((list != NULL) &&
|
||||
((ret == NULL) || (list->priority > priority))) {
|
||||
((ret == NULL) ||
|
||||
(list->priority > priority) ||
|
||||
((list->priority == priority) &&
|
||||
(list->template->position > ret->position)))) {
|
||||
if (xsltTestCompMatch(ctxt, list, node,
|
||||
ctxt->mode, ctxt->modeURI) == 1) {
|
||||
ret = list->template;
|
||||
|
@ -2618,8 +2545,7 @@ xsltCleanupTemplates(xsltStylesheetPtr style ATTRIBUTE_UNUSED) {
|
|||
void
|
||||
xsltFreeTemplateHashes(xsltStylesheetPtr style) {
|
||||
if (style->templatesHash != NULL)
|
||||
xmlHashFree((xmlHashTablePtr) style->templatesHash,
|
||||
xsltFreeCompMatchListEntry);
|
||||
xmlHashFree(style->templatesHash, xsltFreeCompMatchListEntry);
|
||||
if (style->rootMatch != NULL)
|
||||
xsltFreeCompMatchList(style->rootMatch);
|
||||
if (style->keyMatch != NULL)
|
||||
|
|
|
@ -1494,6 +1494,8 @@ xsltNumberComp(xsltStylesheetPtr style, xmlNodePtr cur) {
|
|||
comp->numdata.groupingCharacterLen = xmlStrlen(prop);
|
||||
comp->numdata.groupingCharacter =
|
||||
xsltGetUTF8Char(prop, &(comp->numdata.groupingCharacterLen));
|
||||
if (comp->numdata.groupingCharacter < 0)
|
||||
comp->numdata.groupingCharacter = 0;
|
||||
}
|
||||
|
||||
prop = xsltGetCNsProp(style, cur, (const xmlChar *)"grouping-size", XSLT_NAMESPACE);
|
||||
|
|
|
@ -22,7 +22,7 @@ extern "C" {
|
|||
/*
|
||||
* Interfaces
|
||||
*/
|
||||
extern const xmlChar *xsltExtMarker;
|
||||
XSLTPUBVAR const xmlChar *xsltExtMarker;
|
||||
|
||||
XSLTPUBFUN xsltElemPreCompPtr XSLTCALL
|
||||
xsltDocumentComp (xsltStylesheetPtr style,
|
||||
|
|
|
@ -282,7 +282,7 @@ xsltCheckFilename (const char *path)
|
|||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
DWORD dwAttrs;
|
||||
|
||||
dwAttrs = GetFileAttributes(path);
|
||||
dwAttrs = GetFileAttributesA(path);
|
||||
if (dwAttrs != INVALID_FILE_ATTRIBUTES) {
|
||||
if (dwAttrs & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
return 2;
|
||||
|
|
|
@ -210,6 +210,8 @@ xsltEvalTemplateString(xsltTransformContextPtr ctxt,
|
|||
{
|
||||
xmlNodePtr oldInsert, insert = NULL;
|
||||
xmlChar *ret;
|
||||
const xmlChar *oldLastText;
|
||||
int oldLastTextSize, oldLastTextUse;
|
||||
|
||||
if ((ctxt == NULL) || (contextNode == NULL) || (inst == NULL) ||
|
||||
(inst->type != XML_ELEMENT_NODE))
|
||||
|
@ -233,12 +235,18 @@ xsltEvalTemplateString(xsltTransformContextPtr ctxt,
|
|||
}
|
||||
oldInsert = ctxt->insert;
|
||||
ctxt->insert = insert;
|
||||
oldLastText = ctxt->lasttext;
|
||||
oldLastTextSize = ctxt->lasttsize;
|
||||
oldLastTextUse = ctxt->lasttuse;
|
||||
/*
|
||||
* OPTIMIZE TODO: if inst->children consists only of text-nodes.
|
||||
*/
|
||||
xsltApplyOneTemplate(ctxt, contextNode, inst->children, NULL, NULL);
|
||||
|
||||
ctxt->insert = oldInsert;
|
||||
ctxt->lasttext = oldLastText;
|
||||
ctxt->lasttsize = oldLastTextSize;
|
||||
ctxt->lasttuse = oldLastTextUse;
|
||||
|
||||
ret = xmlNodeGetContent(insert);
|
||||
if (insert != NULL)
|
||||
|
|
|
@ -1895,7 +1895,7 @@ static void
|
|||
xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||
xsltStackElemPtr params) {
|
||||
xmlNodePtr copy;
|
||||
xmlNodePtr delete = NULL, cur;
|
||||
xmlNodePtr cur;
|
||||
int nbchild = 0, oldSize;
|
||||
int childno = 0, oldPos;
|
||||
xsltTemplatePtr template;
|
||||
|
@ -1968,54 +1968,13 @@ xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
|||
return;
|
||||
}
|
||||
/*
|
||||
* Handling of Elements: first pass, cleanup and counting
|
||||
* Handling of Elements: first pass, counting
|
||||
*/
|
||||
cur = node->children;
|
||||
while (cur != NULL) {
|
||||
switch (cur->type) {
|
||||
case XML_TEXT_NODE:
|
||||
case XML_CDATA_SECTION_NODE:
|
||||
case XML_DOCUMENT_NODE:
|
||||
case XML_HTML_DOCUMENT_NODE:
|
||||
case XML_ELEMENT_NODE:
|
||||
case XML_PI_NODE:
|
||||
case XML_COMMENT_NODE:
|
||||
nbchild++;
|
||||
break;
|
||||
case XML_DTD_NODE:
|
||||
/* Unlink the DTD, it's still reachable using doc->intSubset */
|
||||
if (cur->next != NULL)
|
||||
cur->next->prev = cur->prev;
|
||||
if (cur->prev != NULL)
|
||||
cur->prev->next = cur->next;
|
||||
break;
|
||||
default:
|
||||
#ifdef WITH_XSLT_DEBUG_PROCESS
|
||||
XSLT_TRACE(ctxt,XSLT_TRACE_PROCESS_NODE,xsltGenericDebug(xsltGenericDebugContext,
|
||||
"xsltDefaultProcessOneNode: skipping node type %d\n",
|
||||
cur->type));
|
||||
#endif
|
||||
delete = cur;
|
||||
}
|
||||
if (IS_XSLT_REAL_NODE(cur))
|
||||
nbchild++;
|
||||
cur = cur->next;
|
||||
if (delete != NULL) {
|
||||
#ifdef WITH_XSLT_DEBUG_PROCESS
|
||||
XSLT_TRACE(ctxt,XSLT_TRACE_PROCESS_NODE,xsltGenericDebug(xsltGenericDebugContext,
|
||||
"xsltDefaultProcessOneNode: removing ignorable blank node\n"));
|
||||
#endif
|
||||
xmlUnlinkNode(delete);
|
||||
xmlFreeNode(delete);
|
||||
delete = NULL;
|
||||
}
|
||||
}
|
||||
if (delete != NULL) {
|
||||
#ifdef WITH_XSLT_DEBUG_PROCESS
|
||||
XSLT_TRACE(ctxt,XSLT_TRACE_PROCESS_NODE,xsltGenericDebug(xsltGenericDebugContext,
|
||||
"xsltDefaultProcessOneNode: removing ignorable blank node\n"));
|
||||
#endif
|
||||
xmlUnlinkNode(delete);
|
||||
xmlFreeNode(delete);
|
||||
delete = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -3672,8 +3631,10 @@ xsltDocumentElem(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
|||
if (elements != NULL) {
|
||||
if (style->stripSpaces == NULL)
|
||||
style->stripSpaces = xmlHashCreate(10);
|
||||
if (style->stripSpaces == NULL)
|
||||
if (style->stripSpaces == NULL) {
|
||||
xmlFree(elements);
|
||||
return;
|
||||
}
|
||||
|
||||
element = elements;
|
||||
while (*element != 0) {
|
||||
|
@ -4864,7 +4825,7 @@ xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
|||
xsltStylePreCompPtr comp = (xsltStylePreCompPtr) castedComp;
|
||||
#endif
|
||||
int i;
|
||||
xmlNodePtr cur, delNode = NULL, oldContextNode;
|
||||
xmlNodePtr cur, oldContextNode;
|
||||
xmlNodeSetPtr list = NULL, oldList;
|
||||
xsltStackElemPtr withParams = NULL;
|
||||
int oldXPProximityPosition, oldXPContextSize;
|
||||
|
@ -4998,73 +4959,9 @@ xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
|||
else
|
||||
cur = NULL;
|
||||
while (cur != NULL) {
|
||||
switch (cur->type) {
|
||||
case XML_TEXT_NODE:
|
||||
if ((IS_BLANK_NODE(cur)) &&
|
||||
(cur->parent != NULL) &&
|
||||
(cur->parent->type == XML_ELEMENT_NODE) &&
|
||||
(ctxt->style->stripSpaces != NULL)) {
|
||||
const xmlChar *val;
|
||||
|
||||
if (cur->parent->ns != NULL) {
|
||||
val = (const xmlChar *)
|
||||
xmlHashLookup2(ctxt->style->stripSpaces,
|
||||
cur->parent->name,
|
||||
cur->parent->ns->href);
|
||||
if (val == NULL) {
|
||||
val = (const xmlChar *)
|
||||
xmlHashLookup2(ctxt->style->stripSpaces,
|
||||
BAD_CAST "*",
|
||||
cur->parent->ns->href);
|
||||
}
|
||||
} else {
|
||||
val = (const xmlChar *)
|
||||
xmlHashLookup2(ctxt->style->stripSpaces,
|
||||
cur->parent->name, NULL);
|
||||
}
|
||||
if ((val != NULL) &&
|
||||
(xmlStrEqual(val, (xmlChar *) "strip"))) {
|
||||
delNode = cur;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Intentional fall-through */
|
||||
case XML_ELEMENT_NODE:
|
||||
case XML_DOCUMENT_NODE:
|
||||
case XML_HTML_DOCUMENT_NODE:
|
||||
case XML_CDATA_SECTION_NODE:
|
||||
case XML_PI_NODE:
|
||||
case XML_COMMENT_NODE:
|
||||
xmlXPathNodeSetAddUnique(list, cur);
|
||||
break;
|
||||
case XML_DTD_NODE:
|
||||
/* Unlink the DTD, it's still reachable
|
||||
* using doc->intSubset */
|
||||
if (cur->next != NULL)
|
||||
cur->next->prev = cur->prev;
|
||||
if (cur->prev != NULL)
|
||||
cur->prev->next = cur->next;
|
||||
break;
|
||||
case XML_NAMESPACE_DECL:
|
||||
break;
|
||||
default:
|
||||
#ifdef WITH_XSLT_DEBUG_PROCESS
|
||||
XSLT_TRACE(ctxt,XSLT_TRACE_APPLY_TEMPLATES,xsltGenericDebug(xsltGenericDebugContext,
|
||||
"xsltApplyTemplates: skipping cur type %d\n",
|
||||
cur->type));
|
||||
#endif
|
||||
delNode = cur;
|
||||
}
|
||||
if (IS_XSLT_REAL_NODE(cur))
|
||||
xmlXPathNodeSetAddUnique(list, cur);
|
||||
cur = cur->next;
|
||||
if (delNode != NULL) {
|
||||
#ifdef WITH_XSLT_DEBUG_PROCESS
|
||||
XSLT_TRACE(ctxt,XSLT_TRACE_APPLY_TEMPLATES,xsltGenericDebug(xsltGenericDebugContext,
|
||||
"xsltApplyTemplates: removing ignorable blank cur\n"));
|
||||
#endif
|
||||
xmlUnlinkNode(delNode);
|
||||
xmlFreeNode(delNode);
|
||||
delNode = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5121,6 +5018,7 @@ xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
|||
xmlNodePtr sorts[XSLT_MAX_SORT];
|
||||
|
||||
sorts[nbsorts++] = cur;
|
||||
cur = cur->next;
|
||||
|
||||
while (cur) {
|
||||
|
||||
|
|
|
@ -3656,12 +3656,8 @@ xsltPreprocessStylesheet(xsltStylesheetPtr style, xmlNodePtr cur)
|
|||
(!xsltCheckExtURI(style, cur->ns->href))) {
|
||||
goto skip_children;
|
||||
} else if (cur->children != NULL) {
|
||||
if ((cur->children->type != XML_ENTITY_DECL) &&
|
||||
(cur->children->type != XML_ENTITY_REF_NODE) &&
|
||||
(cur->children->type != XML_ENTITY_NODE)) {
|
||||
cur = cur->children;
|
||||
continue;
|
||||
}
|
||||
cur = cur->children;
|
||||
continue;
|
||||
}
|
||||
|
||||
skip_children:
|
||||
|
|
|
@ -291,6 +291,9 @@ struct _xsltTemplate {
|
|||
int templMax; /* Size of the templtes stack */
|
||||
xsltTemplatePtr *templCalledTab; /* templates called */
|
||||
int *templCountTab; /* .. and how often */
|
||||
|
||||
/* Conflict resolution */
|
||||
int position;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1500,17 +1503,18 @@ struct _xsltStylesheet {
|
|||
/*
|
||||
* Template descriptions.
|
||||
*/
|
||||
xsltTemplatePtr templates; /* the ordered list of templates */
|
||||
void *templatesHash; /* hash table or wherever compiled templates
|
||||
information is stored */
|
||||
void *rootMatch; /* template based on / */
|
||||
void *keyMatch; /* template based on key() */
|
||||
void *elemMatch; /* template based on * */
|
||||
void *attrMatch; /* template based on @* */
|
||||
void *parentMatch; /* template based on .. */
|
||||
void *textMatch; /* template based on text() */
|
||||
void *piMatch; /* template based on processing-instruction() */
|
||||
void *commentMatch; /* template based on comment() */
|
||||
xsltTemplatePtr templates; /* the ordered list of templates */
|
||||
xmlHashTablePtr templatesHash; /* hash table or wherever compiled
|
||||
templates information is stored */
|
||||
struct _xsltCompMatch *rootMatch; /* template based on / */
|
||||
struct _xsltCompMatch *keyMatch; /* template based on key() */
|
||||
struct _xsltCompMatch *elemMatch; /* template based on * */
|
||||
struct _xsltCompMatch *attrMatch; /* template based on @* */
|
||||
struct _xsltCompMatch *parentMatch; /* template based on .. */
|
||||
struct _xsltCompMatch *textMatch; /* template based on text() */
|
||||
struct _xsltCompMatch *piMatch; /* template based on
|
||||
processing-instruction() */
|
||||
struct _xsltCompMatch *commentMatch; /* template based on comment() */
|
||||
|
||||
/*
|
||||
* Namespace aliases.
|
||||
|
|
|
@ -20,21 +20,21 @@ extern "C" {
|
|||
*
|
||||
* the version string like "1.2.3"
|
||||
*/
|
||||
#define LIBXSLT_DOTTED_VERSION "1.1.34"
|
||||
#define LIBXSLT_DOTTED_VERSION "1.1.35"
|
||||
|
||||
/**
|
||||
* LIBXSLT_VERSION:
|
||||
*
|
||||
* the version number: 1.2.3 value is 10203
|
||||
*/
|
||||
#define LIBXSLT_VERSION 10134
|
||||
#define LIBXSLT_VERSION 10135
|
||||
|
||||
/**
|
||||
* LIBXSLT_VERSION_STRING:
|
||||
*
|
||||
* the version number string, 1.2.3 value is "10203"
|
||||
*/
|
||||
#define LIBXSLT_VERSION_STRING "10134"
|
||||
#define LIBXSLT_VERSION_STRING "10135"
|
||||
|
||||
/**
|
||||
* LIBXSLT_VERSION_EXTRA:
|
||||
|
|
|
@ -346,7 +346,8 @@ xsltDefaultRegion(const xmlChar *localeName) {
|
|||
void
|
||||
xsltFreeLocale(xsltLocale locale) {
|
||||
#ifdef XSLT_LOCALE_POSIX
|
||||
freelocale(locale);
|
||||
if (locale != NULL)
|
||||
freelocale(locale);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -948,17 +948,19 @@ xsltDocumentSortFunction(xmlNodeSetPtr list) {
|
|||
}
|
||||
|
||||
/**
|
||||
* xsltComputeSortResult:
|
||||
* xsltComputeSortResultiInternal:
|
||||
* @ctxt: a XSLT process context
|
||||
* @sort: node list
|
||||
* @xfrm: Transform strings according to locale
|
||||
*
|
||||
* reorder the current node list accordingly to the set of sorting
|
||||
* requirement provided by the array of nodes.
|
||||
*
|
||||
* Returns a ordered XPath nodeset or NULL in case of error.
|
||||
*/
|
||||
xmlXPathObjectPtr *
|
||||
xsltComputeSortResult(xsltTransformContextPtr ctxt, xmlNodePtr sort) {
|
||||
static xmlXPathObjectPtr *
|
||||
xsltComputeSortResultInternal(xsltTransformContextPtr ctxt, xmlNodePtr sort,
|
||||
int xfrm) {
|
||||
#ifdef XSLT_REFACTORED
|
||||
xsltStyleItemSortPtr comp;
|
||||
#else
|
||||
|
@ -1045,7 +1047,7 @@ xsltComputeSortResult(xsltTransformContextPtr ctxt, xmlNodePtr sort) {
|
|||
}
|
||||
} else {
|
||||
if (res->type == XPATH_STRING) {
|
||||
if (comp->locale != (xsltLocale)0) {
|
||||
if ((xfrm) && (comp->locale != (xsltLocale)0)) {
|
||||
xmlChar *str = res->stringval;
|
||||
res->stringval = (xmlChar *) xsltStrxfrm(comp->locale, str);
|
||||
xmlFree(str);
|
||||
|
@ -1075,6 +1077,21 @@ xsltComputeSortResult(xsltTransformContextPtr ctxt, xmlNodePtr sort) {
|
|||
return(results);
|
||||
}
|
||||
|
||||
/**
|
||||
* xsltComputeSortResult:
|
||||
* @ctxt: a XSLT process context
|
||||
* @sort: node list
|
||||
*
|
||||
* reorder the current node list accordingly to the set of sorting
|
||||
* requirement provided by the array of nodes.
|
||||
*
|
||||
* Returns a ordered XPath nodeset or NULL in case of error.
|
||||
*/
|
||||
xmlXPathObjectPtr *
|
||||
xsltComputeSortResult(xsltTransformContextPtr ctxt, xmlNodePtr sort) {
|
||||
return xsltComputeSortResultInternal(ctxt, sort, /* xfrm */ 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* xsltDefaultSortFunction:
|
||||
* @ctxt: a XSLT process context
|
||||
|
@ -1102,7 +1119,8 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts,
|
|||
int depth;
|
||||
xmlNodePtr node;
|
||||
xmlXPathObjectPtr tmp;
|
||||
int tempstype[XSLT_MAX_SORT], temporder[XSLT_MAX_SORT];
|
||||
int tempstype[XSLT_MAX_SORT], temporder[XSLT_MAX_SORT],
|
||||
templang[XSLT_MAX_SORT];
|
||||
|
||||
if ((ctxt == NULL) || (sorts == NULL) || (nbsorts <= 0) ||
|
||||
(nbsorts >= XSLT_MAX_SORT))
|
||||
|
@ -1124,7 +1142,7 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts,
|
|||
comp->stype =
|
||||
xsltEvalAttrValueTemplate(ctxt, sorts[j],
|
||||
(const xmlChar *) "data-type",
|
||||
XSLT_NAMESPACE);
|
||||
NULL);
|
||||
if (comp->stype != NULL) {
|
||||
tempstype[j] = 1;
|
||||
if (xmlStrEqual(comp->stype, (const xmlChar *) "text"))
|
||||
|
@ -1143,7 +1161,7 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts,
|
|||
if ((comp->order == NULL) && (comp->has_order != 0)) {
|
||||
comp->order = xsltEvalAttrValueTemplate(ctxt, sorts[j],
|
||||
(const xmlChar *) "order",
|
||||
XSLT_NAMESPACE);
|
||||
NULL);
|
||||
if (comp->order != NULL) {
|
||||
temporder[j] = 1;
|
||||
if (xmlStrEqual(comp->order, (const xmlChar *) "ascending"))
|
||||
|
@ -1159,11 +1177,23 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts,
|
|||
}
|
||||
}
|
||||
}
|
||||
templang[j] = 0;
|
||||
if ((comp->lang == NULL) && (comp->has_lang != 0)) {
|
||||
xmlChar *lang = xsltEvalAttrValueTemplate(ctxt, sorts[j],
|
||||
(xmlChar *) "lang",
|
||||
NULL);
|
||||
if (lang != NULL) {
|
||||
templang[j] = 1;
|
||||
comp->locale = xsltNewLocale(lang);
|
||||
xmlFree(lang);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
len = list->nodeNr;
|
||||
|
||||
resultsTab[0] = xsltComputeSortResult(ctxt, sorts[0]);
|
||||
resultsTab[0] = xsltComputeSortResultInternal(ctxt, sorts[0],
|
||||
/* xfrm */ 1);
|
||||
for (i = 1;i < XSLT_MAX_SORT;i++)
|
||||
resultsTab[i] = NULL;
|
||||
|
||||
|
@ -1173,7 +1203,7 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts,
|
|||
descending = comp->descending;
|
||||
number = comp->number;
|
||||
if (results == NULL)
|
||||
return;
|
||||
goto cleanup;
|
||||
|
||||
/* Shell's sort of node-set */
|
||||
for (incr = len / 2; incr > 0; incr /= 2) {
|
||||
|
@ -1234,8 +1264,10 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts,
|
|||
* full set, this might be optimized ... or not
|
||||
*/
|
||||
if (resultsTab[depth] == NULL)
|
||||
resultsTab[depth] = xsltComputeSortResult(ctxt,
|
||||
sorts[depth]);
|
||||
resultsTab[depth] =
|
||||
xsltComputeSortResultInternal(ctxt,
|
||||
sorts[depth],
|
||||
/* xfrm */ 1);
|
||||
res = resultsTab[depth];
|
||||
if (res == NULL)
|
||||
break;
|
||||
|
@ -1315,6 +1347,7 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts,
|
|||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
for (j = 0; j < nbsorts; j++) {
|
||||
comp = sorts[j]->psvi;
|
||||
if (tempstype[j] == 1) {
|
||||
|
@ -1327,6 +1360,10 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts,
|
|||
xmlFree((void *)(comp->order));
|
||||
comp->order = NULL;
|
||||
}
|
||||
if (templang[j] == 1) {
|
||||
xsltFreeLocale(comp->locale);
|
||||
comp->locale = (xsltLocale)0;
|
||||
}
|
||||
if (resultsTab[j] != NULL) {
|
||||
for (i = 0;i < len;i++)
|
||||
xmlXPathFreeObject(resultsTab[j][i]);
|
||||
|
|
Loading…
Reference in a new issue