summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Wellnhofer <wellnhofer@aevum.de>2010-11-08 14:50:17 +0100
committerDaniel Veillard <veillard@redhat.com>2010-11-08 14:50:17 +0100
commit0d6713d715509da1fec27bec220d43aa4fc48d0f (patch)
treed03c874be7266dfd076152a7f78c5ae33e4f822d
parent1a40591d824391efd377a0859a9fab928a36f498 (diff)
downloadlibxslt-0d6713d715509da1fec27bec220d43aa4fc48d0f.tar.gz
libxslt-0d6713d715509da1fec27bec220d43aa4fc48d0f.tar.bz2
libxslt-0d6713d715509da1fec27bec220d43aa4fc48d0f.zip
Precompile patterns in xsl:number
speedup optimization, it should not change semantic at all
-rw-r--r--libxslt/numbers.c55
-rw-r--r--libxslt/numbersInternals.h4
-rw-r--r--libxslt/preproc.c25
3 files changed, 41 insertions, 43 deletions
diff --git a/libxslt/numbers.c b/libxslt/numbers.c
index 8683ca8b..076ba2a6 100644
--- a/libxslt/numbers.c
+++ b/libxslt/numbers.c
@@ -534,8 +534,8 @@ xsltNumberFormatInsertNumbers(xsltNumberDataPtr data,
static int
xsltNumberFormatGetAnyLevel(xsltTransformContextPtr context,
xmlNodePtr node,
- const xmlChar *count,
- const xmlChar *from,
+ xsltCompMatchPtr countPat,
+ xsltCompMatchPtr fromPat,
double *array,
xmlDocPtr doc,
xmlNodePtr elem)
@@ -543,14 +543,7 @@ xsltNumberFormatGetAnyLevel(xsltTransformContextPtr context,
int amount = 0;
int cnt = 0;
xmlNodePtr cur;
- xsltCompMatchPtr countPat = NULL;
- xsltCompMatchPtr fromPat = NULL;
- if (count != NULL)
- countPat = xsltCompilePattern(count, doc, elem, NULL, context);
- if (from != NULL)
- fromPat = xsltCompilePattern(from, doc, elem, NULL, context);
-
/* select the starting node */
switch (node->type) {
case XML_ELEMENT_NODE:
@@ -571,7 +564,7 @@ xsltNumberFormatGetAnyLevel(xsltTransformContextPtr context,
while (cur != NULL) {
/* process current node */
- if (count == NULL) {
+ if (countPat == NULL) {
if ((node->type == cur->type) &&
/* FIXME: must use expanded-name instead of local name */
xmlStrEqual(node->name, cur->name)) {
@@ -586,7 +579,7 @@ xsltNumberFormatGetAnyLevel(xsltTransformContextPtr context,
if (xsltTestCompMatchList(context, cur, countPat))
cnt++;
}
- if ((from != NULL) &&
+ if ((fromPat != NULL) &&
xsltTestCompMatchList(context, cur, fromPat)) {
break; /* while */
}
@@ -613,18 +606,14 @@ xsltNumberFormatGetAnyLevel(xsltTransformContextPtr context,
array[amount++] = (double) cnt;
- if (countPat != NULL)
- xsltFreeCompMatchList(countPat);
- if (fromPat != NULL)
- xsltFreeCompMatchList(fromPat);
return(amount);
}
static int
xsltNumberFormatGetMultipleLevel(xsltTransformContextPtr context,
xmlNodePtr node,
- const xmlChar *count,
- const xmlChar *from,
+ xsltCompMatchPtr countPat,
+ xsltCompMatchPtr fromPat,
double *array,
int max,
xmlDocPtr doc,
@@ -635,17 +624,7 @@ xsltNumberFormatGetMultipleLevel(xsltTransformContextPtr context,
xmlNodePtr ancestor;
xmlNodePtr preceding;
xmlXPathParserContextPtr parser;
- xsltCompMatchPtr countPat;
- xsltCompMatchPtr fromPat;
-
- if (count != NULL)
- countPat = xsltCompilePattern(count, doc, elem, NULL, context);
- else
- countPat = NULL;
- if (from != NULL)
- fromPat = xsltCompilePattern(from, doc, elem, NULL, context);
- else
- fromPat = NULL;
+
context->xpathCtxt->node = node;
parser = xmlXPathNewParserContext(NULL, context->xpathCtxt);
if (parser) {
@@ -654,11 +633,11 @@ xsltNumberFormatGetMultipleLevel(xsltTransformContextPtr context,
(ancestor != NULL) && (ancestor->type != XML_DOCUMENT_NODE);
ancestor = xmlXPathNextAncestor(parser, ancestor)) {
- if ((from != NULL) &&
+ if ((fromPat != NULL) &&
xsltTestCompMatchList(context, ancestor, fromPat))
break; /* for */
- if ((count == NULL && node->type == ancestor->type &&
+ if ((countPat == NULL && node->type == ancestor->type &&
xmlStrEqual(node->name, ancestor->name)) ||
xsltTestCompMatchList(context, ancestor, countPat)) {
/* count(preceding-sibling::*) */
@@ -667,7 +646,7 @@ xsltNumberFormatGetMultipleLevel(xsltTransformContextPtr context,
preceding != NULL;
preceding =
xmlXPathNextPrecedingSibling(parser, preceding)) {
- if (count == NULL) {
+ if (countPat == NULL) {
if ((preceding->type == ancestor->type) &&
xmlStrEqual(preceding->name, ancestor->name)){
if ((preceding->ns == ancestor->ns) ||
@@ -690,8 +669,6 @@ xsltNumberFormatGetMultipleLevel(xsltTransformContextPtr context,
}
xmlXPathFreeParserContext(parser);
}
- xsltFreeCompMatchList(countPat);
- xsltFreeCompMatchList(fromPat);
return amount;
}
@@ -779,8 +756,8 @@ xsltNumberFormat(xsltTransformContextPtr ctxt,
if (xmlStrEqual(data->level, (const xmlChar *) "single")) {
amount = xsltNumberFormatGetMultipleLevel(ctxt,
node,
- data->count,
- data->from,
+ data->countPat,
+ data->fromPat,
&number,
1,
data->doc,
@@ -797,8 +774,8 @@ xsltNumberFormat(xsltTransformContextPtr ctxt,
int max = sizeof(numarray)/sizeof(numarray[0]);
amount = xsltNumberFormatGetMultipleLevel(ctxt,
node,
- data->count,
- data->from,
+ data->countPat,
+ data->fromPat,
numarray,
max,
data->doc,
@@ -813,8 +790,8 @@ xsltNumberFormat(xsltTransformContextPtr ctxt,
} else if (xmlStrEqual(data->level, (const xmlChar *) "any")) {
amount = xsltNumberFormatGetAnyLevel(ctxt,
node,
- data->count,
- data->from,
+ data->countPat,
+ data->fromPat,
&number,
data->doc,
data->node);
diff --git a/libxslt/numbersInternals.h b/libxslt/numbersInternals.h
index 7b3cb17b..cacb2724 100644
--- a/libxslt/numbersInternals.h
+++ b/libxslt/numbersInternals.h
@@ -17,6 +17,8 @@
extern "C" {
#endif
+struct _xsltCompMatch;
+
/**
* xsltNumberData:
*
@@ -37,6 +39,8 @@ struct _xsltNumberData {
int groupingCharacterLen;
xmlDocPtr doc;
xmlNodePtr node;
+ struct _xsltCompMatch *countPat;
+ struct _xsltCompMatch *fromPat;
/*
* accelerators
diff --git a/libxslt/preproc.c b/libxslt/preproc.c
index 0e393437..4a4bfbfd 100644
--- a/libxslt/preproc.c
+++ b/libxslt/preproc.c
@@ -39,6 +39,7 @@
#include "extra.h"
#include "imports.h"
#include "extensions.h"
+#include "pattern.h"
#ifdef WITH_XSLT_DEBUG
#define WITH_XSLT_DEBUG_PREPROC
@@ -420,6 +421,10 @@ xsltFreeStylePreComp(xsltStylePreCompPtr comp) {
}
break;
case XSLT_FUNC_NUMBER:
+ if (item->numdata.countPat != NULL)
+ xsltFreeCompMatchList(item->numdata.countPat);
+ if (item->numdata.fromPat != NULL)
+ xsltFreeCompMatchList(item->numdata.fromPat);
break;
case XSLT_FUNC_APPLYIMPORTS:
break;
@@ -1426,7 +1431,7 @@ xsltNumberComp(xsltStylesheetPtr style, xmlNodePtr cur) {
comp->numdata.node = cur;
comp->numdata.value = xsltGetCNsProp(style, cur, (const xmlChar *)"value",
XSLT_NAMESPACE);
-
+
prop = xsltEvalStaticAttrValueTemplate(style, cur,
(const xmlChar *)"format",
XSLT_NAMESPACE, &comp->numdata.has_format);
@@ -1437,10 +1442,22 @@ xsltNumberComp(xsltStylesheetPtr style, xmlNodePtr cur) {
}
comp->numdata.count = xsltGetCNsProp(style, cur, (const xmlChar *)"count",
- XSLT_NAMESPACE);
+ XSLT_NAMESPACE);
comp->numdata.from = xsltGetCNsProp(style, cur, (const xmlChar *)"from",
- XSLT_NAMESPACE);
-
+ XSLT_NAMESPACE);
+
+ prop = xsltGetCNsProp(style, cur, (const xmlChar *)"count", XSLT_NAMESPACE);
+ if (prop != NULL) {
+ comp->numdata.countPat = xsltCompilePattern(prop, cur->doc, cur, style,
+ NULL);
+ }
+
+ prop = xsltGetCNsProp(style, cur, (const xmlChar *)"from", XSLT_NAMESPACE);
+ if (prop != NULL) {
+ comp->numdata.fromPat = xsltCompilePattern(prop, cur->doc, cur, style,
+ NULL);
+ }
+
prop = xsltGetCNsProp(style, cur, (const xmlChar *)"level", XSLT_NAMESPACE);
if (prop != NULL) {
if (xmlStrEqual(prop, BAD_CAST("single")) ||