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