Commit 6b678a4e authored by Alexandre Julliard's avatar Alexandre Julliard

xslt: Import upstream release 1.1.38.

parent 50c5eb31
...@@ -87,6 +87,7 @@ typedef xsltAttrSetContext *xsltAttrSetContextPtr; ...@@ -87,6 +87,7 @@ typedef xsltAttrSetContext *xsltAttrSetContextPtr;
struct _xsltAttrSetContext { struct _xsltAttrSetContext {
xsltStylesheetPtr topStyle; xsltStylesheetPtr topStyle;
xsltStylesheetPtr style; xsltStylesheetPtr style;
int error;
}; };
static void static void
...@@ -274,7 +275,7 @@ xsltAddUseAttrSetList(xsltUseAttrSetPtr list, const xmlChar *ncname, ...@@ -274,7 +275,7 @@ xsltAddUseAttrSetList(xsltUseAttrSetPtr list, const xmlChar *ncname,
* Returns the newly allocated xsltAttrSetPtr or NULL in case of error. * Returns the newly allocated xsltAttrSetPtr or NULL in case of error.
*/ */
static xsltAttrSetPtr static xsltAttrSetPtr
xsltNewAttrSet() { xsltNewAttrSet(void) {
xsltAttrSetPtr cur; xsltAttrSetPtr cur;
cur = (xsltAttrSetPtr) xmlMalloc(sizeof(xsltAttrSet)); cur = (xsltAttrSetPtr) xmlMalloc(sizeof(xsltAttrSet));
...@@ -421,9 +422,12 @@ xsltParseStylesheetAttributeSet(xsltStylesheetPtr style, xmlNodePtr cur) { ...@@ -421,9 +422,12 @@ xsltParseStylesheetAttributeSet(xsltStylesheetPtr style, xmlNodePtr cur) {
set = xmlHashLookup2(style->attributeSets, ncname, nsUri); set = xmlHashLookup2(style->attributeSets, ncname, nsUri);
if (set == NULL) { if (set == NULL) {
set = xsltNewAttrSet(); set = xsltNewAttrSet();
if (set == NULL) if ((set == NULL) ||
(xmlHashAddEntry2(style->attributeSets, ncname, nsUri, set) < 0)) {
xsltGenericError(xsltGenericErrorContext, "memory error\n");
xsltFreeAttrSet(set);
return; return;
xmlHashAddEntry2(style->attributeSets, ncname, nsUri, set); }
} }
/* /*
...@@ -663,6 +667,12 @@ xsltResolveSASCallback(void *payload, void *data, ...@@ -663,6 +667,12 @@ xsltResolveSASCallback(void *payload, void *data,
xsltStylesheetPtr topStyle = asctx->topStyle; xsltStylesheetPtr topStyle = asctx->topStyle;
xsltStylesheetPtr style = asctx->style; xsltStylesheetPtr style = asctx->style;
if (asctx->error) {
if (style != topStyle)
xsltFreeAttrSet(set);
return;
}
xsltResolveAttrSet(set, topStyle, style, name, ns, 1); xsltResolveAttrSet(set, topStyle, style, name, ns, 1);
/* Move attribute sets to top stylesheet. */ /* Move attribute sets to top stylesheet. */
...@@ -675,6 +685,8 @@ xsltResolveSASCallback(void *payload, void *data, ...@@ -675,6 +685,8 @@ xsltResolveSASCallback(void *payload, void *data,
xsltGenericError(xsltGenericErrorContext, xsltGenericError(xsltGenericErrorContext,
"xsl:attribute-set : internal error, can't move imported " "xsl:attribute-set : internal error, can't move imported "
" attribute set %s\n", name); " attribute set %s\n", name);
asctx->error = 1;
xsltFreeAttrSet(set);
} }
} }
} }
...@@ -695,6 +707,7 @@ xsltResolveStylesheetAttributeSet(xsltStylesheetPtr style) { ...@@ -695,6 +707,7 @@ xsltResolveStylesheetAttributeSet(xsltStylesheetPtr style) {
"Resolving attribute sets references\n"); "Resolving attribute sets references\n");
#endif #endif
asctx.topStyle = style; asctx.topStyle = style;
asctx.error = 0;
cur = style; cur = style;
while (cur != NULL) { while (cur != NULL) {
if (cur->attributeSets != NULL) { if (cur->attributeSets != NULL) {
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <libxml/tree.h> #include <libxml/tree.h>
#include "xsltexports.h" #include "xsltexports.h"
#include "xsltInternals.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
......
...@@ -154,12 +154,9 @@ xsltSetAttrVTsegment(xsltAttrVTPtr avt, void *val) { ...@@ -154,12 +154,9 @@ xsltSetAttrVTsegment(xsltAttrVTPtr avt, void *val) {
if (avt->nb_seg >= avt->max_seg) { if (avt->nb_seg >= avt->max_seg) {
size_t size = sizeof(xsltAttrVT) + size_t size = sizeof(xsltAttrVT) +
(avt->max_seg + MAX_AVT_SEG) * sizeof(void *); (avt->max_seg + MAX_AVT_SEG) * sizeof(void *);
xsltAttrVTPtr tmp = (xsltAttrVTPtr) xmlRealloc(avt, size); avt = (xsltAttrVTPtr) xmlRealloc(avt, size);
if (tmp == NULL) { if (avt == NULL)
xsltFreeAttrVT(avt);
return NULL; return NULL;
}
avt = tmp;
memset(&avt->segments[avt->nb_seg], 0, MAX_AVT_SEG*sizeof(void *)); memset(&avt->segments[avt->nb_seg], 0, MAX_AVT_SEG*sizeof(void *));
avt->max_seg += MAX_AVT_SEG; avt->max_seg += MAX_AVT_SEG;
} }
...@@ -182,7 +179,8 @@ xsltCompileAttr(xsltStylesheetPtr style, xmlAttrPtr attr) { ...@@ -182,7 +179,8 @@ xsltCompileAttr(xsltStylesheetPtr style, xmlAttrPtr attr) {
const xmlChar *cur; const xmlChar *cur;
xmlChar *ret = NULL; xmlChar *ret = NULL;
xmlChar *expr = NULL; xmlChar *expr = NULL;
xsltAttrVTPtr avt; xmlXPathCompExprPtr comp = NULL;
xsltAttrVTPtr avt, tmp;
int i = 0, lastavt = 0; int i = 0, lastavt = 0;
if ((style == NULL) || (attr == NULL) || (attr->children == NULL)) if ((style == NULL) || (attr == NULL) || (attr->children == NULL))
...@@ -246,8 +244,9 @@ xsltCompileAttr(xsltStylesheetPtr style, xmlAttrPtr attr) { ...@@ -246,8 +244,9 @@ xsltCompileAttr(xsltStylesheetPtr style, xmlAttrPtr attr) {
str = cur; str = cur;
if (avt->nb_seg == 0) if (avt->nb_seg == 0)
avt->strstart = 1; avt->strstart = 1;
if ((avt = xsltSetAttrVTsegment(avt, (void *) ret)) == NULL) if ((tmp = xsltSetAttrVTsegment(avt, (void *) ret)) == NULL)
goto error; goto error;
avt = tmp;
ret = NULL; ret = NULL;
lastavt = 0; lastavt = 0;
} }
...@@ -280,8 +279,6 @@ xsltCompileAttr(xsltStylesheetPtr style, xmlAttrPtr attr) { ...@@ -280,8 +279,6 @@ xsltCompileAttr(xsltStylesheetPtr style, xmlAttrPtr attr) {
XSLT_TODO XSLT_TODO
goto error; goto error;
} else { } else {
xmlXPathCompExprPtr comp;
comp = xsltXPathCompile(style, expr); comp = xsltXPathCompile(style, expr);
if (comp == NULL) { if (comp == NULL) {
xsltTransformError(NULL, style, attr->parent, xsltTransformError(NULL, style, attr->parent,
...@@ -293,14 +290,23 @@ xsltCompileAttr(xsltStylesheetPtr style, xmlAttrPtr attr) { ...@@ -293,14 +290,23 @@ xsltCompileAttr(xsltStylesheetPtr style, xmlAttrPtr attr) {
if (avt->nb_seg == 0) if (avt->nb_seg == 0)
avt->strstart = 0; avt->strstart = 0;
if (lastavt == 1) { if (lastavt == 1) {
if ((avt = xsltSetAttrVTsegment(avt, NULL)) == NULL) if ((tmp = xsltSetAttrVTsegment(avt, NULL)) == NULL) {
xsltTransformError(NULL, style, attr->parent,
"out of memory\n");
goto error; goto error;
}
avt = tmp;
} }
if ((avt = xsltSetAttrVTsegment(avt, (void *) comp)) == NULL) if ((tmp = xsltSetAttrVTsegment(avt, (void *) comp)) == NULL) {
xsltTransformError(NULL, style, attr->parent,
"out of memory\n");
goto error; goto error;
}
avt = tmp;
lastavt = 1; lastavt = 1;
xmlFree(expr); xmlFree(expr);
expr = NULL; expr = NULL;
comp = NULL;
} }
cur++; cur++;
str = cur; str = cur;
...@@ -325,8 +331,9 @@ xsltCompileAttr(xsltStylesheetPtr style, xmlAttrPtr attr) { ...@@ -325,8 +331,9 @@ xsltCompileAttr(xsltStylesheetPtr style, xmlAttrPtr attr) {
str = cur; str = cur;
if (avt->nb_seg == 0) if (avt->nb_seg == 0)
avt->strstart = 1; avt->strstart = 1;
if ((avt = xsltSetAttrVTsegment(avt, (void *) ret)) == NULL) if ((tmp = xsltSetAttrVTsegment(avt, (void *) ret)) == NULL)
goto error; goto error;
avt = tmp;
ret = NULL; ret = NULL;
} }
...@@ -350,6 +357,8 @@ error: ...@@ -350,6 +357,8 @@ error:
xmlFree(ret); xmlFree(ret);
if (expr != NULL) if (expr != NULL)
xmlFree(expr); xmlFree(expr);
if (comp != NULL)
xmlXPathFreeCompExpr(comp);
} }
......
...@@ -399,6 +399,8 @@ xsltLoadStyleDocument(xsltStylesheetPtr style, const xmlChar *URI) { ...@@ -399,6 +399,8 @@ xsltLoadStyleDocument(xsltStylesheetPtr style, const xmlChar *URI) {
return(NULL); return(NULL);
ret = xsltNewStyleDocument(style, doc); ret = xsltNewStyleDocument(style, doc);
if (ret == NULL)
xmlFreeDoc(doc);
return(ret); return(ret);
} }
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <libxml/xmlIO.h> #include <libxml/xmlIO.h>
#include "xslt.h" #include "xslt.h"
#include "xsltInternals.h" #include "xsltInternals.h"
#include "xsltlocale.h"
#include "xsltutils.h" #include "xsltutils.h"
#include "imports.h" #include "imports.h"
#include "extensions.h" #include "extensions.h"
...@@ -738,8 +739,11 @@ xsltStyleInitializeStylesheetModule(xsltStylesheetPtr style, ...@@ -738,8 +739,11 @@ xsltStyleInitializeStylesheetModule(xsltStylesheetPtr style,
* Store the user-data in the context of the given stylesheet. * Store the user-data in the context of the given stylesheet.
*/ */
dataContainer = xsltNewExtData(module, userData); dataContainer = xsltNewExtData(module, userData);
if (dataContainer == NULL) if (dataContainer == NULL) {
if (module->styleShutdownFunc)
module->styleShutdownFunc(style, URI, userData);
return (NULL); return (NULL);
}
if (xmlHashAddEntry(style->extInfos, URI, if (xmlHashAddEntry(style->extInfos, URI,
(void *) dataContainer) < 0) (void *) dataContainer) < 0)
...@@ -920,9 +924,8 @@ xsltGetExtData(xsltTransformContextPtr ctxt, const xmlChar * URI) ...@@ -920,9 +924,8 @@ xsltGetExtData(xsltTransformContextPtr ctxt, const xmlChar * URI)
return (NULL); return (NULL);
data = xsltNewExtData(module, extData); data = xsltNewExtData(module, extData);
if (data == NULL) if ((data == NULL) ||
return (NULL); (xmlHashAddEntry(ctxt->extInfos, URI, (void *) data) < 0)) {
if (xmlHashAddEntry(ctxt->extInfos, URI, (void *) data) < 0) {
xsltTransformError(ctxt, NULL, NULL, xsltTransformError(ctxt, NULL, NULL,
"Failed to register module data: %s\n", "Failed to register module data: %s\n",
URI); URI);
...@@ -994,6 +997,8 @@ xsltInitCtxtExt(void *payload, void *data, const xmlChar * URI) ...@@ -994,6 +997,8 @@ xsltInitCtxtExt(void *payload, void *data, const xmlChar * URI)
} }
ctxtData = xsltNewExtData(module, extData); ctxtData = xsltNewExtData(module, extData);
if (ctxtData == NULL) { if (ctxtData == NULL) {
if (module->shutdownFunc)
module->shutdownFunc(ctxt->ctxt, URI, extData);
ctxt->ret = -1; ctxt->ret = -1;
return; return;
} }
...@@ -1001,6 +1006,9 @@ xsltInitCtxtExt(void *payload, void *data, const xmlChar * URI) ...@@ -1001,6 +1006,9 @@ xsltInitCtxtExt(void *payload, void *data, const xmlChar * URI)
if (ctxt->ctxt->extInfos == NULL) if (ctxt->ctxt->extInfos == NULL)
ctxt->ctxt->extInfos = xmlHashCreate(10); ctxt->ctxt->extInfos = xmlHashCreate(10);
if (ctxt->ctxt->extInfos == NULL) { if (ctxt->ctxt->extInfos == NULL) {
if (module->shutdownFunc)
module->shutdownFunc(ctxt->ctxt, URI, extData);
xsltFreeExtData(ctxtData);
ctxt->ret = -1; ctxt->ret = -1;
return; return;
} }
......
...@@ -242,14 +242,14 @@ xsltDocumentFunction(xmlXPathParserContextPtr ctxt, int nargs) ...@@ -242,14 +242,14 @@ xsltDocumentFunction(xmlXPathParserContextPtr ctxt, int nargs)
obj2 = valuePop(ctxt); obj2 = valuePop(ctxt);
} }
if (ctxt->value->type == XPATH_NODESET) { if ((ctxt->value != NULL) && (ctxt->value->type == XPATH_NODESET)) {
int i; int i;
xmlXPathObjectPtr newobj, ret; xmlXPathObjectPtr newobj, ret;
obj = valuePop(ctxt); obj = valuePop(ctxt);
ret = xmlXPathNewNodeSet(NULL); ret = xmlXPathNewNodeSet(NULL);
if ((obj != NULL) && obj->nodesetval) { if ((obj != NULL) && (obj->nodesetval != NULL) && (ret != NULL)) {
for (i = 0; i < obj->nodesetval->nodeNr; i++) { for (i = 0; i < obj->nodesetval->nodeNr; i++) {
valuePush(ctxt, valuePush(ctxt,
xmlXPathNewNodeSet(obj->nodesetval->nodeTab[i])); xmlXPathNewNodeSet(obj->nodesetval->nodeTab[i]));
...@@ -261,11 +261,15 @@ xsltDocumentFunction(xmlXPathParserContextPtr ctxt, int nargs) ...@@ -261,11 +261,15 @@ xsltDocumentFunction(xmlXPathParserContextPtr ctxt, int nargs)
xmlXPathNewNodeSet(obj->nodesetval-> xmlXPathNewNodeSet(obj->nodesetval->
nodeTab[i])); nodeTab[i]));
} }
if (ctxt->error)
break;
xsltDocumentFunction(ctxt, 2); xsltDocumentFunction(ctxt, 2);
newobj = valuePop(ctxt); newobj = valuePop(ctxt);
ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval, if (newobj != NULL) {
newobj->nodesetval); ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval,
xmlXPathFreeObject(newobj); newobj->nodesetval);
xmlXPathFreeObject(newobj);
}
} }
} }
...@@ -280,7 +284,7 @@ xsltDocumentFunction(xmlXPathParserContextPtr ctxt, int nargs) ...@@ -280,7 +284,7 @@ xsltDocumentFunction(xmlXPathParserContextPtr ctxt, int nargs)
* Make sure it's converted to a string * Make sure it's converted to a string
*/ */
xmlXPathStringFunction(ctxt, 1); xmlXPathStringFunction(ctxt, 1);
if (ctxt->value->type != XPATH_STRING) { if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) {
xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
"document() : invalid arg expecting a string\n"); "document() : invalid arg expecting a string\n");
ctxt->error = XPATH_INVALID_TYPE; ctxt->error = XPATH_INVALID_TYPE;
...@@ -379,6 +383,12 @@ xsltKeyFunction(xmlXPathParserContextPtr ctxt, int nargs){ ...@@ -379,6 +383,12 @@ xsltKeyFunction(xmlXPathParserContextPtr ctxt, int nargs){
xmlXPathObjectPtr newobj, ret; xmlXPathObjectPtr newobj, ret;
ret = xmlXPathNewNodeSet(NULL); ret = xmlXPathNewNodeSet(NULL);
if (ret == NULL) {
ctxt->error = XPATH_MEMORY_ERROR;
xmlXPathFreeObject(obj1);
xmlXPathFreeObject(obj2);
return;
}
if (obj2->nodesetval != NULL) { if (obj2->nodesetval != NULL) {
for (i = 0; i < obj2->nodesetval->nodeNr; i++) { for (i = 0; i < obj2->nodesetval->nodeNr; i++) {
...@@ -388,8 +398,9 @@ xsltKeyFunction(xmlXPathParserContextPtr ctxt, int nargs){ ...@@ -388,8 +398,9 @@ xsltKeyFunction(xmlXPathParserContextPtr ctxt, int nargs){
xmlXPathStringFunction(ctxt, 1); xmlXPathStringFunction(ctxt, 1);
xsltKeyFunction(ctxt, 2); xsltKeyFunction(ctxt, 2);
newobj = valuePop(ctxt); newobj = valuePop(ctxt);
ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval, if (newobj != NULL)
newobj->nodesetval); ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval,
newobj->nodesetval);
xmlXPathFreeObject(newobj); xmlXPathFreeObject(newobj);
} }
} }
...@@ -446,13 +457,13 @@ xsltKeyFunction(xmlXPathParserContextPtr ctxt, int nargs){ ...@@ -446,13 +457,13 @@ xsltKeyFunction(xmlXPathParserContextPtr ctxt, int nargs){
*/ */
valuePush(ctxt, obj2); valuePush(ctxt, obj2);
xmlXPathStringFunction(ctxt, 1); xmlXPathStringFunction(ctxt, 1);
if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { obj2 = valuePop(ctxt);
if ((obj2 == NULL) || (obj2->type != XPATH_STRING)) {
xsltTransformError(tctxt, NULL, tctxt->inst, xsltTransformError(tctxt, NULL, tctxt->inst,
"key() : invalid arg expecting a string\n"); "key() : invalid arg expecting a string\n");
ctxt->error = XPATH_INVALID_TYPE; ctxt->error = XPATH_INVALID_TYPE;
goto error; goto error;
} }
obj2 = valuePop(ctxt);
value = obj2->stringval; value = obj2->stringval;
/* /*
...@@ -555,6 +566,10 @@ xsltUnparsedEntityURIFunction(xmlXPathParserContextPtr ctxt, int nargs){ ...@@ -555,6 +566,10 @@ xsltUnparsedEntityURIFunction(xmlXPathParserContextPtr ctxt, int nargs){
obj = valuePop(ctxt); obj = valuePop(ctxt);
if (obj->type != XPATH_STRING) { if (obj->type != XPATH_STRING) {
obj = xmlXPathConvertString(obj); obj = xmlXPathConvertString(obj);
if (obj == NULL) {
xmlXPathErr(ctxt, XPATH_MEMORY_ERROR);
return;
}
} }
str = obj->stringval; str = obj->stringval;
...@@ -647,7 +662,8 @@ xsltFormatNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) ...@@ -647,7 +662,8 @@ xsltFormatNumberFunction(xmlXPathParserContextPtr ctxt, int nargs)
return; return;
} }
if (formatValues != NULL) { if ((ctxt->error == 0) &&
(formatValues != NULL) && (formatObj != NULL) && (numberObj != NULL)) {
if (xsltFormatNumberConversion(formatValues, if (xsltFormatNumberConversion(formatValues,
formatObj->stringval, formatObj->stringval,
numberObj->floatval, numberObj->floatval,
...@@ -672,11 +688,16 @@ xsltFormatNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) ...@@ -672,11 +688,16 @@ xsltFormatNumberFunction(xmlXPathParserContextPtr ctxt, int nargs)
*/ */
void void
xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){ xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){
static char base_address; xsltTransformContextPtr tctxt;
xmlNodePtr cur = NULL; xmlNodePtr cur = NULL;
xmlXPathObjectPtr obj = NULL; xmlXPathObjectPtr obj = NULL;
long val; char *str;
xmlChar str[30]; const xmlChar *nsPrefix = NULL;
void **psviPtr;
unsigned long id;
size_t size, nsPrefixSize;
tctxt = xsltXPathGetTransformContext(ctxt);
if (nargs == 0) { if (nargs == 0) {
cur = ctxt->context->node; cur = ctxt->context->node;
...@@ -686,16 +707,15 @@ xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){ ...@@ -686,16 +707,15 @@ xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){
if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_NODESET)) { if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_NODESET)) {
ctxt->error = XPATH_INVALID_TYPE; ctxt->error = XPATH_INVALID_TYPE;
xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, xsltTransformError(tctxt, NULL, NULL,
"generate-id() : invalid arg expecting a node-set\n"); "generate-id() : invalid arg expecting a node-set\n");
return; goto out;
} }
obj = valuePop(ctxt); obj = valuePop(ctxt);
nodelist = obj->nodesetval; nodelist = obj->nodesetval;
if ((nodelist == NULL) || (nodelist->nodeNr <= 0)) { if ((nodelist == NULL) || (nodelist->nodeNr <= 0)) {
xmlXPathFreeObject(obj);
valuePush(ctxt, xmlXPathNewCString("")); valuePush(ctxt, xmlXPathNewCString(""));
return; goto out;
} }
cur = nodelist->nodeTab[0]; cur = nodelist->nodeTab[0];
for (i = 1;i < nodelist->nodeNr;i++) { for (i = 1;i < nodelist->nodeNr;i++) {
...@@ -704,22 +724,93 @@ xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){ ...@@ -704,22 +724,93 @@ xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){
cur = nodelist->nodeTab[i]; cur = nodelist->nodeTab[i];
} }
} else { } else {
xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, xsltTransformError(tctxt, NULL, NULL,
"generate-id() : invalid number of args %d\n", nargs); "generate-id() : invalid number of args %d\n", nargs);
ctxt->error = XPATH_INVALID_ARITY; ctxt->error = XPATH_INVALID_ARITY;
return; goto out;
} }
if (obj) size = 30; /* for "id%lu" */
xmlXPathFreeObject(obj);
if (cur->type == XML_NAMESPACE_DECL) {
xmlNsPtr ns = (xmlNsPtr) cur;
val = (long)((char *)cur - (char *)&base_address); nsPrefix = ns->prefix;
if (val >= 0) { if (nsPrefix == NULL)
snprintf((char *)str, sizeof(str), "idp%ld", val); nsPrefix = BAD_CAST "";
nsPrefixSize = xmlStrlen(nsPrefix);
/* For "ns" and hex-encoded string */
size += nsPrefixSize * 2 + 2;
/* Parent is stored in 'next'. */
cur = (xmlNodePtr) ns->next;
}
psviPtr = xsltGetPSVIPtr(cur);
if (psviPtr == NULL) {
xsltTransformError(tctxt, NULL, NULL,
"generate-id(): invalid node type %d\n", cur->type);
ctxt->error = XPATH_INVALID_TYPE;
goto out;
}
if (xsltGetSourceNodeFlags(cur) & XSLT_SOURCE_NODE_HAS_ID) {
id = (unsigned long) (size_t) *psviPtr;
} else { } else {
snprintf((char *)str, sizeof(str), "idm%ld", -val); if (cur->type == XML_TEXT_NODE && cur->line == USHRT_MAX) {
/* Text nodes store big line numbers in psvi. */
cur->line = 0;
} else if (*psviPtr != NULL) {
xsltTransformError(tctxt, NULL, NULL,
"generate-id(): psvi already set\n");
ctxt->error = XPATH_MEMORY_ERROR;
goto out;
}
if (tctxt->currentId == ULONG_MAX) {
xsltTransformError(tctxt, NULL, NULL,
"generate-id(): id overflow\n");
ctxt->error = XPATH_MEMORY_ERROR;
goto out;
}
id = ++tctxt->currentId;
*psviPtr = (void *) (size_t) id;
xsltSetSourceNodeFlags(tctxt, cur, XSLT_SOURCE_NODE_HAS_ID);
} }
valuePush(ctxt, xmlXPathNewString(str));
str = xmlMalloc(size);
if (str == NULL) {
xsltTransformError(tctxt, NULL, NULL,
"generate-id(): out of memory\n");
ctxt->error = XPATH_MEMORY_ERROR;
goto out;
}
if (nsPrefix == NULL) {
snprintf(str, size, "id%lu", id);
} else {
size_t i, j;
snprintf(str, size, "id%luns", id);
/*
* Only ASCII alphanumerics are allowed, so we hex-encode the prefix.
*/
j = strlen(str);
for (i = 0; i < nsPrefixSize; i++) {
int v;
v = nsPrefix[i] >> 4;
str[j++] = v < 10 ? '0' + v : 'A' + (v - 10);
v = nsPrefix[i] & 15;
str[j++] = v < 10 ? '0' + v : 'A' + (v - 10);
}
str[j] = '\0';
}
valuePush(ctxt, xmlXPathWrapString(BAD_CAST str));
out:
xmlXPathFreeObject(obj);
} }
/** /**
......
...@@ -53,6 +53,35 @@ static void xsltFixImportedCompSteps(xsltStylesheetPtr master, ...@@ -53,6 +53,35 @@ static void xsltFixImportedCompSteps(xsltStylesheetPtr master,
} }
} }
static int
xsltCheckCycle(xsltStylesheetPtr style, const xmlChar *URI) {
xsltStylesheetPtr ancestor;
xsltDocumentPtr docptr;
/*
* in order to detect recursion, we check all previously included
* stylesheets.
*/
docptr = style->includes;
while (docptr != NULL) {
if (xmlStrEqual(docptr->doc->URL, URI))
return(-1);
docptr = docptr->includes;
}
/*
* Also check imported stylesheets.
*/
ancestor = style;
while (ancestor != NULL) {
if (xmlStrEqual(ancestor->doc->URL, URI))
return(-1);
ancestor = ancestor->parent;
}
return(0);
}
/** /**
* xsltParseStylesheetImport: * xsltParseStylesheetImport:
* @style: the XSLT stylesheet * @style: the XSLT stylesheet
...@@ -91,16 +120,10 @@ xsltParseStylesheetImport(xsltStylesheetPtr style, xmlNodePtr cur) { ...@@ -91,16 +120,10 @@ xsltParseStylesheetImport(xsltStylesheetPtr style, xmlNodePtr cur) {
goto error; goto error;
} }
res = style; if (xsltCheckCycle(style, URI) < 0) {
while (res != NULL) { xsltTransformError(NULL, style, cur,
if (res->doc == NULL) "xsl:import : recursion detected on imported URL %s\n", URI);
break; goto error;
if (xmlStrEqual(res->doc->URL, URI)) {
xsltTransformError(NULL, style, cur,
"xsl:import : recursion detected on imported URL %s\n", URI);
goto error;
}
res = res->parent;
} }
/* /*
...@@ -170,7 +193,6 @@ xsltParseStylesheetInclude(xsltStylesheetPtr style, xmlNodePtr cur) { ...@@ -170,7 +193,6 @@ xsltParseStylesheetInclude(xsltStylesheetPtr style, xmlNodePtr cur) {
xmlChar *URI = NULL; xmlChar *URI = NULL;
xsltStylesheetPtr result; xsltStylesheetPtr result;
xsltDocumentPtr include; xsltDocumentPtr include;
xsltDocumentPtr docptr;
int oldNopreproc; int oldNopreproc;
if ((cur == NULL) || (style == NULL)) if ((cur == NULL) || (style == NULL))
...@@ -191,18 +213,10 @@ xsltParseStylesheetInclude(xsltStylesheetPtr style, xmlNodePtr cur) { ...@@ -191,18 +213,10 @@ xsltParseStylesheetInclude(xsltStylesheetPtr style, xmlNodePtr cur) {
goto error; goto error;
} }
/* if (xsltCheckCycle(style, URI) < 0) {
* in order to detect recursion, we check all previously included xsltTransformError(NULL, style, cur,
* stylesheets. "xsl:include : recursion detected on included URL %s\n", URI);
*/ goto error;
docptr = style->includes;
while (docptr != NULL) {
if (xmlStrEqual(docptr->doc->URL, URI)) {
xsltTransformError(NULL, style, cur,
"xsl:include : recursion detected on included URL %s\n", URI);
goto error;
}
docptr = docptr->includes;
} }
include = xsltLoadStyleDocument(style, URI); include = xsltLoadStyleDocument(style, URI);
......
...@@ -294,6 +294,8 @@ xsltAddKey(xsltStylesheetPtr style, const xmlChar *name, ...@@ -294,6 +294,8 @@ xsltAddKey(xsltStylesheetPtr style, const xmlChar *name,
#endif #endif
key = xsltNewKeyDef(name, nameURI); key = xsltNewKeyDef(name, nameURI);
if (key == NULL)
return(-1);
key->match = xmlStrdup(match); key->match = xmlStrdup(match);
key->use = xmlStrdup(use); key->use = xmlStrdup(use);
key->inst = inst; key->inst = inst;
...@@ -827,31 +829,17 @@ fprintf(stderr, "xsltInitCtxtKey %s : %d\n", keyDef->name, ctxt->keyInitLevel); ...@@ -827,31 +829,17 @@ fprintf(stderr, "xsltInitCtxtKey %s : %d\n", keyDef->name, ctxt->keyInitLevel);
keylist = xmlXPathNodeSetCreate(cur); keylist = xmlXPathNodeSetCreate(cur);
if (keylist == NULL) if (keylist == NULL)
goto error; goto error;
xmlHashAddEntry(table->keys, str, keylist); if (xmlHashAddEntry(table->keys, str, keylist) < 0) {
xmlXPathFreeNodeSet(keylist);
goto error;
}
} else { } else {
/* /*
* TODO: How do we know if this function failed? * TODO: How do we know if this function failed?
*/ */
xmlXPathNodeSetAdd(keylist, cur); xmlXPathNodeSetAdd(keylist, cur);
} }
switch (cur->type) { xsltSetSourceNodeFlags(ctxt, cur, XSLT_SOURCE_NODE_HAS_KEY);
case XML_ELEMENT_NODE:
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_PI_NODE:
case XML_COMMENT_NODE:
cur->psvi = keyDef;
break;
case XML_ATTRIBUTE_NODE:
((xmlAttrPtr) cur)->psvi = keyDef;
break;
case XML_DOCUMENT_NODE:
case XML_HTML_DOCUMENT_NODE:
((xmlDocPtr) cur)->psvi = keyDef;
break;
default:
break;
}
xmlFree(str); xmlFree(str);
str = NULL; str = NULL;
......
...@@ -116,7 +116,7 @@ xsltIsLetterDigit(int val) { ...@@ -116,7 +116,7 @@ xsltIsLetterDigit(int val) {
#define IS_DIGIT_ONE(x) xsltIsDigitZero((x)-1) #define IS_DIGIT_ONE(x) xsltIsDigitZero((x)-1)
static int static int
xsltIsDigitZero(unsigned int ch) xsltIsDigitZero(int ch)
{ {
/* /*
* Reference: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt * Reference: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
...@@ -183,7 +183,7 @@ xsltNumberFormatDecimal(xmlBufferPtr buffer, ...@@ -183,7 +183,7 @@ xsltNumberFormatDecimal(xmlBufferPtr buffer,
i = -1; i = -1;
break; break;
} }
*(--pointer) = (xmlChar)val; *(--pointer) = val;
} }
else { else {
/* /*
...@@ -353,8 +353,7 @@ xsltNumberFormatTokenize(const xmlChar *format, ...@@ -353,8 +353,7 @@ xsltNumberFormatTokenize(const xmlChar *format,
* Insert initial non-alphanumeric token. * Insert initial non-alphanumeric token.
* There is always such a token in the list, even if NULL * There is always such a token in the list, even if NULL
*/ */
while (!xsltIsLetterDigit(val = xmlStringCurrentChar(NULL, format+ix, while (!xsltIsLetterDigit(val = xsltGetUTF8CharZ(format+ix, &len))) {
&len))) {
if (format[ix] == 0) /* if end of format string */ if (format[ix] == 0) /* if end of format string */
break; /* while */ break; /* while */
ix += len; ix += len;
...@@ -377,19 +376,19 @@ xsltNumberFormatTokenize(const xmlChar *format, ...@@ -377,19 +376,19 @@ xsltNumberFormatTokenize(const xmlChar *format,
tokens->end = NULL; tokens->end = NULL;
} }
val = xmlStringCurrentChar(NULL, format+ix, &len); val = xsltGetUTF8CharZ(format+ix, &len);
if (IS_DIGIT_ONE(val) || if (IS_DIGIT_ONE(val) ||
IS_DIGIT_ZERO(val)) { IS_DIGIT_ZERO(val)) {
tokens->tokens[tokens->nTokens].width = 1; tokens->tokens[tokens->nTokens].width = 1;
while (IS_DIGIT_ZERO(val)) { while (IS_DIGIT_ZERO(val)) {
tokens->tokens[tokens->nTokens].width++; tokens->tokens[tokens->nTokens].width++;
ix += len; ix += len;
val = xmlStringCurrentChar(NULL, format+ix, &len); val = xsltGetUTF8CharZ(format+ix, &len);
} }
if (IS_DIGIT_ONE(val)) { if (IS_DIGIT_ONE(val)) {
tokens->tokens[tokens->nTokens].token = val - 1; tokens->tokens[tokens->nTokens].token = val - 1;
ix += len; ix += len;
val = xmlStringCurrentChar(NULL, format+ix, &len); val = xsltGetUTF8CharZ(format+ix, &len);
} else { } else {
tokens->tokens[tokens->nTokens].token = '0'; tokens->tokens[tokens->nTokens].token = '0';
tokens->tokens[tokens->nTokens].width = 1; tokens->tokens[tokens->nTokens].width = 1;
...@@ -400,7 +399,7 @@ xsltNumberFormatTokenize(const xmlChar *format, ...@@ -400,7 +399,7 @@ xsltNumberFormatTokenize(const xmlChar *format,
(val == 'i') ) { (val == 'i') ) {
tokens->tokens[tokens->nTokens].token = val; tokens->tokens[tokens->nTokens].token = val;
ix += len; ix += len;
val = xmlStringCurrentChar(NULL, format+ix, &len); val = xsltGetUTF8CharZ(format+ix, &len);
} else { } else {
/* XSLT section 7.7 /* XSLT section 7.7
* "Any other format token indicates a numbering sequence * "Any other format token indicates a numbering sequence
...@@ -422,7 +421,7 @@ xsltNumberFormatTokenize(const xmlChar *format, ...@@ -422,7 +421,7 @@ xsltNumberFormatTokenize(const xmlChar *format,
*/ */
while (xsltIsLetterDigit(val)) { while (xsltIsLetterDigit(val)) {
ix += len; ix += len;
val = xmlStringCurrentChar(NULL, format+ix, &len); val = xsltGetUTF8CharZ(format+ix, &len);
} }
/* /*
...@@ -433,7 +432,7 @@ xsltNumberFormatTokenize(const xmlChar *format, ...@@ -433,7 +432,7 @@ xsltNumberFormatTokenize(const xmlChar *format,
if (val == 0) if (val == 0)
break; /* while */ break; /* while */
ix += len; ix += len;
val = xmlStringCurrentChar(NULL, format+ix, &len); val = xsltGetUTF8CharZ(format+ix, &len);
} }
if (ix > j) if (ix > j)
tokens->end = xmlStrndup(&format[j], ix - j); tokens->end = xmlStrndup(&format[j], ix - j);
...@@ -965,6 +964,7 @@ xsltFormatNumberConversion(xsltDecimalFormatPtr self, ...@@ -965,6 +964,7 @@ xsltFormatNumberConversion(xsltDecimalFormatPtr self,
xmlChar *the_format, *prefix = NULL, *suffix = NULL; xmlChar *the_format, *prefix = NULL, *suffix = NULL;
xmlChar *nprefix, *nsuffix = NULL; xmlChar *nprefix, *nsuffix = NULL;
int prefix_length, suffix_length = 0, nprefix_length, nsuffix_length; int prefix_length, suffix_length = 0, nprefix_length, nsuffix_length;
int exp10;
double scale; double scale;
int j, len = 0; int j, len = 0;
int self_grouping_len; int self_grouping_len;
...@@ -985,32 +985,12 @@ xsltFormatNumberConversion(xsltDecimalFormatPtr self, ...@@ -985,32 +985,12 @@ xsltFormatNumberConversion(xsltDecimalFormatPtr self,
"Invalid format (0-length)\n"); "Invalid format (0-length)\n");
} }
*result = NULL; *result = NULL;
switch (xmlXPathIsInf(number)) { if (xmlXPathIsNaN(number)) {
case -1: if ((self == NULL) || (self->noNumber == NULL))
if (self->minusSign == NULL) *result = xmlStrdup(BAD_CAST "NaN");
*result = xmlStrdup(BAD_CAST "-"); else
else *result = xmlStrdup(self->noNumber);
*result = xmlStrdup(self->minusSign); return(status);
/* Intentional fall-through */
case 1:
if ((self == NULL) || (self->infinity == NULL))
*result = xmlStrcat(*result, BAD_CAST "Infinity");
else
*result = xmlStrcat(*result, self->infinity);
return(status);
default:
if (xmlXPathIsNaN(number)) {
if ((self == NULL) || (self->noNumber == NULL))
*result = xmlStrdup(BAD_CAST "NaN");
else
*result = xmlStrdup(self->noNumber);
return(status);
}
}
buffer = xmlBufferCreate();
if (buffer == NULL) {
return XPATH_MEMORY_ERROR;
} }
format_info.integer_hash = 0; format_info.integer_hash = 0;
...@@ -1283,6 +1263,30 @@ OUTPUT_NUMBER: ...@@ -1283,6 +1263,30 @@ OUTPUT_NUMBER:
format_info.add_decimal = TRUE; format_info.add_decimal = TRUE;
} }
/* Apply multiplier */
number *= (double)format_info.multiplier;
switch (xmlXPathIsInf(number)) {
case -1:
if (self->minusSign == NULL)
*result = xmlStrdup(BAD_CAST "-");
else
*result = xmlStrdup(self->minusSign);
/* Intentional fall-through */
case 1:
if ((self == NULL) || (self->infinity == NULL))
*result = xmlStrcat(*result, BAD_CAST "Infinity");
else
*result = xmlStrcat(*result, self->infinity);
return(status);
default:
break;
}
buffer = xmlBufferCreate();
if (buffer == NULL) {
return XPATH_MEMORY_ERROR;
}
/* Ready to output our number. First see if "default sign" is required */ /* Ready to output our number. First see if "default sign" is required */
if (default_sign != 0) if (default_sign != 0)
xmlBufferAdd(buffer, self->minusSign, xmlUTF8Strsize(self->minusSign, 1)); xmlBufferAdd(buffer, self->minusSign, xmlUTF8Strsize(self->minusSign, 1));
...@@ -1297,10 +1301,24 @@ OUTPUT_NUMBER: ...@@ -1297,10 +1301,24 @@ OUTPUT_NUMBER:
j += len; j += len;
} }
/* Round to n digits */
number = fabs(number);
exp10 = format_info.frac_digits + format_info.frac_hash;
/* DBL_MAX_10_EXP should be 308 on IEEE platforms. */
if (exp10 > DBL_MAX_10_EXP) {
if (format_info.frac_digits > DBL_MAX_10_EXP) {
format_info.frac_digits = DBL_MAX_10_EXP;
format_info.frac_hash = 0;
} else {
format_info.frac_hash = DBL_MAX_10_EXP - format_info.frac_digits;
}
exp10 = DBL_MAX_10_EXP;
}
scale = pow(10.0, (double) exp10);
number += .5 / scale;
number -= fmod(number, 1 / scale);
/* Next do the integer part of the number */ /* Next do the integer part of the number */
number = fabs(number) * (double)format_info.multiplier;
scale = pow(10.0, (double)(format_info.frac_digits + format_info.frac_hash));
number = floor((scale * number + 0.5)) / scale;
if ((self->grouping != NULL) && if ((self->grouping != NULL) &&
(self->grouping[0] != 0)) { (self->grouping[0] != 0)) {
int gchar; int gchar;
......
...@@ -311,10 +311,6 @@ xsltCompMatchAdd(xsltParserContextPtr ctxt, xsltCompMatchPtr comp, ...@@ -311,10 +311,6 @@ xsltCompMatchAdd(xsltParserContextPtr ctxt, xsltCompMatchPtr comp,
"xsltCompMatchAdd: memory re-allocation failure.\n"); "xsltCompMatchAdd: memory re-allocation failure.\n");
if (ctxt->style != NULL) if (ctxt->style != NULL)
ctxt->style->errors++; ctxt->style->errors++;
if (value)
xmlFree(value);
if (value2)
xmlFree(value2);
return (-1); return (-1);
} }
comp->maxStep *= 2; comp->maxStep *= 2;
...@@ -483,16 +479,12 @@ xsltReverseCompMatch(xsltParserContextPtr ctxt, xsltCompMatchPtr comp) { ...@@ -483,16 +479,12 @@ xsltReverseCompMatch(xsltParserContextPtr ctxt, xsltCompMatchPtr comp) {
static int static int
xsltPatPushState(xsltTransformContextPtr ctxt, xsltStepStates *states, xsltPatPushState(xsltTransformContextPtr ctxt, xsltStepStates *states,
int step, xmlNodePtr node) { int step, xmlNodePtr node) {
if ((states->states == NULL) || (states->maxstates <= 0)) { if (states->maxstates <= states->nbstates) {
states->maxstates = 4;
states->nbstates = 0;
states->states = xmlMalloc(4 * sizeof(xsltStepState));
}
else if (states->maxstates <= states->nbstates) {
xsltStepState *tmp; xsltStepState *tmp;
int newMax = states->maxstates == 0 ? 4 : 2 * states->maxstates;
tmp = (xsltStepStatePtr) xmlRealloc(states->states, tmp = (xsltStepStatePtr) xmlRealloc(states->states,
2 * states->maxstates * sizeof(xsltStepState)); newMax * sizeof(xsltStepState));
if (tmp == NULL) { if (tmp == NULL) {
xsltGenericError(xsltGenericErrorContext, xsltGenericError(xsltGenericErrorContext,
"xsltPatPushState: memory re-allocation failure.\n"); "xsltPatPushState: memory re-allocation failure.\n");
...@@ -500,7 +492,7 @@ xsltPatPushState(xsltTransformContextPtr ctxt, xsltStepStates *states, ...@@ -500,7 +492,7 @@ xsltPatPushState(xsltTransformContextPtr ctxt, xsltStepStates *states,
return(-1); return(-1);
} }
states->states = tmp; states->states = tmp;
states->maxstates *= 2; states->maxstates = newMax;
} }
states->states[states->nbstates].step = step; states->states[states->nbstates].step = step;
states->states[states->nbstates++].node = node; states->states[states->nbstates++].node = node;
...@@ -1234,10 +1226,10 @@ xsltScanLiteral(xsltParserContextPtr ctxt) { ...@@ -1234,10 +1226,10 @@ xsltScanLiteral(xsltParserContextPtr ctxt) {
if (CUR == '"') { if (CUR == '"') {
NEXT; NEXT;
cur = q = CUR_PTR; cur = q = CUR_PTR;
val = xmlStringCurrentChar(NULL, cur, &len); val = xsltGetUTF8CharZ(cur, &len);
while ((xmlIsCharQ(val)) && (val != '"')) { while ((xmlIsCharQ(val)) && (val != '"')) {
cur += len; cur += len;
val = xmlStringCurrentChar(NULL, cur, &len); val = xsltGetUTF8CharZ(cur, &len);
} }
if (!xmlIsCharQ(val)) { if (!xmlIsCharQ(val)) {
ctxt->error = 1; ctxt->error = 1;
...@@ -1250,10 +1242,10 @@ xsltScanLiteral(xsltParserContextPtr ctxt) { ...@@ -1250,10 +1242,10 @@ xsltScanLiteral(xsltParserContextPtr ctxt) {
} else if (CUR == '\'') { } else if (CUR == '\'') {
NEXT; NEXT;
cur = q = CUR_PTR; cur = q = CUR_PTR;
val = xmlStringCurrentChar(NULL, cur, &len); val = xsltGetUTF8CharZ(cur, &len);
while ((xmlIsCharQ(val)) && (val != '\'')) { while ((xmlIsCharQ(val)) && (val != '\'')) {
cur += len; cur += len;
val = xmlStringCurrentChar(NULL, cur, &len); val = xsltGetUTF8CharZ(cur, &len);
} }
if (!xmlIsCharQ(val)) { if (!xmlIsCharQ(val)) {
ctxt->error = 1; ctxt->error = 1;
...@@ -1288,7 +1280,7 @@ xsltScanNCName(xsltParserContextPtr ctxt) { ...@@ -1288,7 +1280,7 @@ xsltScanNCName(xsltParserContextPtr ctxt) {
SKIP_BLANKS; SKIP_BLANKS;
cur = q = CUR_PTR; cur = q = CUR_PTR;
val = xmlStringCurrentChar(NULL, cur, &len); val = xsltGetUTF8CharZ(cur, &len);
if (!xmlIsBaseCharQ(val) && !xmlIsIdeographicQ(val) && (val != '_')) if (!xmlIsBaseCharQ(val) && !xmlIsIdeographicQ(val) && (val != '_'))
return(NULL); return(NULL);
...@@ -1299,7 +1291,7 @@ xsltScanNCName(xsltParserContextPtr ctxt) { ...@@ -1299,7 +1291,7 @@ xsltScanNCName(xsltParserContextPtr ctxt) {
xmlIsCombiningQ(val) || xmlIsCombiningQ(val) ||
xmlIsExtenderQ(val)) { xmlIsExtenderQ(val)) {
cur += len; cur += len;
val = xmlStringCurrentChar(NULL, cur, &len); val = xsltGetUTF8CharZ(cur, &len);
} }
ret = xmlStrndup(q, cur - q); ret = xmlStrndup(q, cur - q);
CUR_PTR = cur; CUR_PTR = cur;
...@@ -1512,6 +1504,7 @@ xsltCompileStepPattern(xsltParserContextPtr ctxt, xmlChar *token, int novar) { ...@@ -1512,6 +1504,7 @@ xsltCompileStepPattern(xsltParserContextPtr ctxt, xmlChar *token, int novar) {
xmlChar *name = NULL; xmlChar *name = NULL;
const xmlChar *URI = NULL; const xmlChar *URI = NULL;
xmlChar *URL = NULL; xmlChar *URL = NULL;
xmlChar *ret = NULL;
int level; int level;
xsltAxis axis = 0; xsltAxis axis = 0;
...@@ -1588,7 +1581,6 @@ parse_node_test: ...@@ -1588,7 +1581,6 @@ parse_node_test:
xsltTransformError(NULL, NULL, NULL, xsltTransformError(NULL, NULL, NULL,
"xsltCompileStepPattern : Name expected\n"); "xsltCompileStepPattern : Name expected\n");
ctxt->error = 1; ctxt->error = 1;
xmlFree(URL);
goto error; goto error;
} }
} else { } else {
...@@ -1651,7 +1643,6 @@ parse_predicate: ...@@ -1651,7 +1643,6 @@ parse_predicate:
level = 0; level = 0;
while (CUR == '[') { while (CUR == '[') {
const xmlChar *q; const xmlChar *q;
xmlChar *ret = NULL;
level++; level++;
NEXT; NEXT;
...@@ -1695,6 +1686,10 @@ error: ...@@ -1695,6 +1686,10 @@ error:
xmlFree(token); xmlFree(token);
if (name != NULL) if (name != NULL)
xmlFree(name); xmlFree(name);
if (URL != NULL)
xmlFree(URL);
if (ret != NULL)
xmlFree(ret);
} }
/** /**
...@@ -2087,6 +2082,8 @@ xsltAddTemplate(xsltStylesheetPtr style, xsltTemplatePtr cur, ...@@ -2087,6 +2082,8 @@ xsltAddTemplate(xsltStylesheetPtr style, xsltTemplatePtr cur,
if (pat == NULL) if (pat == NULL)
return(-1); return(-1);
while (pat) { while (pat) {
int success = 0;
next = pat->next; next = pat->next;
pat->next = NULL; pat->next = NULL;
name = NULL; name = NULL;
...@@ -2158,17 +2155,15 @@ xsltAddTemplate(xsltStylesheetPtr style, xsltTemplatePtr cur, ...@@ -2158,17 +2155,15 @@ xsltAddTemplate(xsltStylesheetPtr style, xsltTemplatePtr cur,
if (name != NULL) { if (name != NULL) {
if (style->templatesHash == NULL) { if (style->templatesHash == NULL) {
style->templatesHash = xmlHashCreate(1024); style->templatesHash = xmlHashCreate(1024);
if (style->templatesHash == NULL) { success = (style->templatesHash != NULL) &&
xsltFreeCompMatch(pat); (xmlHashAddEntry3(style->templatesHash, name, mode,
return(-1); modeURI, pat) >= 0);
}
xmlHashAddEntry3(style->templatesHash, name, mode, modeURI, pat);
} else { } else {
list = (xsltCompMatchPtr) xmlHashLookup3(style->templatesHash, list = (xsltCompMatchPtr) xmlHashLookup3(style->templatesHash,
name, mode, modeURI); name, mode, modeURI);
if (list == NULL) { if (list == NULL) {
xmlHashAddEntry3(style->templatesHash, name, success = (xmlHashAddEntry3(style->templatesHash, name,
mode, modeURI, pat); mode, modeURI, pat) >= 0);
} else { } else {
/* /*
* Note '<=' since one must choose among the matching * Note '<=' since one must choose among the matching
...@@ -2188,6 +2183,7 @@ xsltAddTemplate(xsltStylesheetPtr style, xsltTemplatePtr cur, ...@@ -2188,6 +2183,7 @@ xsltAddTemplate(xsltStylesheetPtr style, xsltTemplatePtr cur,
pat->next = list->next; pat->next = list->next;
list->next = pat; list->next = pat;
} }
success = 1;
} }
} }
} else if (top != NULL) { } else if (top != NULL) {
...@@ -2207,10 +2203,13 @@ xsltAddTemplate(xsltStylesheetPtr style, xsltTemplatePtr cur, ...@@ -2207,10 +2203,13 @@ xsltAddTemplate(xsltStylesheetPtr style, xsltTemplatePtr cur,
pat->next = list->next; pat->next = list->next;
list->next = pat; list->next = pat;
} }
} else { success = 1;
}
if (success == 0) {
xsltTransformError(NULL, style, NULL, xsltTransformError(NULL, style, NULL,
"xsltAddTemplate: invalid compiled pattern\n"); "xsltAddTemplate: invalid compiled pattern\n");
xsltFreeCompMatch(pat); xsltFreeCompMatch(pat);
xsltFreeCompMatchList(next);
return(-1); return(-1);
} }
#ifdef WITH_XSLT_DEBUG_PATTERN #ifdef WITH_XSLT_DEBUG_PATTERN
...@@ -2283,7 +2282,6 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, ...@@ -2283,7 +2282,6 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
const xmlChar *name = NULL; const xmlChar *name = NULL;
xsltCompMatchPtr list = NULL; xsltCompMatchPtr list = NULL;
float priority; float priority;
int keyed = 0;
if ((ctxt == NULL) || (node == NULL)) if ((ctxt == NULL) || (node == NULL))
return(NULL); return(NULL);
...@@ -2361,37 +2359,25 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, ...@@ -2361,37 +2359,25 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
list = curstyle->rootMatch; list = curstyle->rootMatch;
else else
list = curstyle->elemMatch; list = curstyle->elemMatch;
if (node->psvi != NULL) keyed = 1;
break; break;
case XML_ATTRIBUTE_NODE: { case XML_ATTRIBUTE_NODE: {
xmlAttrPtr attr;
list = curstyle->attrMatch; list = curstyle->attrMatch;
attr = (xmlAttrPtr) node;
if (attr->psvi != NULL) keyed = 1;
break; break;
} }
case XML_PI_NODE: case XML_PI_NODE:
list = curstyle->piMatch; list = curstyle->piMatch;
if (node->psvi != NULL) keyed = 1;
break; break;
case XML_DOCUMENT_NODE: case XML_DOCUMENT_NODE:
case XML_HTML_DOCUMENT_NODE: { case XML_HTML_DOCUMENT_NODE: {
xmlDocPtr doc;
list = curstyle->rootMatch; list = curstyle->rootMatch;
doc = (xmlDocPtr) node;
if (doc->psvi != NULL) keyed = 1;
break; break;
} }
case XML_TEXT_NODE: case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE: case XML_CDATA_SECTION_NODE:
list = curstyle->textMatch; list = curstyle->textMatch;
if (node->psvi != NULL) keyed = 1;
break; break;
case XML_COMMENT_NODE: case XML_COMMENT_NODE:
list = curstyle->commentMatch; list = curstyle->commentMatch;
if (node->psvi != NULL) keyed = 1;
break; break;
case XML_ENTITY_REF_NODE: case XML_ENTITY_REF_NODE:
case XML_ENTITY_NODE: case XML_ENTITY_NODE:
...@@ -2461,7 +2447,7 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, ...@@ -2461,7 +2447,7 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
} }
keyed_match: keyed_match:
if (keyed) { if (xsltGetSourceNodeFlags(node) & XSLT_SOURCE_NODE_HAS_KEY) {
list = curstyle->keyMatch; list = curstyle->keyMatch;
while ((list != NULL) && while ((list != NULL) &&
((ret == NULL) || ((ret == NULL) ||
...@@ -2489,27 +2475,7 @@ keyed_match: ...@@ -2489,27 +2475,7 @@ keyed_match:
if (xsltComputeAllKeys(ctxt, node) == -1) if (xsltComputeAllKeys(ctxt, node) == -1)
goto error; goto error;
switch (node->type) { if (xsltGetSourceNodeFlags(node) & XSLT_SOURCE_NODE_HAS_KEY)
case XML_ELEMENT_NODE:
if (node->psvi != NULL) keyed = 1;
break;
case XML_ATTRIBUTE_NODE:
if (((xmlAttrPtr) node)->psvi != NULL) keyed = 1;
break;
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_COMMENT_NODE:
case XML_PI_NODE:
if (node->psvi != NULL) keyed = 1;
break;
case XML_DOCUMENT_NODE:
case XML_HTML_DOCUMENT_NODE:
if (((xmlDocPtr) node)->psvi != NULL) keyed = 1;
break;
default:
break;
}
if (keyed)
goto keyed_match; goto keyed_match;
} }
if (ret != NULL) if (ret != NULL)
......
...@@ -392,8 +392,6 @@ xsltFreeStylePreComp(xsltStylePreCompPtr comp) { ...@@ -392,8 +392,6 @@ xsltFreeStylePreComp(xsltStylePreCompPtr comp) {
break; break;
case XSLT_FUNC_SORT: { case XSLT_FUNC_SORT: {
xsltStyleItemSortPtr item = (xsltStyleItemSortPtr) comp; xsltStyleItemSortPtr item = (xsltStyleItemSortPtr) comp;
if (item->locale != (xsltLocale)0)
xsltFreeLocale(item->locale);
if (item->comp != NULL) if (item->comp != NULL)
xmlXPathFreeCompExpr(item->comp); xmlXPathFreeCompExpr(item->comp);
} }
...@@ -496,8 +494,6 @@ xsltFreeStylePreComp(xsltStylePreCompPtr comp) { ...@@ -496,8 +494,6 @@ xsltFreeStylePreComp(xsltStylePreCompPtr comp) {
break; break;
} }
#else #else
if (comp->locale != (xsltLocale)0)
xsltFreeLocale(comp->locale);
if (comp->comp != NULL) if (comp->comp != NULL)
xmlXPathFreeCompExpr(comp->comp); xmlXPathFreeCompExpr(comp->comp);
if (comp->numdata.countPat != NULL) if (comp->numdata.countPat != NULL)
...@@ -743,12 +739,6 @@ xsltSortComp(xsltStylesheetPtr style, xmlNodePtr inst) { ...@@ -743,12 +739,6 @@ xsltSortComp(xsltStylesheetPtr style, xmlNodePtr inst) {
comp->lang = xsltEvalStaticAttrValueTemplate(style, inst, comp->lang = xsltEvalStaticAttrValueTemplate(style, inst,
(const xmlChar *)"lang", (const xmlChar *)"lang",
NULL, &comp->has_lang); NULL, &comp->has_lang);
if (comp->lang != NULL) {
comp->locale = xsltNewLocale(comp->lang);
}
else {
comp->locale = (xsltLocale)0;
}
comp->select = xsltGetCNsProp(style, inst,(const xmlChar *)"select", XSLT_NAMESPACE); comp->select = xsltGetCNsProp(style, inst,(const xmlChar *)"select", XSLT_NAMESPACE);
if (comp->select == NULL) { if (comp->select == NULL) {
......
...@@ -151,7 +151,7 @@ xsltEvalXPathStringNs(xsltTransformContextPtr ctxt, xmlXPathCompExprPtr comp, ...@@ -151,7 +151,7 @@ xsltEvalXPathStringNs(xsltTransformContextPtr ctxt, xmlXPathCompExprPtr comp,
if (res != NULL) { if (res != NULL) {
if (res->type != XPATH_STRING) if (res->type != XPATH_STRING)
res = xmlXPathConvertString(res); res = xmlXPathConvertString(res);
if (res->type == XPATH_STRING) { if ((res != NULL) && (res->type == XPATH_STRING)) {
ret = res->stringval; ret = res->stringval;
res->stringval = NULL; res->stringval = NULL;
} else { } else {
...@@ -229,7 +229,7 @@ xsltEvalTemplateString(xsltTransformContextPtr ctxt, ...@@ -229,7 +229,7 @@ xsltEvalTemplateString(xsltTransformContextPtr ctxt,
insert = xmlNewDocNode(ctxt->output, NULL, insert = xmlNewDocNode(ctxt->output, NULL,
(const xmlChar *)"fake", NULL); (const xmlChar *)"fake", NULL);
if (insert == NULL) { if (insert == NULL) {
xsltTransformError(ctxt, NULL, contextNode, xsltTransformError(ctxt, NULL, inst,
"Failed to create temporary node\n"); "Failed to create temporary node\n");
return(NULL); return(NULL);
} }
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include "xslt.h" #include "xslt.h"
#include "xsltInternals.h" #include "xsltInternals.h"
#include "xsltutils.h" #include "xsltutils.h"
#include "xsltlocale.h"
#include "pattern.h" #include "pattern.h"
#include "transform.h" #include "transform.h"
#include "variables.h" #include "variables.h"
...@@ -119,26 +120,18 @@ xsltApplyXSLTTemplate(xsltTransformContextPtr ctxt, ...@@ -119,26 +120,18 @@ xsltApplyXSLTTemplate(xsltTransformContextPtr ctxt,
static int static int
templPush(xsltTransformContextPtr ctxt, xsltTemplatePtr value) templPush(xsltTransformContextPtr ctxt, xsltTemplatePtr value)
{ {
if (ctxt->templMax == 0) { if (ctxt->templNr >= ctxt->templMax) {
ctxt->templMax = 4; xsltTemplatePtr *tmp;
ctxt->templTab = int newMax = ctxt->templMax == 0 ? 4 : ctxt->templMax * 2;
(xsltTemplatePtr *) xmlMalloc(ctxt->templMax *
sizeof(ctxt->templTab[0])); tmp = (xsltTemplatePtr *) xmlRealloc(ctxt->templTab,
if (ctxt->templTab == NULL) { newMax * sizeof(*tmp));
xmlGenericError(xmlGenericErrorContext, "malloc failed !\n"); if (tmp == NULL) {
return (0);
}
}
else if (ctxt->templNr >= ctxt->templMax) {
ctxt->templMax *= 2;
ctxt->templTab =
(xsltTemplatePtr *) xmlRealloc(ctxt->templTab,
ctxt->templMax *
sizeof(ctxt->templTab[0]));
if (ctxt->templTab == NULL) {
xmlGenericError(xmlGenericErrorContext, "realloc failed !\n"); xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");
return (0); return (0);
} }
ctxt->templTab = tmp;
ctxt->templMax = newMax;
} }
ctxt->templTab[ctxt->templNr] = value; ctxt->templTab[ctxt->templNr] = value;
ctxt->templ = value; ctxt->templ = value;
...@@ -492,7 +485,7 @@ void xsltDebugSetDefaultTrace(xsltDebugTraceCodes val) { ...@@ -492,7 +485,7 @@ void xsltDebugSetDefaultTrace(xsltDebugTraceCodes val) {
* *
* Returns the current default debug tracing level mask * Returns the current default debug tracing level mask
*/ */
xsltDebugTraceCodes xsltDebugGetDefaultTrace() { xsltDebugTraceCodes xsltDebugGetDefaultTrace(void) {
return xsltDefaultTrace; return xsltDefaultTrace;
} }
...@@ -706,6 +699,10 @@ xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc) { ...@@ -706,6 +699,10 @@ xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc) {
cur->xinclude = xsltGetXIncludeDefault(); cur->xinclude = xsltGetXIncludeDefault();
cur->keyInitLevel = 0; cur->keyInitLevel = 0;
cur->newLocale = xsltNewLocale;
cur->freeLocale = xsltFreeLocale;
cur->genSortKey = xsltStrxfrm;
return(cur); return(cur);
internal_err: internal_err:
...@@ -716,7 +713,7 @@ internal_err: ...@@ -716,7 +713,7 @@ internal_err:
/** /**
* xsltFreeTransformContext: * xsltFreeTransformContext:
* @ctxt: an XSLT parser context * @ctxt: an XSLT transform context
* *
* Free up the memory allocated by @ctxt * Free up the memory allocated by @ctxt
*/ */
...@@ -1090,8 +1087,10 @@ xsltCopyText(xsltTransformContextPtr ctxt, xmlNodePtr target, ...@@ -1090,8 +1087,10 @@ xsltCopyText(xsltTransformContextPtr ctxt, xmlNodePtr target,
if (xmlDictOwns(ctxt->dict, cur->content)) if (xmlDictOwns(ctxt->dict, cur->content))
copy->content = cur->content; copy->content = cur->content;
else { else {
if ((copy->content = xmlStrdup(cur->content)) == NULL) if ((copy->content = xmlStrdup(cur->content)) == NULL) {
xmlFreeNode(copy);
return NULL; return NULL;
}
} }
ctxt->lasttext = NULL; ctxt->lasttext = NULL;
...@@ -2224,26 +2223,18 @@ xsltLocalVariablePush(xsltTransformContextPtr ctxt, ...@@ -2224,26 +2223,18 @@ xsltLocalVariablePush(xsltTransformContextPtr ctxt,
xsltStackElemPtr variable, xsltStackElemPtr variable,
int level) int level)
{ {
if (ctxt->varsMax == 0) {
ctxt->varsMax = 10;
ctxt->varsTab =
(xsltStackElemPtr *) xmlMalloc(ctxt->varsMax *
sizeof(ctxt->varsTab[0]));
if (ctxt->varsTab == NULL) {
xmlGenericError(xmlGenericErrorContext, "malloc failed !\n");
return (-1);
}
}
if (ctxt->varsNr >= ctxt->varsMax) { if (ctxt->varsNr >= ctxt->varsMax) {
ctxt->varsMax *= 2; xsltStackElemPtr *tmp;
ctxt->varsTab = int newMax = ctxt->varsMax == 0 ? 10 : 2 * ctxt->varsMax;
(xsltStackElemPtr *) xmlRealloc(ctxt->varsTab,
ctxt->varsMax * tmp = (xsltStackElemPtr *) xmlRealloc(ctxt->varsTab,
sizeof(ctxt->varsTab[0])); newMax * sizeof(*tmp));
if (ctxt->varsTab == NULL) { if (tmp == NULL) {
xmlGenericError(xmlGenericErrorContext, "realloc failed !\n"); xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");
return (-1); return (-1);
} }
ctxt->varsTab = tmp;
ctxt->varsMax = newMax;
} }
ctxt->varsTab[ctxt->varsNr++] = variable; ctxt->varsTab[ctxt->varsNr++] = variable;
ctxt->vars = variable; ctxt->vars = variable;
...@@ -2275,17 +2266,17 @@ xsltReleaseLocalRVTs(xsltTransformContextPtr ctxt, xmlDocPtr base) ...@@ -2275,17 +2266,17 @@ xsltReleaseLocalRVTs(xsltTransformContextPtr ctxt, xmlDocPtr base)
do { do {
tmp = cur; tmp = cur;
cur = (xmlDocPtr) cur->next; cur = (xmlDocPtr) cur->next;
if (tmp->psvi == XSLT_RVT_LOCAL) { if (tmp->compression == XSLT_RVT_LOCAL) {
xsltReleaseRVT(ctxt, tmp); xsltReleaseRVT(ctxt, tmp);
} else if (tmp->psvi == XSLT_RVT_GLOBAL) { } else if (tmp->compression == XSLT_RVT_GLOBAL) {
xsltRegisterPersistRVT(ctxt, tmp); xsltRegisterPersistRVT(ctxt, tmp);
} else if (tmp->psvi == XSLT_RVT_FUNC_RESULT) { } else if (tmp->compression == XSLT_RVT_FUNC_RESULT) {
/* /*
* This will either register the RVT again or move it to the * This will either register the RVT again or move it to the
* context variable. * context variable.
*/ */
xsltRegisterLocalRVT(ctxt, tmp); xsltRegisterLocalRVT(ctxt, tmp);
tmp->psvi = XSLT_RVT_FUNC_RESULT; tmp->compression = XSLT_RVT_FUNC_RESULT;
} else { } else {
xmlGenericError(xmlGenericErrorContext, xmlGenericError(xmlGenericErrorContext,
"xsltReleaseLocalRVTs: Unexpected RVT flag %p\n", "xsltReleaseLocalRVTs: Unexpected RVT flag %p\n",
...@@ -5747,6 +5738,49 @@ xsltCountKeys(xsltTransformContextPtr ctxt) ...@@ -5747,6 +5738,49 @@ xsltCountKeys(xsltTransformContextPtr ctxt)
} }
/** /**
* xsltCleanupSourceDoc:
* @doc: Document
*
* Resets source node flags and ids stored in 'psvi' member.
*/
static void
xsltCleanupSourceDoc(xmlDocPtr doc) {
xmlNodePtr cur = (xmlNodePtr) doc;
void **psviPtr;
while (1) {
xsltClearSourceNodeFlags(cur, XSLT_SOURCE_NODE_MASK);
psviPtr = xsltGetPSVIPtr(cur);
if (psviPtr)
*psviPtr = NULL;
if (cur->type == XML_ELEMENT_NODE) {
xmlAttrPtr prop = cur->properties;
while (prop) {
prop->atype &= ~(XSLT_SOURCE_NODE_MASK << 27);
prop->psvi = NULL;
prop = prop->next;
}
}
if (cur->children != NULL && cur->type != XML_ENTITY_REF_NODE) {
cur = cur->children;
} else {
if (cur == (xmlNodePtr) doc)
return;
while (cur->next == NULL) {
cur = cur->parent;
if (cur == (xmlNodePtr) doc)
return;
}
cur = cur->next;
}
}
}
/**
* xsltApplyStylesheetInternal: * xsltApplyStylesheetInternal:
* @style: a parsed XSLT stylesheet * @style: a parsed XSLT stylesheet
* @doc: a parsed XML document * @doc: a parsed XML document
...@@ -6144,6 +6178,9 @@ xsltApplyStylesheetInternal(xsltStylesheetPtr style, xmlDocPtr doc, ...@@ -6144,6 +6178,9 @@ xsltApplyStylesheetInternal(xsltStylesheetPtr style, xmlDocPtr doc,
printf("# Reused variables : %d\n", ctxt->cache->dbgReusedVars); printf("# Reused variables : %d\n", ctxt->cache->dbgReusedVars);
#endif #endif
if (ctxt->sourceDocDirty)
xsltCleanupSourceDoc(doc);
if ((ctxt != NULL) && (userCtxt == NULL)) if ((ctxt != NULL) && (userCtxt == NULL))
xsltFreeTransformContext(ctxt); xsltFreeTransformContext(ctxt);
......
...@@ -123,7 +123,7 @@ xsltRegisterTmpRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT) ...@@ -123,7 +123,7 @@ xsltRegisterTmpRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT)
return(-1); return(-1);
RVT->prev = NULL; RVT->prev = NULL;
RVT->psvi = XSLT_RVT_LOCAL; RVT->compression = XSLT_RVT_LOCAL;
/* /*
* We'll restrict the lifetime of user-created fragments * We'll restrict the lifetime of user-created fragments
...@@ -163,7 +163,7 @@ xsltRegisterLocalRVT(xsltTransformContextPtr ctxt, ...@@ -163,7 +163,7 @@ xsltRegisterLocalRVT(xsltTransformContextPtr ctxt,
return(-1); return(-1);
RVT->prev = NULL; RVT->prev = NULL;
RVT->psvi = XSLT_RVT_LOCAL; RVT->compression = XSLT_RVT_LOCAL;
/* /*
* When evaluating "select" expressions of xsl:variable * When evaluating "select" expressions of xsl:variable
...@@ -255,7 +255,7 @@ xsltExtensionInstructionResultRegister( ...@@ -255,7 +255,7 @@ xsltExtensionInstructionResultRegister(
* Returns 0 in case of success and -1 in case of error. * Returns 0 in case of success and -1 in case of error.
*/ */
int int
xsltFlagRVTs(xsltTransformContextPtr ctxt, xmlXPathObjectPtr obj, void *val) { xsltFlagRVTs(xsltTransformContextPtr ctxt, xmlXPathObjectPtr obj, int val) {
int i; int i;
xmlNodePtr cur; xmlNodePtr cur;
xmlDocPtr doc; xmlDocPtr doc;
...@@ -302,34 +302,36 @@ xsltFlagRVTs(xsltTransformContextPtr ctxt, xmlXPathObjectPtr obj, void *val) { ...@@ -302,34 +302,36 @@ xsltFlagRVTs(xsltTransformContextPtr ctxt, xmlXPathObjectPtr obj, void *val) {
return(-1); return(-1);
} }
if (doc->name && (doc->name[0] == ' ') && if (doc->name && (doc->name[0] == ' ') &&
doc->psvi != XSLT_RVT_GLOBAL) { doc->compression != XSLT_RVT_GLOBAL) {
/* /*
* This is a result tree fragment. * This is a result tree fragment.
* We store ownership information in the @psvi field. * We store ownership information in the @compression field.
* TODO: How do we know if this is a doc acquired via the * TODO: How do we know if this is a doc acquired via the
* document() function? * document() function?
*/ */
#ifdef WITH_XSLT_DEBUG_VARIABLE #ifdef WITH_XSLT_DEBUG_VARIABLE
XSLT_TRACE(ctxt,XSLT_TRACE_VARIABLES,xsltGenericDebug(xsltGenericDebugContext, XSLT_TRACE(ctxt, XSLT_TRACE_VARIABLES,
"Flagging RVT %p: %p -> %p\n", doc, doc->psvi, val)); xsltGenericDebug(xsltGenericDebugContext,
"Flagging RVT %p: %d -> %d\n",
(void *) doc, doc->compression, val));
#endif #endif
if (val == XSLT_RVT_LOCAL) { if (val == XSLT_RVT_LOCAL) {
if (doc->psvi == XSLT_RVT_FUNC_RESULT) if (doc->compression == XSLT_RVT_FUNC_RESULT)
doc->psvi = XSLT_RVT_LOCAL; doc->compression = XSLT_RVT_LOCAL;
} else if (val == XSLT_RVT_GLOBAL) { } else if (val == XSLT_RVT_GLOBAL) {
if (doc->psvi != XSLT_RVT_LOCAL) { if (doc->compression != XSLT_RVT_LOCAL) {
xmlGenericError(xmlGenericErrorContext, xmlGenericError(xmlGenericErrorContext,
"xsltFlagRVTs: Invalid transition %p => GLOBAL\n", "xsltFlagRVTs: Invalid transition %d => GLOBAL\n",
doc->psvi); doc->compression);
doc->psvi = XSLT_RVT_GLOBAL; doc->compression = XSLT_RVT_GLOBAL;
return(-1); return(-1);
} }
/* Will be registered as persistant in xsltReleaseLocalRVTs. */ /* Will be registered as persistant in xsltReleaseLocalRVTs. */
doc->psvi = XSLT_RVT_GLOBAL; doc->compression = XSLT_RVT_GLOBAL;
} else if (val == XSLT_RVT_FUNC_RESULT) { } else if (val == XSLT_RVT_FUNC_RESULT) {
doc->psvi = val; doc->compression = val;
} }
} }
} }
...@@ -377,7 +379,7 @@ xsltReleaseRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT) ...@@ -377,7 +379,7 @@ xsltReleaseRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT)
/* /*
* Reset the ownership information. * Reset the ownership information.
*/ */
RVT->psvi = NULL; RVT->compression = 0;
RVT->next = (xmlNodePtr) ctxt->cache->RVT; RVT->next = (xmlNodePtr) ctxt->cache->RVT;
ctxt->cache->RVT = RVT; ctxt->cache->RVT = RVT;
...@@ -416,7 +418,7 @@ xsltRegisterPersistRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT) ...@@ -416,7 +418,7 @@ xsltRegisterPersistRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT)
{ {
if ((ctxt == NULL) || (RVT == NULL)) return(-1); if ((ctxt == NULL) || (RVT == NULL)) return(-1);
RVT->psvi = XSLT_RVT_GLOBAL; RVT->compression = XSLT_RVT_GLOBAL;
RVT->prev = NULL; RVT->prev = NULL;
RVT->next = (xmlNodePtr) ctxt->persistRVT; RVT->next = (xmlNodePtr) ctxt->persistRVT;
if (ctxt->persistRVT != NULL) if (ctxt->persistRVT != NULL)
...@@ -575,15 +577,15 @@ xsltFreeStackElem(xsltStackElemPtr elem) { ...@@ -575,15 +577,15 @@ xsltFreeStackElem(xsltStackElemPtr elem) {
cur = elem->fragment; cur = elem->fragment;
elem->fragment = (xmlDocPtr) cur->next; elem->fragment = (xmlDocPtr) cur->next;
if (cur->psvi == XSLT_RVT_LOCAL) { if (cur->compression == XSLT_RVT_LOCAL) {
xsltReleaseRVT(elem->context, cur); xsltReleaseRVT(elem->context, cur);
} else if (cur->psvi == XSLT_RVT_FUNC_RESULT) { } else if (cur->compression == XSLT_RVT_FUNC_RESULT) {
xsltRegisterLocalRVT(elem->context, cur); xsltRegisterLocalRVT(elem->context, cur);
cur->psvi = XSLT_RVT_FUNC_RESULT; cur->compression = XSLT_RVT_FUNC_RESULT;
} else { } else {
xmlGenericError(xmlGenericErrorContext, xmlGenericError(xmlGenericErrorContext,
"xsltFreeStackElem: Unexpected RVT flag %p\n", "xsltFreeStackElem: Unexpected RVT flag %d\n",
cur->psvi); cur->compression);
} }
} }
} }
...@@ -755,26 +757,18 @@ xsltAddStackElem(xsltTransformContextPtr ctxt, xsltStackElemPtr elem) ...@@ -755,26 +757,18 @@ xsltAddStackElem(xsltTransformContextPtr ctxt, xsltStackElemPtr elem)
return(-1); return(-1);
do { do {
if (ctxt->varsMax == 0) {
ctxt->varsMax = 10;
ctxt->varsTab =
(xsltStackElemPtr *) xmlMalloc(ctxt->varsMax *
sizeof(ctxt->varsTab[0]));
if (ctxt->varsTab == NULL) {
xmlGenericError(xmlGenericErrorContext, "malloc failed !\n");
return (-1);
}
}
if (ctxt->varsNr >= ctxt->varsMax) { if (ctxt->varsNr >= ctxt->varsMax) {
ctxt->varsMax *= 2; xsltStackElemPtr *tmp;
ctxt->varsTab = int newMax = ctxt->varsMax == 0 ? 10 : 2 * ctxt->varsMax;
(xsltStackElemPtr *) xmlRealloc(ctxt->varsTab,
ctxt->varsMax * tmp = (xsltStackElemPtr *) xmlRealloc(ctxt->varsTab,
sizeof(ctxt->varsTab[0])); newMax * sizeof(*tmp));
if (ctxt->varsTab == NULL) { if (tmp == NULL) {
xmlGenericError(xmlGenericErrorContext, "realloc failed !\n"); xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");
return (-1); return (-1);
} }
ctxt->varsTab = tmp;
ctxt->varsMax = newMax;
} }
ctxt->varsTab[ctxt->varsNr++] = elem; ctxt->varsTab[ctxt->varsNr++] = elem;
ctxt->vars = elem; ctxt->vars = elem;
...@@ -986,7 +980,7 @@ xsltEvalVariable(xsltTransformContextPtr ctxt, xsltStackElemPtr variable, ...@@ -986,7 +980,7 @@ xsltEvalVariable(xsltTransformContextPtr ctxt, xsltStackElemPtr variable,
* the Result Tree Fragment. * the Result Tree Fragment.
*/ */
variable->fragment = container; variable->fragment = container;
container->psvi = XSLT_RVT_LOCAL; container->compression = XSLT_RVT_LOCAL;
oldOutput = ctxt->output; oldOutput = ctxt->output;
oldInsert = ctxt->insert; oldInsert = ctxt->insert;
...@@ -1316,8 +1310,13 @@ xsltEvalGlobalVariables(xsltTransformContextPtr ctxt) { ...@@ -1316,8 +1310,13 @@ xsltEvalGlobalVariables(xsltTransformContextPtr ctxt) {
if (def == NULL) { if (def == NULL) {
def = xsltCopyStackElem(elem); def = xsltCopyStackElem(elem);
xmlHashAddEntry2(ctxt->globalVars, if (xmlHashAddEntry2(ctxt->globalVars,
elem->name, elem->nameURI, def); elem->name, elem->nameURI, def) < 0) {
xmlGenericError(xmlGenericErrorContext,
"hash update failed\n");
xsltFreeStackElem(def);
return(-1);
}
} else if ((elem->comp != NULL) && } else if ((elem->comp != NULL) &&
(elem->comp->type == XSLT_FUNC_VARIABLE)) { (elem->comp->type == XSLT_FUNC_VARIABLE)) {
/* /*
...@@ -1681,7 +1680,7 @@ xsltProcessUserParamInternal(xsltTransformContextPtr ctxt, ...@@ -1681,7 +1680,7 @@ xsltProcessUserParamInternal(xsltTransformContextPtr ctxt,
int int
xsltEvalUserParams(xsltTransformContextPtr ctxt, const char **params) { xsltEvalUserParams(xsltTransformContextPtr ctxt, const char **params) {
int indx = 0; size_t indx = 0;
const xmlChar *name; const xmlChar *name;
const xmlChar *value; const xmlChar *value;
...@@ -1711,7 +1710,7 @@ xsltEvalUserParams(xsltTransformContextPtr ctxt, const char **params) { ...@@ -1711,7 +1710,7 @@ xsltEvalUserParams(xsltTransformContextPtr ctxt, const char **params) {
int int
xsltQuoteUserParams(xsltTransformContextPtr ctxt, const char **params) { xsltQuoteUserParams(xsltTransformContextPtr ctxt, const char **params) {
int indx = 0; size_t indx = 0;
const xmlChar *name; const xmlChar *name;
const xmlChar *value; const xmlChar *value;
...@@ -1875,7 +1874,10 @@ xsltRegisterVariable(xsltTransformContextPtr ctxt, ...@@ -1875,7 +1874,10 @@ xsltRegisterVariable(xsltTransformContextPtr ctxt,
#endif /* else of XSLT_REFACTORED */ #endif /* else of XSLT_REFACTORED */
variable = xsltBuildVariable(ctxt, (xsltStylePreCompPtr) comp, tree); variable = xsltBuildVariable(ctxt, (xsltStylePreCompPtr) comp, tree);
xsltAddStackElem(ctxt, variable); if (xsltAddStackElem(ctxt, variable) < 0) {
xsltFreeStackElem(variable);
return(-1);
}
return(0); return(0);
} }
......
...@@ -43,7 +43,7 @@ extern "C" { ...@@ -43,7 +43,7 @@ extern "C" {
* *
* RVT is destroyed after the current instructions ends. * RVT is destroyed after the current instructions ends.
*/ */
#define XSLT_RVT_LOCAL ((void *)1) #define XSLT_RVT_LOCAL 1
/** /**
* XSLT_RVT_FUNC_RESULT: * XSLT_RVT_FUNC_RESULT:
...@@ -52,14 +52,14 @@ extern "C" { ...@@ -52,14 +52,14 @@ extern "C" {
* destroyed after exiting a template and will be reset to XSLT_RVT_LOCAL or * destroyed after exiting a template and will be reset to XSLT_RVT_LOCAL or
* XSLT_RVT_VARIABLE in the template that receives the return value. * XSLT_RVT_VARIABLE in the template that receives the return value.
*/ */
#define XSLT_RVT_FUNC_RESULT ((void *)2) #define XSLT_RVT_FUNC_RESULT 2
/** /**
* XSLT_RVT_GLOBAL: * XSLT_RVT_GLOBAL:
* *
* RVT is part of a global variable. * RVT is part of a global variable.
*/ */
#define XSLT_RVT_GLOBAL ((void *)3) #define XSLT_RVT_GLOBAL 3
/* /*
* Interfaces for the variable module. * Interfaces for the variable module.
......
...@@ -91,13 +91,7 @@ const xmlChar *xsltXSLTAttrMarker = (const xmlChar *) "LRE XSLT Attr"; ...@@ -91,13 +91,7 @@ const xmlChar *xsltXSLTAttrMarker = (const xmlChar *) "LRE XSLT Attr";
#ifdef XSLT_LOCALE_WINAPI #ifdef XSLT_LOCALE_WINAPI
extern xmlRMutexPtr xsltLocaleMutex; extern xmlRMutexPtr xsltLocaleMutex;
#endif #endif
/*
* Harmless but avoiding a problem when compiling against a
* libxml <= 2.3.11 without LIBXML_DEBUG_ENABLED
*/
#ifndef LIBXML_DEBUG_ENABLED
double xmlXPathStringEvalNumber(const xmlChar *str);
#endif
/* /*
* Useful macros * Useful macros
*/ */
...@@ -157,31 +151,23 @@ exclPrefixPush(xsltStylesheetPtr style, xmlChar * value) ...@@ -157,31 +151,23 @@ exclPrefixPush(xsltStylesheetPtr style, xmlChar * value)
{ {
int i; int i;
if (style->exclPrefixMax == 0) {
style->exclPrefixMax = 4;
style->exclPrefixTab =
(xmlChar * *)xmlMalloc(style->exclPrefixMax *
sizeof(style->exclPrefixTab[0]));
if (style->exclPrefixTab == NULL) {
xmlGenericError(xmlGenericErrorContext, "malloc failed !\n");
return (-1);
}
}
/* do not push duplicates */ /* do not push duplicates */
for (i = 0;i < style->exclPrefixNr;i++) { for (i = 0;i < style->exclPrefixNr;i++) {
if (xmlStrEqual(style->exclPrefixTab[i], value)) if (xmlStrEqual(style->exclPrefixTab[i], value))
return(-1); return(-1);
} }
if (style->exclPrefixNr >= style->exclPrefixMax) { if (style->exclPrefixNr >= style->exclPrefixMax) {
style->exclPrefixMax *= 2; xmlChar **tmp;
style->exclPrefixTab = size_t max = style->exclPrefixMax ? style->exclPrefixMax * 2 : 4;
(xmlChar * *)xmlRealloc(style->exclPrefixTab,
style->exclPrefixMax * tmp = xmlRealloc(style->exclPrefixTab,
sizeof(style->exclPrefixTab[0])); max * sizeof(style->exclPrefixTab[0]));
if (style->exclPrefixTab == NULL) { if (tmp == NULL) {
xmlGenericError(xmlGenericErrorContext, "realloc failed !\n"); xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");
return (-1); return (-1);
} }
style->exclPrefixTab = tmp;
style->exclPrefixMax = max;
} }
style->exclPrefixTab[style->exclPrefixNr] = value; style->exclPrefixTab[style->exclPrefixNr] = value;
style->exclPrefix = value; style->exclPrefix = value;
...@@ -1117,9 +1103,9 @@ xsltGetInheritedNsList(xsltStylesheetPtr style, ...@@ -1117,9 +1103,9 @@ xsltGetInheritedNsList(xsltStylesheetPtr style,
xmlNodePtr node) xmlNodePtr node)
{ {
xmlNsPtr cur; xmlNsPtr cur;
xmlNsPtr *ret = NULL; xmlNsPtr *ret = NULL, *tmp;
int nbns = 0; int nbns = 0;
int maxns = 10; int maxns = 0;
int i; int i;
if ((style == NULL) || (template == NULL) || (node == NULL) || if ((style == NULL) || (template == NULL) || (node == NULL) ||
...@@ -1144,17 +1130,6 @@ xsltGetInheritedNsList(xsltStylesheetPtr style, ...@@ -1144,17 +1130,6 @@ xsltGetInheritedNsList(xsltStylesheetPtr style,
if (xmlStrEqual(cur->href, style->exclPrefixTab[i])) if (xmlStrEqual(cur->href, style->exclPrefixTab[i]))
goto skip_ns; goto skip_ns;
} }
if (ret == NULL) {
ret =
(xmlNsPtr *) xmlMalloc((maxns + 1) *
sizeof(xmlNsPtr));
if (ret == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xsltGetInheritedNsList : out of memory!\n");
return(0);
}
ret[nbns] = NULL;
}
/* /*
* Skip shadowed namespace bindings. * Skip shadowed namespace bindings.
*/ */
...@@ -1165,16 +1140,16 @@ xsltGetInheritedNsList(xsltStylesheetPtr style, ...@@ -1165,16 +1140,16 @@ xsltGetInheritedNsList(xsltStylesheetPtr style,
} }
if (i >= nbns) { if (i >= nbns) {
if (nbns >= maxns) { if (nbns >= maxns) {
maxns *= 2; maxns = (maxns == 0) ? 10 : 2 * maxns;
ret = (xmlNsPtr *) xmlRealloc(ret, tmp = (xmlNsPtr *) xmlRealloc(ret,
(maxns + (maxns + 1) * sizeof(xmlNsPtr));
1) * if (tmp == NULL) {
sizeof(xmlNsPtr));
if (ret == NULL) {
xmlGenericError(xmlGenericErrorContext, xmlGenericError(xmlGenericErrorContext,
"xsltGetInheritedNsList : realloc failed!\n"); "xsltGetInheritedNsList : realloc failed!\n");
xmlFree(ret);
return(0); return(0);
} }
ret = tmp;
} }
ret[nbns++] = cur; ret[nbns++] = cur;
ret[nbns] = NULL; ret[nbns] = NULL;
...@@ -1330,8 +1305,10 @@ xsltParseStylesheetOutput(xsltStylesheetPtr style, xmlNodePtr cur) ...@@ -1330,8 +1305,10 @@ xsltParseStylesheetOutput(xsltStylesheetPtr style, xmlNodePtr cur)
if (elements != NULL) { if (elements != NULL) {
if (style->cdataSection == NULL) if (style->cdataSection == NULL)
style->cdataSection = xmlHashCreate(10); style->cdataSection = xmlHashCreate(10);
if (style->cdataSection == NULL) if (style->cdataSection == NULL) {
xmlFree(elements);
return; return;
}
element = elements; element = elements;
while (*element != 0) { while (*element != 0) {
...@@ -1569,8 +1546,10 @@ xsltParseStylesheetPreserveSpace(xsltStylesheetPtr style, xmlNodePtr cur) { ...@@ -1569,8 +1546,10 @@ xsltParseStylesheetPreserveSpace(xsltStylesheetPtr style, xmlNodePtr cur) {
if (style->stripSpaces == NULL) if (style->stripSpaces == NULL)
style->stripSpaces = xmlHashCreate(10); style->stripSpaces = xmlHashCreate(10);
if (style->stripSpaces == NULL) if (style->stripSpaces == NULL) {
xmlFree(elements);
return; return;
}
element = elements; element = elements;
while (*element != 0) { while (*element != 0) {
...@@ -1698,6 +1677,11 @@ xsltParseStylesheetStripSpace(xsltStylesheetPtr style, xmlNodePtr cur) { ...@@ -1698,6 +1677,11 @@ xsltParseStylesheetStripSpace(xsltStylesheetPtr style, xmlNodePtr cur) {
if ((cur == NULL) || (style == NULL) || (cur->type != XML_ELEMENT_NODE)) if ((cur == NULL) || (style == NULL) || (cur->type != XML_ELEMENT_NODE))
return; return;
if (style->stripSpaces == NULL)
style->stripSpaces = xmlHashCreate(10);
if (style->stripSpaces == NULL)
return;
elements = xmlGetNsProp(cur, (const xmlChar *)"elements", NULL); elements = xmlGetNsProp(cur, (const xmlChar *)"elements", NULL);
if (elements == NULL) { if (elements == NULL) {
xsltTransformError(NULL, style, cur, xsltTransformError(NULL, style, cur,
...@@ -1706,11 +1690,6 @@ xsltParseStylesheetStripSpace(xsltStylesheetPtr style, xmlNodePtr cur) { ...@@ -1706,11 +1690,6 @@ xsltParseStylesheetStripSpace(xsltStylesheetPtr style, xmlNodePtr cur) {
return; return;
} }
if (style->stripSpaces == NULL)
style->stripSpaces = xmlHashCreate(10);
if (style->stripSpaces == NULL)
return;
element = elements; element = elements;
while (*element != 0) { while (*element != 0) {
while (IS_BLANK(*element)) element++; while (IS_BLANK(*element)) element++;
...@@ -5526,9 +5505,6 @@ xsltCompileXSLTIncludeElem(xsltCompilerCtxtPtr cctxt, xmlNodePtr node) { ...@@ -5526,9 +5505,6 @@ xsltCompileXSLTIncludeElem(xsltCompilerCtxtPtr cctxt, xmlNodePtr node) {
return(item); return(item);
} }
/**
* xsltParseFindTopLevelElem:
*/
static int static int
xsltParseFindTopLevelElem(xsltCompilerCtxtPtr cctxt, xsltParseFindTopLevelElem(xsltCompilerCtxtPtr cctxt,
xmlNodePtr cur, xmlNodePtr cur,
...@@ -6687,6 +6663,9 @@ xsltParseStylesheetUser(xsltStylesheetPtr style, xmlDocPtr doc) { ...@@ -6687,6 +6663,9 @@ xsltParseStylesheetUser(xsltStylesheetPtr style, xmlDocPtr doc) {
} }
#endif /* else of XSLT_REFACTORED */ #endif /* else of XSLT_REFACTORED */
if (style->parent == NULL)
xsltResolveStylesheetAttributeSet(style);
if (style->errors != 0) { if (style->errors != 0) {
/* /*
* Detach the doc from the stylesheet; otherwise the doc * Detach the doc from the stylesheet; otherwise the doc
...@@ -6701,15 +6680,12 @@ xsltParseStylesheetUser(xsltStylesheetPtr style, xmlDocPtr doc) { ...@@ -6701,15 +6680,12 @@ xsltParseStylesheetUser(xsltStylesheetPtr style, xmlDocPtr doc) {
return(-1); return(-1);
} }
if (style->parent == NULL)
xsltResolveStylesheetAttributeSet(style);
return(0); return(0);
} }
/** /**
* xsltParseStylesheetDoc: * xsltParseStylesheetDoc:
* @doc: and xmlDoc parsed XML * @doc: an xmlDoc parsed XML
* *
* parse an XSLT stylesheet, building the associated structures. doc * parse an XSLT stylesheet, building the associated structures. doc
* is kept as a reference within the returned stylesheet, so changes * is kept as a reference within the returned stylesheet, so changes
...@@ -6844,7 +6820,8 @@ xsltParseStylesheetPI(const xmlChar *value) { ...@@ -6844,7 +6820,8 @@ xsltParseStylesheetPI(const xmlChar *value) {
if (val == NULL) if (val == NULL)
return(NULL); return(NULL);
if ((xmlStrcasecmp(val, BAD_CAST "text/xml")) && if ((xmlStrcasecmp(val, BAD_CAST "text/xml")) &&
(xmlStrcasecmp(val, BAD_CAST "text/xsl"))) { (xmlStrcasecmp(val, BAD_CAST "text/xsl")) &&
(xmlStrcasecmp(val, BAD_CAST "application/xslt+xml"))) {
xmlFree(val); xmlFree(val);
break; break;
} }
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#include <libxml/xmlstring.h> #include <libxml/xmlstring.h>
#include <libxslt/xslt.h> #include <libxslt/xslt.h>
#include "xsltexports.h" #include "xsltexports.h"
#include "xsltlocale.h"
#include "numbersInternals.h" #include "numbersInternals.h"
#ifdef __cplusplus #ifdef __cplusplus
...@@ -1047,7 +1046,6 @@ struct _xsltStyleItemSort { ...@@ -1047,7 +1046,6 @@ struct _xsltStyleItemSort {
int descending; /* sort */ int descending; /* sort */
const xmlChar *lang; /* sort */ const xmlChar *lang; /* sort */
int has_lang; /* sort */ int has_lang; /* sort */
xsltLocale locale; /* sort */
const xmlChar *case_order; /* sort */ const xmlChar *case_order; /* sort */
int lower_first; /* sort */ int lower_first; /* sort */
...@@ -1377,7 +1375,6 @@ struct _xsltStylePreComp { ...@@ -1377,7 +1375,6 @@ struct _xsltStylePreComp {
int descending; /* sort */ int descending; /* sort */
const xmlChar *lang; /* sort */ const xmlChar *lang; /* sort */
int has_lang; /* sort */ int has_lang; /* sort */
xsltLocale locale; /* sort */
const xmlChar *case_order; /* sort */ const xmlChar *case_order; /* sort */
int lower_first; /* sort */ int lower_first; /* sort */
...@@ -1663,6 +1660,13 @@ typedef enum { ...@@ -1663,6 +1660,13 @@ typedef enum {
XSLT_OUTPUT_TEXT XSLT_OUTPUT_TEXT
} xsltOutputType; } xsltOutputType;
typedef void *
(*xsltNewLocaleFunc)(const xmlChar *lang, int lowerFirst);
typedef void
(*xsltFreeLocaleFunc)(void *locale);
typedef xmlChar *
(*xsltGenSortKeyFunc)(void *locale, const xmlChar *lang);
typedef enum { typedef enum {
XSLT_STATE_OK = 0, XSLT_STATE_OK = 0,
XSLT_STATE_ERROR, XSLT_STATE_ERROR,
...@@ -1786,6 +1790,12 @@ struct _xsltTransformContext { ...@@ -1786,6 +1790,12 @@ struct _xsltTransformContext {
int maxTemplateVars; int maxTemplateVars;
unsigned long opLimit; unsigned long opLimit;
unsigned long opCount; unsigned long opCount;
int sourceDocDirty;
unsigned long currentId; /* For generate-id() */
xsltNewLocaleFunc newLocale;
xsltFreeLocaleFunc freeLocale;
xsltGenSortKeyFunc genSortKey;
}; };
/** /**
...@@ -1915,7 +1925,7 @@ XSLTPUBFUN int XSLTCALL ...@@ -1915,7 +1925,7 @@ XSLTPUBFUN int XSLTCALL
xsltFlagRVTs( xsltFlagRVTs(
xsltTransformContextPtr ctxt, xsltTransformContextPtr ctxt,
xmlXPathObjectPtr obj, xmlXPathObjectPtr obj,
void *val); int val);
XSLTPUBFUN void XSLTCALL XSLTPUBFUN void XSLTCALL
xsltFreeRVTs (xsltTransformContextPtr ctxt); xsltFreeRVTs (xsltTransformContextPtr ctxt);
XSLTPUBFUN void XSLTCALL XSLTPUBFUN void XSLTCALL
......
...@@ -20,21 +20,21 @@ extern "C" { ...@@ -20,21 +20,21 @@ extern "C" {
* *
* the version string like "1.2.3" * the version string like "1.2.3"
*/ */
#define LIBXSLT_DOTTED_VERSION "1.1.36" #define LIBXSLT_DOTTED_VERSION "1.1.38"
/** /**
* LIBXSLT_VERSION: * LIBXSLT_VERSION:
* *
* the version number: 1.2.3 value is 10203 * the version number: 1.2.3 value is 10203
*/ */
#define LIBXSLT_VERSION 10136 #define LIBXSLT_VERSION 10138
/** /**
* LIBXSLT_VERSION_STRING: * LIBXSLT_VERSION_STRING:
* *
* the version number string, 1.2.3 value is "10203" * the version number string, 1.2.3 value is "10203"
*/ */
#define LIBXSLT_VERSION_STRING "10136" #define LIBXSLT_VERSION_STRING "10138"
/** /**
* LIBXSLT_VERSION_EXTRA: * LIBXSLT_VERSION_EXTRA:
......
...@@ -19,6 +19,30 @@ ...@@ -19,6 +19,30 @@
#include "xsltlocale.h" #include "xsltlocale.h"
#include "xsltutils.h" #include "xsltutils.h"
#ifdef HAVE_STRXFRM_L
#define XSLT_LOCALE_POSIX
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
#ifdef HAVE_XLOCALE_H
#include <xlocale.h>
#endif
#elif defined(_WIN32)
#define XSLT_LOCALE_WINAPI
#include <windows.h>
#include <winnls.h>
#else
#define XSLT_LOCALE_NONE
#endif
#define TOUPPER(c) (c & ~0x20) #define TOUPPER(c) (c & ~0x20)
#define TOLOWER(c) (c | 0x20) #define TOLOWER(c) (c | 0x20)
#define ISALPHA(c) ((unsigned)(TOUPPER(c) - 'A') < 26) #define ISALPHA(c) ((unsigned)(TOUPPER(c) - 'A') < 26)
...@@ -37,8 +61,7 @@ xmlRMutexPtr xsltLocaleMutex = NULL; ...@@ -37,8 +61,7 @@ xmlRMutexPtr xsltLocaleMutex = NULL;
struct xsltRFC1766Info_s { struct xsltRFC1766Info_s {
/*note typedef unsigned char xmlChar !*/ /*note typedef unsigned char xmlChar !*/
xmlChar tag[XSLTMAX_LANGTAGLEN+1]; xmlChar tag[XSLTMAX_LANGTAGLEN+1];
/*note typedef LCID xsltLocale !*/ LCID lcid;
xsltLocale lcid;
}; };
typedef struct xsltRFC1766Info_s xsltRFC1766Info; typedef struct xsltRFC1766Info_s xsltRFC1766Info;
...@@ -46,14 +69,15 @@ static int xsltLocaleListSize = 0; ...@@ -46,14 +69,15 @@ static int xsltLocaleListSize = 0;
static xsltRFC1766Info *xsltLocaleList = NULL; static xsltRFC1766Info *xsltLocaleList = NULL;
static xsltLocale static void *
xslt_locale_WINAPI(const xmlChar *languageTag) { xslt_locale_WINAPI(const xmlChar *languageTag) {
int k; int k;
xsltRFC1766Info *p = xsltLocaleList; xsltRFC1766Info *p = xsltLocaleList;
for (k=0; k<xsltLocaleListSize; k++, p++) for (k=0; k<xsltLocaleListSize; k++, p++)
if (xmlStrcmp(p->tag, languageTag) == 0) return p->lcid; if (xmlStrcmp(p->tag, languageTag) == 0)
return((xsltLocale)0); return(&p->lcid);
return(NULL);
} }
static void xsltEnumSupportedLocales(void); static void xsltEnumSupportedLocales(void);
...@@ -83,17 +107,17 @@ xsltFreeLocales(void) { ...@@ -83,17 +107,17 @@ xsltFreeLocales(void) {
* *
* Returns the locale or NULL on error or if no matching locale was found * Returns the locale or NULL on error or if no matching locale was found
*/ */
xsltLocale void *
xsltNewLocale(const xmlChar *languageTag) { xsltNewLocale(const xmlChar *languageTag, int lowerFirst ATTRIBUTE_UNUSED) {
#ifdef XSLT_LOCALE_POSIX #ifdef XSLT_LOCALE_POSIX
xsltLocale locale; locale_t locale;
char localeName[XSLTMAX_LANGTAGLEN+6]; /* 6 chars for ".utf8\0" */ char localeName[XSLTMAX_LANGTAGLEN+7]; /* 7 chars for ".UTF-8\0" */
const xmlChar *p = languageTag; const xmlChar *p = languageTag;
const char *region = NULL; const char *region = NULL;
char *q = localeName; char *q = localeName;
int i, llen; int i, llen;
/* Convert something like "pt-br" to "pt_BR.utf8" */ /* Convert something like "pt-br" to "pt_BR.UTF-8" */
if (languageTag == NULL) if (languageTag == NULL)
return(NULL); return(NULL);
...@@ -117,7 +141,7 @@ xsltNewLocale(const xmlChar *languageTag) { ...@@ -117,7 +141,7 @@ xsltNewLocale(const xmlChar *languageTag) {
if (i == 0 || *p) if (i == 0 || *p)
return(NULL); return(NULL);
memcpy(q, ".utf8", 6); memcpy(q, ".UTF-8", 7);
locale = newlocale(LC_COLLATE_MASK, localeName, NULL); locale = newlocale(LC_COLLATE_MASK, localeName, NULL);
if (locale != NULL) if (locale != NULL)
return(locale); return(locale);
...@@ -129,7 +153,7 @@ xsltNewLocale(const xmlChar *languageTag) { ...@@ -129,7 +153,7 @@ xsltNewLocale(const xmlChar *languageTag) {
/* Try locale without territory, e.g. for Esperanto (eo) */ /* Try locale without territory, e.g. for Esperanto (eo) */
memcpy(q, ".utf8", 6); memcpy(q, ".UTF-8", 7);
locale = newlocale(LC_COLLATE_MASK, localeName, NULL); locale = newlocale(LC_COLLATE_MASK, localeName, NULL);
if (locale != NULL) if (locale != NULL)
return(locale); return(locale);
...@@ -147,7 +171,7 @@ xsltNewLocale(const xmlChar *languageTag) { ...@@ -147,7 +171,7 @@ xsltNewLocale(const xmlChar *languageTag) {
*q++ = '_'; *q++ = '_';
*q++ = region[0]; *q++ = region[0];
*q++ = region[1]; *q++ = region[1];
memcpy(q, ".utf8", 6); memcpy(q, ".UTF-8", 7);
locale = newlocale(LC_COLLATE_MASK, localeName, NULL); locale = newlocale(LC_COLLATE_MASK, localeName, NULL);
return(locale); return(locale);
...@@ -155,7 +179,7 @@ xsltNewLocale(const xmlChar *languageTag) { ...@@ -155,7 +179,7 @@ xsltNewLocale(const xmlChar *languageTag) {
#ifdef XSLT_LOCALE_WINAPI #ifdef XSLT_LOCALE_WINAPI
{ {
xsltLocale locale = (xsltLocale)0; void *locale = NULL;
xmlChar localeName[XSLTMAX_LANGTAGLEN+1]; xmlChar localeName[XSLTMAX_LANGTAGLEN+1];
xmlChar *q = localeName; xmlChar *q = localeName;
const xmlChar *p = languageTag; const xmlChar *p = languageTag;
...@@ -344,10 +368,12 @@ xsltDefaultRegion(const xmlChar *localeName) { ...@@ -344,10 +368,12 @@ xsltDefaultRegion(const xmlChar *localeName) {
* Frees a locale created with xsltNewLocale * Frees a locale created with xsltNewLocale
*/ */
void void
xsltFreeLocale(xsltLocale locale) { xsltFreeLocale(void *locale) {
#ifdef XSLT_LOCALE_POSIX #ifdef XSLT_LOCALE_POSIX
if (locale != NULL) if (locale != NULL)
freelocale(locale); freelocale(locale);
#else
(void) locale;
#endif #endif
} }
...@@ -356,57 +382,82 @@ xsltFreeLocale(xsltLocale locale) { ...@@ -356,57 +382,82 @@ xsltFreeLocale(xsltLocale locale) {
* @locale: locale created with xsltNewLocale * @locale: locale created with xsltNewLocale
* @string: UTF-8 string to transform * @string: UTF-8 string to transform
* *
* Transforms a string according to locale. The transformed string must then be * Transforms a string according to locale. The transformed string must be
* compared with xsltLocaleStrcmp and freed with xmlFree. * freed with xmlFree.
* *
* Returns the transformed string or NULL on error * Returns the transformed string or NULL on error
*/ */
xsltLocaleChar * xmlChar *
xsltStrxfrm(xsltLocale locale, const xmlChar *string) xsltStrxfrm(void *vlocale, const xmlChar *string)
{ {
#ifdef XSLT_LOCALE_NONE #ifdef XSLT_LOCALE_NONE
return(NULL); return(NULL);
#else #else
size_t xstrlen, r; xmlChar *xstr;
xsltLocaleChar *xstr;
#ifdef XSLT_LOCALE_POSIX #ifdef XSLT_LOCALE_POSIX
xstrlen = strxfrm_l(NULL, (const char *)string, 0, locale) + 1; size_t xstrlen, r;
xstr = (xsltLocaleChar *) xmlMalloc(xstrlen);
xstrlen = strxfrm_l(NULL, (const char *)string, 0, vlocale) + 1;
xstr = (xmlChar *) xmlMalloc(xstrlen);
if (xstr == NULL) { if (xstr == NULL) {
xsltTransformError(NULL, NULL, NULL, xsltTransformError(NULL, NULL, NULL,
"xsltStrxfrm : out of memory error\n"); "xsltStrxfrm : out of memory error\n");
return(NULL); return(NULL);
} }
r = strxfrm_l((char *)xstr, (const char *)string, xstrlen, locale); r = strxfrm_l((char *)xstr, (const char *)string, xstrlen, vlocale);
if (r >= xstrlen) {
xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : strxfrm failed\n");
xmlFree(xstr);
return(NULL);
}
#endif #endif
#ifdef XSLT_LOCALE_WINAPI #ifdef XSLT_LOCALE_WINAPI
xstrlen = MultiByteToWideChar(CP_UTF8, 0, (char *) string, -1, NULL, 0); int wstrlen, xstrlen, r;
if (xstrlen == 0) { wchar_t *wstr;
LCID *lcid = vlocale;
wstrlen = MultiByteToWideChar(CP_UTF8, 0, (char *) string, -1, NULL, 0);
if (wstrlen == 0) {
xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : MultiByteToWideChar check failed\n"); xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : MultiByteToWideChar check failed\n");
return(NULL); return(NULL);
} }
xstr = (xsltLocaleChar*) xmlMalloc(xstrlen * sizeof(xsltLocaleChar)); wstr = (wchar_t *) xmlMalloc(wstrlen * sizeof(wchar_t));
if (xstr == NULL) { if (wstr == NULL) {
xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : out of memory\n"); xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : out of memory\n");
return(NULL); return(NULL);
} }
r = MultiByteToWideChar(CP_UTF8, 0, (char *) string, -1, xstr, xstrlen); r = MultiByteToWideChar(CP_UTF8, 0, (char *) string, -1, wstr, wstrlen);
if (r == 0) { if (r == 0) {
xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : MultiByteToWideChar failed\n"); xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : MultiByteToWideChar failed\n");
xmlFree(xstr); xmlFree(wstr);
return(NULL); return(NULL);
} }
return(xstr); /* This returns the size in bytes. */
#endif /* XSLT_LOCALE_WINAPI */ xstrlen = LCMapStringW(*lcid, LCMAP_SORTKEY, wstr, wstrlen, NULL, 0);
if (xstrlen == 0) {
if (r >= xstrlen) { xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : LCMapStringW failed\n");
xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : strxfrm failed\n"); xmlFree(wstr);
return(NULL);
}
xstr = (xmlChar*) xmlMalloc(xstrlen);
if (xstr == NULL) {
xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : out of memory\n");
xmlFree(wstr);
return(NULL);
}
r = LCMapStringW(*lcid, LCMAP_SORTKEY, wstr, wstrlen, (wchar_t *) xstr,
xstrlen);
xmlFree(wstr);
if (r == 0) {
xsltTransformError(NULL, NULL, NULL, "xsltStrxfrm : LCMapStringW failed\n");
xmlFree(xstr); xmlFree(xstr);
return(NULL); return(NULL);
} }
#endif /* XSLT_LOCALE_WINAPI */
return(xstr); return(xstr);
#endif /* XSLT_LOCALE_NONE */ #endif /* XSLT_LOCALE_NONE */
...@@ -414,35 +465,22 @@ xsltStrxfrm(xsltLocale locale, const xmlChar *string) ...@@ -414,35 +465,22 @@ xsltStrxfrm(xsltLocale locale, const xmlChar *string)
/** /**
* xsltLocaleStrcmp: * xsltLocaleStrcmp:
* @locale: a locale identifier * @locale: unused
* @str1: a string transformed with xsltStrxfrm * @str1: a string transformed with xsltStrxfrm
* @str2: a string transformed with xsltStrxfrm * @str2: a string transformed with xsltStrxfrm
* *
* Compares two strings transformed with xsltStrxfrm * DEPRECATED: Same as xmlStrcmp.
*
* Compares two strings transformed with xsltStrxfrm.
* *
* Returns a value < 0 if str1 sorts before str2, * Returns a value < 0 if str1 sorts before str2,
* a value > 0 if str1 sorts after str2, * a value > 0 if str1 sorts after str2,
* 0 if str1 and str2 are equal wrt sorting * 0 if str1 and str2 are equal wrt sorting
*/ */
int int
xsltLocaleStrcmp(xsltLocale locale, const xsltLocaleChar *str1, const xsltLocaleChar *str2) { xsltLocaleStrcmp(void *locale, const xmlChar *str1, const xmlChar *str2) {
(void)locale; (void)locale;
#ifdef XSLT_LOCALE_WINAPI
{
int ret;
if (str1 == str2) return(0);
if (str1 == NULL) return(-1);
if (str2 == NULL) return(1);
ret = CompareStringW(locale, 0, str1, -1, str2, -1);
if (ret == 0) {
xsltTransformError(NULL, NULL, NULL, "xsltLocaleStrcmp : CompareStringW fail\n");
return(0);
}
return(ret - 2);
}
#else
return(xmlStrcmp(str1, str2)); return(xmlStrcmp(str1, str2));
#endif
} }
#ifdef XSLT_LOCALE_WINAPI #ifdef XSLT_LOCALE_WINAPI
...@@ -454,7 +492,7 @@ xsltLocaleStrcmp(xsltLocale locale, const xsltLocaleChar *str1, const xsltLocale ...@@ -454,7 +492,7 @@ xsltLocaleStrcmp(xsltLocale locale, const xsltLocaleChar *str1, const xsltLocale
* *
* Returns TRUE * Returns TRUE
*/ */
BOOL CALLBACK static BOOL CALLBACK
xsltCountSupportedLocales(LPSTR lcid) { xsltCountSupportedLocales(LPSTR lcid) {
(void) lcid; (void) lcid;
++xsltLocaleListSize; ++xsltLocaleListSize;
...@@ -469,7 +507,7 @@ xsltCountSupportedLocales(LPSTR lcid) { ...@@ -469,7 +507,7 @@ xsltCountSupportedLocales(LPSTR lcid) {
* *
* Returns TRUE if not at the end of the array * Returns TRUE if not at the end of the array
*/ */
BOOL CALLBACK static BOOL CALLBACK
xsltIterateSupportedLocales(LPSTR lcid) { xsltIterateSupportedLocales(LPSTR lcid) {
static int count = 0; static int count = 0;
xmlChar iso639lang [XSLTMAX_ISO639LANGLEN +1]; xmlChar iso639lang [XSLTMAX_ISO639LANGLEN +1];
...@@ -477,7 +515,7 @@ xsltIterateSupportedLocales(LPSTR lcid) { ...@@ -477,7 +515,7 @@ xsltIterateSupportedLocales(LPSTR lcid) {
int k, l; int k, l;
xsltRFC1766Info *p = xsltLocaleList + count; xsltRFC1766Info *p = xsltLocaleList + count;
k = sscanf(lcid, "%lx", (long*)&p->lcid); k = sscanf(lcid, "%lx", (unsigned long*)&p->lcid);
if (k < 1) goto end; if (k < 1) goto end;
/*don't count terminating null character*/ /*don't count terminating null character*/
k = GetLocaleInfoA(p->lcid, LOCALE_SISO639LANGNAME, k = GetLocaleInfoA(p->lcid, LOCALE_SISO639LANGNAME,
......
...@@ -14,63 +14,23 @@ ...@@ -14,63 +14,23 @@
#include <libxml/xmlstring.h> #include <libxml/xmlstring.h>
#include "xsltexports.h" #include "xsltexports.h"
#ifdef HAVE_STRXFRM_L XSLTPUBFUN void * XSLTCALL
xsltNewLocale (const xmlChar *langName,
/* int lowerFirst);
* XSLT_LOCALE_POSIX:
* Macro indicating to use POSIX locale extensions
*/
#define XSLT_LOCALE_POSIX
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
#ifdef HAVE_XLOCALE_H
#include <xlocale.h>
#endif
typedef locale_t xsltLocale;
typedef xmlChar xsltLocaleChar;
#elif defined(_WIN32)
/*
* XSLT_LOCALE_WINAPI:
* Macro indicating to use WinAPI for extended locale support
*/
#define XSLT_LOCALE_WINAPI
#include <windows.h>
#include <winnls.h>
typedef LCID xsltLocale;
typedef wchar_t xsltLocaleChar;
#else
/*
* XSLT_LOCALE_NONE:
* Macro indicating that there's no extended locale support
*/
#define XSLT_LOCALE_NONE
typedef void *xsltLocale;
typedef xmlChar xsltLocaleChar;
#endif
XSLTPUBFUN xsltLocale XSLTCALL
xsltNewLocale (const xmlChar *langName);
XSLTPUBFUN void XSLTCALL XSLTPUBFUN void XSLTCALL
xsltFreeLocale (xsltLocale locale); xsltFreeLocale (void *locale);
XSLTPUBFUN xsltLocaleChar * XSLTCALL XSLTPUBFUN xmlChar * XSLTCALL
xsltStrxfrm (xsltLocale locale, xsltStrxfrm (void *locale,
const xmlChar *string); const xmlChar *string);
XSLTPUBFUN int XSLTCALL
xsltLocaleStrcmp (xsltLocale locale,
const xsltLocaleChar *str1,
const xsltLocaleChar *str2);
XSLTPUBFUN void XSLTCALL XSLTPUBFUN void XSLTCALL
xsltFreeLocales (void); xsltFreeLocales (void);
/* Backward compatibility */
typedef void *xsltLocale;
typedef xmlChar xsltLocaleChar;
XSLTPUBFUN int XSLTCALL
xsltLocaleStrcmp (void *locale,
const xmlChar *str1,
const xmlChar *str2);
#endif /* __XML_XSLTLOCALE_H__ */ #endif /* __XML_XSLTLOCALE_H__ */
...@@ -91,6 +91,13 @@ XSLTPUBFUN const xmlChar * XSLTCALL ...@@ -91,6 +91,13 @@ XSLTPUBFUN const xmlChar * XSLTCALL
XSLTPUBFUN int XSLTCALL XSLTPUBFUN int XSLTCALL
xsltGetUTF8Char (const unsigned char *utf, xsltGetUTF8Char (const unsigned char *utf,
int *len); int *len);
#ifdef IN_LIBXSLT
/** DOC_DISABLE */
XSLTPUBFUN int XSLTCALL
xsltGetUTF8CharZ (const unsigned char *utf,
int *len);
/** DOC_ENABLE */
#endif
/* /*
* XSLT Debug Tracing Tracing Types * XSLT Debug Tracing Tracing Types
...@@ -179,6 +186,11 @@ XSLTPUBFUN void XSLTCALL ...@@ -179,6 +186,11 @@ XSLTPUBFUN void XSLTCALL
xsltSetCtxtSortFunc (xsltTransformContextPtr ctxt, xsltSetCtxtSortFunc (xsltTransformContextPtr ctxt,
xsltSortFunc handler); xsltSortFunc handler);
XSLTPUBFUN void XSLTCALL XSLTPUBFUN void XSLTCALL
xsltSetCtxtLocaleHandlers (xsltTransformContextPtr ctxt,
xsltNewLocaleFunc newLocale,
xsltFreeLocaleFunc freeLocale,
xsltGenSortKeyFunc genSortKey);
XSLTPUBFUN void XSLTCALL
xsltDefaultSortFunction (xsltTransformContextPtr ctxt, xsltDefaultSortFunction (xsltTransformContextPtr ctxt,
xmlNodePtr *sorts, xmlNodePtr *sorts,
int nbsorts); int nbsorts);
...@@ -244,6 +256,24 @@ XSLTPUBFUN xmlXPathCompExprPtr XSLTCALL ...@@ -244,6 +256,24 @@ XSLTPUBFUN xmlXPathCompExprPtr XSLTCALL
const xmlChar *str, const xmlChar *str,
int flags); int flags);
#ifdef IN_LIBXSLT
/** DOC_DISABLE */
#define XSLT_SOURCE_NODE_MASK 15u
#define XSLT_SOURCE_NODE_HAS_KEY 1u
#define XSLT_SOURCE_NODE_HAS_ID 2u
int
xsltGetSourceNodeFlags(xmlNodePtr node);
int
xsltSetSourceNodeFlags(xsltTransformContextPtr ctxt, xmlNodePtr node,
int flags);
int
xsltClearSourceNodeFlags(xmlNodePtr node, int flags);
void **
xsltGetPSVIPtr(xmlNodePtr cur);
/** DOC_ENABLE */
#endif
#ifdef WITH_PROFILER
/* /*
* Profiling. * Profiling.
*/ */
...@@ -257,6 +287,7 @@ XSLTPUBFUN long XSLTCALL ...@@ -257,6 +287,7 @@ XSLTPUBFUN long XSLTCALL
xsltTimestamp (void); xsltTimestamp (void);
XSLTPUBFUN void XSLTCALL XSLTPUBFUN void XSLTCALL
xsltCalibrateAdjust (long delta); xsltCalibrateAdjust (long delta);
#endif
/** /**
* XSLT_TIMESTAMP_TICS_PER_SEC: * XSLT_TIMESTAMP_TICS_PER_SEC:
...@@ -289,10 +320,11 @@ typedef void (*xsltHandleDebuggerCallback) (xmlNodePtr cur, xmlNodePtr node, ...@@ -289,10 +320,11 @@ typedef void (*xsltHandleDebuggerCallback) (xmlNodePtr cur, xmlNodePtr node,
typedef int (*xsltAddCallCallback) (xsltTemplatePtr templ, xmlNodePtr source); typedef int (*xsltAddCallCallback) (xsltTemplatePtr templ, xmlNodePtr source);
typedef void (*xsltDropCallCallback) (void); typedef void (*xsltDropCallCallback) (void);
XSLTPUBFUN void XSLTCALL
xsltSetDebuggerStatus (int value);
XSLTPUBFUN int XSLTCALL XSLTPUBFUN int XSLTCALL
xsltGetDebuggerStatus (void); xsltGetDebuggerStatus (void);
#ifdef WITH_DEBUGGER
XSLTPUBFUN void XSLTCALL
xsltSetDebuggerStatus (int value);
XSLTPUBFUN int XSLTCALL XSLTPUBFUN int XSLTCALL
xsltSetDebuggerCallbacks (int no, void *block); xsltSetDebuggerCallbacks (int no, void *block);
XSLTPUBFUN int XSLTCALL XSLTPUBFUN int XSLTCALL
...@@ -300,6 +332,7 @@ XSLTPUBFUN int XSLTCALL ...@@ -300,6 +332,7 @@ XSLTPUBFUN int XSLTCALL
xmlNodePtr source); xmlNodePtr source);
XSLTPUBFUN void XSLTCALL XSLTPUBFUN void XSLTCALL
xslDropCall (void); xslDropCall (void);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment