Index: third_party/libxslt/libxslt/xsltutils.c |
diff --git a/third_party/libxslt/libxslt/xsltutils.c b/third_party/libxslt/libxslt/xsltutils.c |
index 9565e152fbfd1791c7c96b47fe0ee8c1d9841d17..ab981a4237274e6ea44604250f047b9c6c844ead 100644 |
--- a/third_party/libxslt/libxslt/xsltutils.c |
+++ b/third_party/libxslt/libxslt/xsltutils.c |
@@ -19,6 +19,7 @@ |
#endif |
#include <string.h> |
+#include <time.h> |
#ifdef HAVE_SYS_TIME_H |
#include <sys/time.h> |
#endif |
@@ -53,9 +54,9 @@ |
#endif /* WIN32 */ |
/************************************************************************ |
- * * |
- * Convenience function * |
- * * |
+ * * |
+ * Convenience function * |
+ * * |
************************************************************************/ |
/** |
@@ -90,10 +91,15 @@ xsltGetCNsProp(xsltStylesheetPtr style, xmlNodePtr node, |
if ((node == NULL) || (style == NULL) || (style->dict == NULL)) |
return(NULL); |
- prop = node->properties; |
- if (nameSpace == NULL) { |
+ if (nameSpace == NULL) |
return xmlGetProp(node, name); |
- } |
+ |
+ if (node->type == XML_NAMESPACE_DECL) |
+ return(NULL); |
+ if (node->type == XML_ELEMENT_NODE) |
+ prop = node->properties; |
+ else |
+ prop = NULL; |
while (prop != NULL) { |
/* |
* One need to have |
@@ -130,7 +136,7 @@ xsltGetCNsProp(xsltStylesheetPtr style, xmlNodePtr node, |
attrDecl = xmlGetDtdAttrDesc(doc->intSubset, node->name, name); |
if ((attrDecl == NULL) && (doc->extSubset != NULL)) |
attrDecl = xmlGetDtdAttrDesc(doc->extSubset, node->name, name); |
- |
+ |
if ((attrDecl != NULL) && (attrDecl->prefix != NULL)) { |
/* |
* The DTD declaration only allows a prefix search |
@@ -172,7 +178,15 @@ xsltGetNsProp(xmlNodePtr node, const xmlChar *name, const xmlChar *nameSpace) { |
if (node == NULL) |
return(NULL); |
- prop = node->properties; |
+ if (nameSpace == NULL) |
+ return xmlGetProp(node, name); |
+ |
+ if (node->type == XML_NAMESPACE_DECL) |
+ return(NULL); |
+ if (node->type == XML_ELEMENT_NODE) |
+ prop = node->properties; |
+ else |
+ prop = NULL; |
/* |
* TODO: Substitute xmlGetProp() for xmlGetNsProp(), since the former |
* is not namespace-aware and will return an attribute with equal |
@@ -182,8 +196,6 @@ xsltGetNsProp(xmlNodePtr node, const xmlChar *name, const xmlChar *nameSpace) { |
* So this would return "myName" even if an attribute @name |
* in the XSLT was requested. |
*/ |
- if (nameSpace == NULL) |
- return(xmlGetProp(node, name)); |
while (prop != NULL) { |
/* |
* One need to have |
@@ -216,7 +228,7 @@ xsltGetNsProp(xmlNodePtr node, const xmlChar *name, const xmlChar *nameSpace) { |
attrDecl = xmlGetDtdAttrDesc(doc->intSubset, node->name, name); |
if ((attrDecl == NULL) && (doc->extSubset != NULL)) |
attrDecl = xmlGetDtdAttrDesc(doc->extSubset, node->name, name); |
- |
+ |
if ((attrDecl != NULL) && (attrDecl->prefix != NULL)) { |
/* |
* The DTD declaration only allows a prefix search |
@@ -314,7 +326,7 @@ error: |
* -1 in case of an error. |
*/ |
int |
-xsltPointerListAddSize(xsltPointerListPtr list, |
+xsltPointerListAddSize(xsltPointerListPtr list, |
void *item, |
int initialSize) |
{ |
@@ -410,9 +422,9 @@ xsltPointerListClear(xsltPointerListPtr list) |
#endif /* XSLT_REFACTORED */ |
/************************************************************************ |
- * * |
- * Handling of XSLT stylesheets messages * |
- * * |
+ * * |
+ * Handling of XSLT stylesheets messages * |
+ * * |
************************************************************************/ |
/** |
@@ -465,9 +477,9 @@ xsltMessage(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst) { |
} |
/************************************************************************ |
- * * |
- * Handling of out of context errors * |
- * * |
+ * * |
+ * Handling of out of context errors * |
+ * * |
************************************************************************/ |
#define XSLT_GET_VAR_STR(msg, str) { \ |
@@ -477,14 +489,14 @@ xsltMessage(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst) { |
va_list ap; \ |
\ |
str = (char *) xmlMalloc(150); \ |
- if (str == NULL) \ |
+ if (str == NULL) \ |
return; \ |
\ |
size = 150; \ |
\ |
while (size < 64000) { \ |
va_start(ap, msg); \ |
- chars = vsnprintf(str, size, msg, ap); \ |
+ chars = vsnprintf(str, size, msg, ap); \ |
va_end(ap); \ |
if ((chars > -1) && (chars < size)) \ |
break; \ |
@@ -504,7 +516,7 @@ xsltMessage(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst) { |
* @ctx: an error context |
* @msg: the message to display/transmit |
* @...: extra parameters for the message display |
- * |
+ * |
* Default handler for out of context error messages. |
*/ |
static void |
@@ -550,7 +562,7 @@ xsltSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc handler) { |
* @ctx: an error context |
* @msg: the message to display/transmit |
* @...: extra parameters for the message display |
- * |
+ * |
* Default handler for out of context error messages. |
*/ |
static void |
@@ -632,8 +644,8 @@ xsltPrintErrorContext(xsltTransformContextPtr ctxt, |
if (node->name != NULL) |
name = node->name; |
} |
- } |
- |
+ } |
+ |
if (ctxt != NULL) |
type = "runtime error"; |
else if (style != NULL) { |
@@ -719,9 +731,9 @@ xsltTransformError(xsltTransformContextPtr ctxt, |
} |
/************************************************************************ |
- * * |
- * QNames * |
- * * |
+ * * |
+ * QNames * |
+ * * |
************************************************************************/ |
/** |
@@ -796,9 +808,9 @@ xsltGetQNameURI(xmlNodePtr node, xmlChar ** name) |
* we are not trying to validate but just to cut, and yes it will |
* work even if this is a set of UTF-8 encoded chars |
*/ |
- while ((qname[len] != 0) && (qname[len] != ':')) |
+ while ((qname[len] != 0) && (qname[len] != ':')) |
len++; |
- |
+ |
if (qname[len] == 0) |
return(NULL); |
@@ -903,11 +915,11 @@ xsltGetQNameURI2(xsltStylesheetPtr style, xmlNodePtr node, |
xmlFree(qname); |
return(ns->href); |
} |
- |
+ |
/************************************************************************ |
- * * |
- * Sorting * |
- * * |
+ * * |
+ * Sorting * |
+ * * |
************************************************************************/ |
/** |
@@ -962,7 +974,7 @@ xsltComputeSortResult(xsltTransformContextPtr ctxt, xmlNodePtr sort) { |
xmlNodeSetPtr list = NULL; |
xmlXPathObjectPtr res; |
int len = 0; |
- int i; |
+ int i; |
xmlNodePtr oldNode; |
xmlNodePtr oldInst; |
int oldPos, oldSize ; |
@@ -1078,7 +1090,7 @@ xsltComputeSortResult(xsltTransformContextPtr ctxt, xmlNodePtr sort) { |
* reorder the current node list accordingly to the set of sorting |
* requirement provided by the arry of nodes. |
*/ |
-void |
+void |
xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, |
int nbsorts) { |
#ifdef XSLT_REFACTORED |
@@ -1095,7 +1107,7 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, |
int tst; |
int depth; |
xmlNodePtr node; |
- xmlXPathObjectPtr tmp; |
+ xmlXPathObjectPtr tmp; |
int tempstype[XSLT_MAX_SORT], temporder[XSLT_MAX_SORT]; |
if ((ctxt == NULL) || (sorts == NULL) || (nbsorts <= 0) || |
@@ -1175,7 +1187,7 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, |
j = i - incr; |
if (results[i] == NULL) |
continue; |
- |
+ |
while (j >= 0) { |
if (results[j] == NULL) |
tst = 1; |
@@ -1193,7 +1205,7 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, |
else if (results[j]->floatval == |
results[j + incr]->floatval) |
tst = 0; |
- else if (results[j]->floatval > |
+ else if (results[j]->floatval > |
results[j + incr]->floatval) |
tst = 1; |
else tst = -1; |
@@ -1201,10 +1213,10 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, |
tst = xsltLocaleStrcmp( |
comp->locale, |
(xsltLocaleChar *) results[j]->stringval, |
- (xsltLocaleChar *) results[j + incr]->stringval); |
+ (xsltLocaleChar *) results[j + incr]->stringval); |
} else { |
tst = xmlStrcmp(results[j]->stringval, |
- results[j + incr]->stringval); |
+ results[j + incr]->stringval); |
} |
if (descending) |
tst = -tst; |
@@ -1227,11 +1239,11 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, |
* Compute the result of the next level for the |
* full set, this might be optimized ... or not |
*/ |
- if (resultsTab[depth] == NULL) |
+ if (resultsTab[depth] == NULL) |
resultsTab[depth] = xsltComputeSortResult(ctxt, |
sorts[depth]); |
res = resultsTab[depth]; |
- if (res == NULL) |
+ if (res == NULL) |
break; |
if (res[j] == NULL) { |
if (res[j+incr] != NULL) |
@@ -1242,7 +1254,7 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, |
accordance with XSLT spec */ |
if (xmlXPathIsNaN(res[j]->floatval)) { |
if (xmlXPathIsNaN(res[j + |
- incr]->floatval)) |
+ incr]->floatval)) |
tst = 0; |
else |
tst = -1; |
@@ -1252,7 +1264,7 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, |
else if (res[j]->floatval == res[j + incr]-> |
floatval) |
tst = 0; |
- else if (res[j]->floatval > |
+ else if (res[j]->floatval > |
res[j + incr]->floatval) |
tst = 1; |
else tst = -1; |
@@ -1260,10 +1272,10 @@ xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, |
tst = xsltLocaleStrcmp( |
comp->locale, |
(xsltLocaleChar *) res[j]->stringval, |
- (xsltLocaleChar *) res[j + incr]->stringval); |
+ (xsltLocaleChar *) res[j + incr]->stringval); |
} else { |
tst = xmlStrcmp(res[j]->stringval, |
- res[j + incr]->stringval); |
+ res[j + incr]->stringval); |
} |
if (desc) |
tst = -tst; |
@@ -1375,32 +1387,32 @@ xsltSetSortFunc(xsltSortFunc handler) { |
* @handler: the new handler function |
* |
* Function to set the handler for XSLT sorting |
- * for the specified context. |
+ * for the specified context. |
* If the handler is NULL, then the global |
* sort function will be called |
*/ |
-void |
+void |
xsltSetCtxtSortFunc(xsltTransformContextPtr ctxt, xsltSortFunc handler) { |
ctxt->sortfunc = handler; |
} |
/************************************************************************ |
- * * |
- * Parsing options * |
- * * |
+ * * |
+ * Parsing options * |
+ * * |
************************************************************************/ |
/** |
* xsltSetCtxtParseOptions: |
* @ctxt: a XSLT process context |
* @options: a combination of libxml2 xmlParserOption |
- * |
- * Change the default parser option passed by the XSLT engine to the |
+ * |
+ * Change the default parser option passed by the XSLT engine to the |
* parser when using document() loading. |
* |
* Returns the previous options or -1 in case of error |
*/ |
-int |
+int |
xsltSetCtxtParseOptions(xsltTransformContextPtr ctxt, int options) |
{ |
int oldopts; |
@@ -1419,9 +1431,9 @@ xsltSetCtxtParseOptions(xsltTransformContextPtr ctxt, int options) |
} |
/************************************************************************ |
- * * |
- * Output * |
- * * |
+ * * |
+ * Output * |
+ * * |
************************************************************************/ |
/** |
@@ -1512,7 +1524,7 @@ xsltSaveResultTo(xmlOutputBufferPtr buf, xmlDocPtr result, |
cur = cur->next; |
continue; |
} |
- |
+ |
do { |
cur = cur->parent; |
if (cur == NULL) |
@@ -1537,9 +1549,11 @@ xsltSaveResultTo(xmlOutputBufferPtr buf, xmlDocPtr result, |
if (omitXmlDecl != 1) { |
xmlOutputBufferWriteString(buf, "<?xml version="); |
- if (result->version != NULL) |
- xmlBufferWriteQuotedString(buf->buffer, result->version); |
- else |
+ if (result->version != NULL) { |
+ xmlOutputBufferWriteString(buf, "\""); |
+ xmlOutputBufferWriteString(buf, (const char *)result->version); |
+ xmlOutputBufferWriteString(buf, "\""); |
+ } else |
xmlOutputBufferWriteString(buf, "\"1.0\""); |
if (encoding == NULL) { |
if (result->encoding != NULL) |
@@ -1551,7 +1565,9 @@ xsltSaveResultTo(xmlOutputBufferPtr buf, xmlDocPtr result, |
} |
if (encoding != NULL) { |
xmlOutputBufferWriteString(buf, " encoding="); |
- xmlBufferWriteQuotedString(buf->buffer, (xmlChar *) encoding); |
+ xmlOutputBufferWriteString(buf, "\""); |
+ xmlOutputBufferWriteString(buf, (const char *) encoding); |
+ xmlOutputBufferWriteString(buf, "\""); |
} |
switch (standalone) { |
case 0: |
@@ -1571,13 +1587,14 @@ xsltSaveResultTo(xmlOutputBufferPtr buf, xmlDocPtr result, |
while (child != NULL) { |
xmlNodeDumpOutput(buf, result, child, 0, (indent == 1), |
(const char *) encoding); |
- if ((child->type == XML_DTD_NODE) || |
+ if (indent && ((child->type == XML_DTD_NODE) || |
((child->type == XML_COMMENT_NODE) && |
- (child->next != NULL))) |
+ (child->next != NULL)))) |
xmlOutputBufferWriteString(buf, "\n"); |
child = child->next; |
} |
- xmlOutputBufferWriteString(buf, "\n"); |
+ if (indent) |
+ xmlOutputBufferWriteString(buf, "\n"); |
} |
xmlOutputBufferFlush(buf); |
} |
@@ -1728,7 +1745,7 @@ xsltSaveResultToFd(int fd, xmlDocPtr result, xsltStylesheetPtr style) { |
* Returns 0 in case of success and -1 in case of error |
*/ |
int |
-xsltSaveResultToString(xmlChar **doc_txt_ptr, int * doc_txt_len, |
+xsltSaveResultToString(xmlChar **doc_txt_ptr, int * doc_txt_len, |
xmlDocPtr result, xsltStylesheetPtr style) { |
xmlOutputBufferPtr buf; |
const xmlChar *encoding; |
@@ -1754,6 +1771,15 @@ xsltSaveResultToString(xmlChar **doc_txt_ptr, int * doc_txt_len, |
if (buf == NULL) |
return(-1); |
xsltSaveResultTo(buf, result, style); |
+#ifdef LIBXML2_NEW_BUFFER |
+ if (buf->conv != NULL) { |
+ *doc_txt_len = xmlBufUse(buf->conv); |
+ *doc_txt_ptr = xmlStrndup(xmlBufContent(buf->conv), *doc_txt_len); |
+ } else { |
+ *doc_txt_len = xmlBufUse(buf->buffer); |
+ *doc_txt_ptr = xmlStrndup(xmlBufContent(buf->buffer), *doc_txt_len); |
+ } |
+#else |
if (buf->conv != NULL) { |
*doc_txt_len = buf->conv->use; |
*doc_txt_ptr = xmlStrndup(buf->conv->content, *doc_txt_len); |
@@ -1761,14 +1787,15 @@ xsltSaveResultToString(xmlChar **doc_txt_ptr, int * doc_txt_len, |
*doc_txt_len = buf->buffer->use; |
*doc_txt_ptr = xmlStrndup(buf->buffer->content, *doc_txt_len); |
} |
+#endif |
(void)xmlOutputBufferClose(buf); |
return 0; |
} |
/************************************************************************ |
- * * |
- * Generating profiling informations * |
- * * |
+ * * |
+ * Generating profiling informations * |
+ * * |
************************************************************************/ |
static long calibration = -1; |
@@ -1840,7 +1867,35 @@ xsltTimestamp(void) |
return (long) (seconds * XSLT_TIMESTAMP_TICS_PER_SEC); |
#else /* XSLT_WIN32_PERFORMANCE_COUNTER */ |
-#ifdef HAVE_GETTIMEOFDAY |
+#ifdef HAVE_CLOCK_GETTIME |
+# if defined(CLOCK_MONOTONIC) |
+# define XSLT_CLOCK CLOCK_MONOTONIC |
+# elif defined(CLOCK_HIGHRES) |
+# define XSLT_CLOCK CLOCK_HIGHRES |
+# else |
+# define XSLT_CLOCK CLOCK_REALTIME |
+# endif |
+ static struct timespec startup; |
+ struct timespec cur; |
+ long tics; |
+ |
+ if (calibration < 0) { |
+ clock_gettime(XSLT_CLOCK, &startup); |
+ calibration = 0; |
+ calibration = xsltCalibrateTimestamps(); |
+ clock_gettime(XSLT_CLOCK, &startup); |
+ return (0); |
+ } |
+ |
+ clock_gettime(XSLT_CLOCK, &cur); |
+ tics = (cur.tv_sec - startup.tv_sec) * XSLT_TIMESTAMP_TICS_PER_SEC; |
+ tics += (cur.tv_nsec - startup.tv_nsec) / |
+ (1000000000l / XSLT_TIMESTAMP_TICS_PER_SEC); |
+ |
+ tics -= calibration; |
+ return(tics); |
+ |
+#elif HAVE_GETTIMEOFDAY |
static struct timeval startup; |
struct timeval cur; |
long tics; |
@@ -1857,7 +1912,7 @@ xsltTimestamp(void) |
tics = (cur.tv_sec - startup.tv_sec) * XSLT_TIMESTAMP_TICS_PER_SEC; |
tics += (cur.tv_usec - startup.tv_usec) / |
(1000000l / XSLT_TIMESTAMP_TICS_PER_SEC); |
- |
+ |
tics -= calibration; |
return(tics); |
#else |
@@ -1870,6 +1925,30 @@ xsltTimestamp(void) |
#endif /* XSLT_WIN32_PERFORMANCE_COUNTER */ |
} |
+static char * |
+pretty_templ_match(xsltTemplatePtr templ) { |
+ static char dst[1001]; |
+ char *src = (char *)templ->match; |
+ int i=0,j; |
+ |
+ /* strip white spaces */ |
+ for (j=0; i<1000 && src[j]; i++,j++) { |
+ for(;src[j]==' ';j++); |
+ dst[i]=src[j]; |
+ } |
+ if(i<998 && templ->mode) { |
+ /* append [mode] */ |
+ dst[i++]='['; |
+ src=(char *)templ->mode; |
+ for (j=0; i<999 && src[j]; i++,j++) { |
+ dst[i]=src[j]; |
+ } |
+ dst[i++]=']'; |
+ } |
+ dst[i]='\0'; |
+ return dst; |
+} |
+ |
#define MAX_TEMPLATES 10000 |
/** |
@@ -1881,13 +1960,14 @@ xsltTimestamp(void) |
*/ |
void |
xsltSaveProfiling(xsltTransformContextPtr ctxt, FILE *output) { |
- int nb, i,j; |
+ int nb, i,j,k,l; |
int max; |
int total; |
long totalt; |
xsltTemplatePtr *templates; |
xsltStylesheetPtr style; |
- xsltTemplatePtr template; |
+ xsltTemplatePtr templ1,templ2; |
+ int *childt; |
if ((output == NULL) || (ctxt == NULL)) |
return; |
@@ -1902,14 +1982,14 @@ xsltSaveProfiling(xsltTransformContextPtr ctxt, FILE *output) { |
style = ctxt->style; |
while (style != NULL) { |
- template = style->templates; |
- while (template != NULL) { |
+ templ1 = style->templates; |
+ while (templ1 != NULL) { |
if (nb >= max) |
break; |
- if (template->nbCalls > 0) |
- templates[nb++] = template; |
- template = template->next; |
+ if (templ1->nbCalls > 0) |
+ templates[nb++] = templ1; |
+ templ1 = templ1->next; |
} |
style = xsltNextImport(style); |
@@ -1920,58 +2000,161 @@ xsltSaveProfiling(xsltTransformContextPtr ctxt, FILE *output) { |
if ((templates[i]->time <= templates[j]->time) || |
((templates[i]->time == templates[j]->time) && |
(templates[i]->nbCalls <= templates[j]->nbCalls))) { |
- template = templates[j]; |
+ templ1 = templates[j]; |
templates[j] = templates[i]; |
- templates[i] = template; |
+ templates[i] = templ1; |
} |
} |
} |
+ |
+ /* print flat profile */ |
+ |
fprintf(output, "%6s%20s%20s%10s Calls Tot 100us Avg\n\n", |
"number", "match", "name", "mode"); |
total = 0; |
totalt = 0; |
for (i = 0;i < nb;i++) { |
+ templ1 = templates[i]; |
fprintf(output, "%5d ", i); |
- if (templates[i]->match != NULL) { |
- if (xmlStrlen(templates[i]->match) > 20) |
- fprintf(output, "%s\n%26s", templates[i]->match, ""); |
+ if (templ1->match != NULL) { |
+ if (xmlStrlen(templ1->match) > 20) |
+ fprintf(output, "%s\n%26s", templ1->match, ""); |
else |
- fprintf(output, "%20s", templates[i]->match); |
+ fprintf(output, "%20s", templ1->match); |
} else { |
fprintf(output, "%20s", ""); |
} |
- if (templates[i]->name != NULL) { |
- if (xmlStrlen(templates[i]->name) > 20) |
- fprintf(output, "%s\n%46s", templates[i]->name, ""); |
+ if (templ1->name != NULL) { |
+ if (xmlStrlen(templ1->name) > 20) |
+ fprintf(output, "%s\n%46s", templ1->name, ""); |
else |
- fprintf(output, "%20s", templates[i]->name); |
+ fprintf(output, "%20s", templ1->name); |
} else { |
fprintf(output, "%20s", ""); |
} |
- if (templates[i]->mode != NULL) { |
- if (xmlStrlen(templates[i]->mode) > 10) |
- fprintf(output, "%s\n%56s", templates[i]->mode, ""); |
+ if (templ1->mode != NULL) { |
+ if (xmlStrlen(templ1->mode) > 10) |
+ fprintf(output, "%s\n%56s", templ1->mode, ""); |
else |
- fprintf(output, "%10s", templates[i]->mode); |
+ fprintf(output, "%10s", templ1->mode); |
} else { |
fprintf(output, "%10s", ""); |
} |
- fprintf(output, " %6d", templates[i]->nbCalls); |
- fprintf(output, " %6ld %6ld\n", templates[i]->time, |
- templates[i]->time / templates[i]->nbCalls); |
- total += templates[i]->nbCalls; |
- totalt += templates[i]->time; |
+ fprintf(output, " %6d", templ1->nbCalls); |
+ fprintf(output, " %6ld %6ld\n", templ1->time, |
+ templ1->time / templ1->nbCalls); |
+ total += templ1->nbCalls; |
+ totalt += templ1->time; |
} |
fprintf(output, "\n%30s%26s %6d %6ld\n", "Total", "", total, totalt); |
+ |
+ /* print call graph */ |
+ |
+ childt = xmlMalloc((nb + 1) * sizeof(int)); |
+ if (childt == NULL) |
+ return; |
+ |
+ /* precalculate children times */ |
+ for (i = 0; i < nb; i++) { |
+ templ1 = templates[i]; |
+ |
+ childt[i] = 0; |
+ for (k = 0; k < nb; k++) { |
+ templ2 = templates[k]; |
+ for (l = 0; l < templ2->templNr; l++) { |
+ if (templ2->templCalledTab[l] == templ1) { |
+ childt[i] +=templ2->time; |
+ } |
+ } |
+ } |
+ } |
+ childt[i] = 0; |
+ |
+ fprintf(output, "\nindex %% time self children called name\n"); |
+ |
+ for (i = 0; i < nb; i++) { |
+ char ix_str[20], timep_str[20], times_str[20], timec_str[20], called_str[20]; |
+ int t; |
+ |
+ templ1 = templates[i]; |
+ /* callers */ |
+ for (j = 0; j < templ1->templNr; j++) { |
+ templ2 = templ1->templCalledTab[j]; |
+ for (k = 0; k < nb; k++) { |
+ if (templates[k] == templ2) |
+ break; |
+ } |
+ t=templ2?templ2->time:totalt; |
+ sprintf(times_str,"%8.3f",(float)t/XSLT_TIMESTAMP_TICS_PER_SEC); |
+ sprintf(timec_str,"%8.3f",(float)childt[k]/XSLT_TIMESTAMP_TICS_PER_SEC); |
+ sprintf(called_str,"%6d/%d", |
+ templ1->templCountTab[j], /* number of times caller calls 'this' */ |
+ templ1->nbCalls); /* total number of calls to 'this' */ |
+ |
+ fprintf(output, " %-8s %-8s %-12s %s [%d]\n", |
+ times_str,timec_str,called_str, |
+ (templ2?(templ2->name?(char *)templ2->name:pretty_templ_match(templ2)):"-"),k); |
+ } |
+ /* this */ |
+ sprintf(ix_str,"[%d]",i); |
+ sprintf(timep_str,"%6.2f",(float)templ1->time*100.0/totalt); |
+ sprintf(times_str,"%8.3f",(float)templ1->time/XSLT_TIMESTAMP_TICS_PER_SEC); |
+ sprintf(timec_str,"%8.3f",(float)childt[i]/XSLT_TIMESTAMP_TICS_PER_SEC); |
+ fprintf(output, "%-5s %-6s %-8s %-8s %6d %s [%d]\n", |
+ ix_str, timep_str,times_str,timec_str, |
+ templ1->nbCalls, |
+ templ1->name?(char *)templ1->name:pretty_templ_match(templ1),i); |
+ /* callees |
+ * - go over templates[0..nb] and their templCalledTab[] |
+ * - print those where we in the the call-stack |
+ */ |
+ total = 0; |
+ for (k = 0; k < nb; k++) { |
+ templ2 = templates[k]; |
+ for (l = 0; l < templ2->templNr; l++) { |
+ if (templ2->templCalledTab[l] == templ1) { |
+ total+=templ2->templCountTab[l]; |
+ } |
+ } |
+ } |
+ for (k = 0; k < nb; k++) { |
+ templ2 = templates[k]; |
+ for (l = 0; l < templ2->templNr; l++) { |
+ if (templ2->templCalledTab[l] == templ1) { |
+ sprintf(times_str,"%8.3f",(float)templ2->time/XSLT_TIMESTAMP_TICS_PER_SEC); |
+ sprintf(timec_str,"%8.3f",(float)childt[k]/XSLT_TIMESTAMP_TICS_PER_SEC); |
+ sprintf(called_str,"%6d/%d", |
+ templ2->templCountTab[l], /* number of times 'this' calls callee */ |
+ total); /* total number of calls from 'this' */ |
+ fprintf(output, " %-8s %-8s %-12s %s [%d]\n", |
+ times_str,timec_str,called_str, |
+ templ2->name?(char *)templ2->name:pretty_templ_match(templ2),k); |
+ } |
+ } |
+ } |
+ fprintf(output, "-----------------------------------------------\n"); |
+ } |
+ |
+ fprintf(output, "\f\nIndex by function name\n"); |
+ for (i = 0; i < nb; i++) { |
+ templ1 = templates[i]; |
+ fprintf(output, "[%d] %s (%s:%d)\n", |
+ i, templ1->name?(char *)templ1->name:pretty_templ_match(templ1), |
+ templ1->style->doc->URL,templ1->elem->line); |
+ } |
+ |
+ fprintf(output, "\f\n"); |
+ xmlFree(childt); |
+ |
xmlFree(templates); |
} |
/************************************************************************ |
- * * |
- * Fetching profiling informations * |
- * * |
+ * * |
+ * Fetching profiling informations * |
+ * * |
************************************************************************/ |
/** |
@@ -2084,15 +2267,16 @@ xsltGetProfileInformation(xsltTransformContextPtr ctxt) |
} |
/************************************************************************ |
- * * |
- * Hooks for libxml2 XPath * |
- * * |
+ * * |
+ * Hooks for libxml2 XPath * |
+ * * |
************************************************************************/ |
/** |
- * xsltXPathCompile: |
+ * xsltXPathCompileFlags: |
* @style: the stylesheet |
* @str: the XPath expression |
+ * @flags: extra compilation flags to pass down to libxml2 XPath |
* |
* Compile an XPath expression |
* |
@@ -2100,7 +2284,7 @@ xsltGetProfileInformation(xsltTransformContextPtr ctxt) |
* the caller has to free the object. |
*/ |
xmlXPathCompExprPtr |
-xsltXPathCompile(xsltStylesheetPtr style, const xmlChar *str) { |
+xsltXPathCompileFlags(xsltStylesheetPtr style, const xmlChar *str, int flags) { |
xmlXPathContextPtr xpathCtxt; |
xmlXPathCompExprPtr ret; |
@@ -2132,6 +2316,8 @@ xsltXPathCompile(xsltStylesheetPtr style, const xmlChar *str) { |
if (xpathCtxt == NULL) |
return NULL; |
} |
+ xpathCtxt->flags = flags; |
+ |
/* |
* Compile the expression. |
*/ |
@@ -2152,10 +2338,25 @@ xsltXPathCompile(xsltStylesheetPtr style, const xmlChar *str) { |
return(ret); |
} |
+/** |
+ * xsltXPathCompile: |
+ * @style: the stylesheet |
+ * @str: the XPath expression |
+ * |
+ * Compile an XPath expression |
+ * |
+ * Returns the xmlXPathCompExprPtr resulting from the compilation or NULL. |
+ * the caller has to free the object. |
+ */ |
+xmlXPathCompExprPtr |
+xsltXPathCompile(xsltStylesheetPtr style, const xmlChar *str) { |
+ return(xsltXPathCompileFlags(style, str, 0)); |
+} |
+ |
/************************************************************************ |
- * * |
- * Hooks for the debugger * |
- * * |
+ * * |
+ * Hooks for the debugger * |
+ * * |
************************************************************************/ |
/* |
@@ -2183,18 +2384,18 @@ int xslDebugStatus; |
/** |
* xsltSetDebuggerStatus: |
* @value : the value to be set |
- * |
+ * |
* This function sets the value of xslDebugStatus. |
*/ |
void |
xsltSetDebuggerStatus(int value) |
{ |
- xslDebugStatus = value; |
+ xslDebugStatus = value; |
} |
/** |
- * xsltGetDebuggerStatus: |
- * |
+ * xsltGetDebuggerStatus: |
+ * |
* Get xslDebugStatus. |
* |
* Returns the value of xslDebugStatus. |
@@ -2202,16 +2403,16 @@ xsltSetDebuggerStatus(int value) |
int |
xsltGetDebuggerStatus(void) |
{ |
- return(xslDebugStatus); |
+ return(xslDebugStatus); |
} |
/** |
* xsltSetDebuggerCallbacks: |
* @no : number of callbacks |
* @block : the block of callbacks |
- * |
+ * |
* This function allow to plug a debugger into the XSLT library |
- * @block points to a block of memory containing the address of @no |
+ * @block points to a block of memory containing the address of @no |
* callback routines. |
* |
* Returns 0 in case of success and -1 in case of error |
@@ -2236,9 +2437,9 @@ xsltSetDebuggerCallbacks(int no, void *block) |
* @cur : source node being executed |
* @node : data node being processed |
* @templ : temlate that applies to node |
- * @ctxt : the xslt transform context |
- * |
- * If either cur or node are a breakpoint, or xslDebugStatus in state |
+ * @ctxt : the xslt transform context |
+ * |
+ * If either cur or node are a breakpoint, or xslDebugStatus in state |
* where debugging must occcur at this time then transfer control |
* to the xslDebugBreak function |
*/ |
@@ -2256,7 +2457,7 @@ xslHandleDebugger(xmlNodePtr cur, xmlNodePtr node, xsltTemplatePtr templ, |
* @source : the source node being processed |
* |
* Add template "call" to call stack |
- * Returns : 1 on sucess 0 otherwise an error may be printed if |
+ * Returns : 1 on sucess 0 otherwise an error may be printed if |
* WITH_XSLT_DEBUG_BREAKPOINTS is defined |
*/ |
int |