ReactOS  0.4.15-dev-440-g5f37b68
xsltutils.c
Go to the documentation of this file.
1 /*
2  * xsltutils.c: Utilities for the XSL Transformation 1.0 engine
3  *
4  * Reference:
5  * http://www.w3.org/TR/1999/REC-xslt-19991116
6  *
7  * See Copyright for the status of this software.
8  *
9  * daniel@veillard.com
10  */
11 
12 #include "precomp.h"
13 
14 #ifdef HAVE_SYS_TIME_H
15 #include <sys/time.h>
16 #endif
17 #ifdef HAVE_UNISTD_H
18 #include <unistd.h>
19 #endif
20 
21 #if defined(_WIN32) && !defined(__CYGWIN__)
22 #define XSLT_WIN32_PERFORMANCE_COUNTER
23 #endif
24 
25 /************************************************************************
26  * *
27  * Convenience function *
28  * *
29  ************************************************************************/
30 
51 const xmlChar *
53  const xmlChar *name, const xmlChar *nameSpace) {
54  xmlAttrPtr prop;
55  xmlDocPtr doc;
56  xmlNsPtr ns;
57  xmlChar *tmp;
58  const xmlChar *ret;
59 
60  if ((node == NULL) || (style == NULL) || (style->dict == NULL))
61  return(NULL);
62 
63  if (nameSpace == NULL)
64  return xmlGetProp(node, name);
65 
66  if (node->type == XML_NAMESPACE_DECL)
67  return(NULL);
68  if (node->type == XML_ELEMENT_NODE)
69  prop = node->properties;
70  else
71  prop = NULL;
72  while (prop != NULL) {
73  /*
74  * One need to have
75  * - same attribute names
76  * - and the attribute carrying that namespace
77  */
78  if ((xmlStrEqual(prop->name, name)) &&
79  (((prop->ns == NULL) && (node->ns != NULL) &&
80  (xmlStrEqual(node->ns->href, nameSpace))) ||
81  ((prop->ns != NULL) &&
82  (xmlStrEqual(prop->ns->href, nameSpace))))) {
83 
84  tmp = xmlNodeListGetString(node->doc, prop->children, 1);
85  if (tmp == NULL)
86  ret = xmlDictLookup(style->dict, BAD_CAST "", 0);
87  else {
88  ret = xmlDictLookup(style->dict, tmp, -1);
89  xmlFree(tmp);
90  }
91  return ret;
92  }
93  prop = prop->next;
94  }
95  tmp = NULL;
96  /*
97  * Check if there is a default declaration in the internal
98  * or external subsets
99  */
100  doc = node->doc;
101  if (doc != NULL) {
102  if (doc->intSubset != NULL) {
103  xmlAttributePtr attrDecl;
104 
105  attrDecl = xmlGetDtdAttrDesc(doc->intSubset, node->name, name);
106  if ((attrDecl == NULL) && (doc->extSubset != NULL))
107  attrDecl = xmlGetDtdAttrDesc(doc->extSubset, node->name, name);
108 
109  if ((attrDecl != NULL) && (attrDecl->prefix != NULL)) {
110  /*
111  * The DTD declaration only allows a prefix search
112  */
113  ns = xmlSearchNs(doc, node, attrDecl->prefix);
114  if ((ns != NULL) && (xmlStrEqual(ns->href, nameSpace)))
115  return(xmlDictLookup(style->dict,
116  attrDecl->defaultValue, -1));
117  }
118  }
119  }
120  return(NULL);
121 }
141 xmlChar *
142 xsltGetNsProp(xmlNodePtr node, const xmlChar *name, const xmlChar *nameSpace) {
143  xmlAttrPtr prop;
144  xmlDocPtr doc;
145  xmlNsPtr ns;
146 
147  if (node == NULL)
148  return(NULL);
149 
150  if (nameSpace == NULL)
151  return xmlGetProp(node, name);
152 
153  if (node->type == XML_NAMESPACE_DECL)
154  return(NULL);
155  if (node->type == XML_ELEMENT_NODE)
156  prop = node->properties;
157  else
158  prop = NULL;
159  /*
160  * TODO: Substitute xmlGetProp() for xmlGetNsProp(), since the former
161  * is not namespace-aware and will return an attribute with equal
162  * name regardless of its namespace.
163  * Example:
164  * <xsl:element foo:name="myName"/>
165  * So this would return "myName" even if an attribute @name
166  * in the XSLT was requested.
167  */
168  while (prop != NULL) {
169  /*
170  * One need to have
171  * - same attribute names
172  * - and the attribute carrying that namespace
173  */
174  if ((xmlStrEqual(prop->name, name)) &&
175  (((prop->ns == NULL) && (node->ns != NULL) &&
176  (xmlStrEqual(node->ns->href, nameSpace))) ||
177  ((prop->ns != NULL) &&
178  (xmlStrEqual(prop->ns->href, nameSpace))))) {
179  xmlChar *ret;
180 
181  ret = xmlNodeListGetString(node->doc, prop->children, 1);
182  if (ret == NULL) return(xmlStrdup((xmlChar *)""));
183  return(ret);
184  }
185  prop = prop->next;
186  }
187 
188  /*
189  * Check if there is a default declaration in the internal
190  * or external subsets
191  */
192  doc = node->doc;
193  if (doc != NULL) {
194  if (doc->intSubset != NULL) {
195  xmlAttributePtr attrDecl;
196 
197  attrDecl = xmlGetDtdAttrDesc(doc->intSubset, node->name, name);
198  if ((attrDecl == NULL) && (doc->extSubset != NULL))
199  attrDecl = xmlGetDtdAttrDesc(doc->extSubset, node->name, name);
200 
201  if ((attrDecl != NULL) && (attrDecl->prefix != NULL)) {
202  /*
203  * The DTD declaration only allows a prefix search
204  */
205  ns = xmlSearchNs(doc, node, attrDecl->prefix);
206  if ((ns != NULL) && (xmlStrEqual(ns->href, nameSpace)))
207  return(xmlStrdup(attrDecl->defaultValue));
208  }
209  }
210  }
211  return(NULL);
212 }
213 
226 int
227 xsltGetUTF8Char(const unsigned char *utf, int *len) {
228  unsigned int c;
229 
230  if (utf == NULL)
231  goto error;
232  if (len == NULL)
233  goto error;
234  if (*len < 1)
235  goto error;
236 
237  c = utf[0];
238  if (c & 0x80) {
239  if (*len < 2)
240  goto error;
241  if ((utf[1] & 0xc0) != 0x80)
242  goto error;
243  if ((c & 0xe0) == 0xe0) {
244  if (*len < 3)
245  goto error;
246  if ((utf[2] & 0xc0) != 0x80)
247  goto error;
248  if ((c & 0xf0) == 0xf0) {
249  if (*len < 4)
250  goto error;
251  if ((c & 0xf8) != 0xf0 || (utf[3] & 0xc0) != 0x80)
252  goto error;
253  *len = 4;
254  /* 4-byte code */
255  c = (utf[0] & 0x7) << 18;
256  c |= (utf[1] & 0x3f) << 12;
257  c |= (utf[2] & 0x3f) << 6;
258  c |= utf[3] & 0x3f;
259  } else {
260  /* 3-byte code */
261  *len = 3;
262  c = (utf[0] & 0xf) << 12;
263  c |= (utf[1] & 0x3f) << 6;
264  c |= utf[2] & 0x3f;
265  }
266  } else {
267  /* 2-byte code */
268  *len = 2;
269  c = (utf[0] & 0x1f) << 6;
270  c |= utf[1] & 0x3f;
271  }
272  } else {
273  /* 1-byte code */
274  *len = 1;
275  }
276  return(c);
277 
278 error:
279  if (len != NULL)
280  *len = 0;
281  return(-1);
282 }
283 
284 #ifdef XSLT_REFACTORED
285 
297 int
298 xsltPointerListAddSize(xsltPointerListPtr list,
299  void *item,
300  int initialSize)
301 {
302  if (list->items == NULL) {
303  if (initialSize <= 0)
304  initialSize = 1;
305  list->items = (void **) xmlMalloc(
306  initialSize * sizeof(void *));
307  if (list->items == NULL) {
309  "xsltPointerListAddSize: memory allocation failure.\n");
310  return(-1);
311  }
312  list->number = 0;
313  list->size = initialSize;
314  } else if (list->size <= list->number) {
315  list->size *= 2;
316  list->items = (void **) xmlRealloc(list->items,
317  list->size * sizeof(void *));
318  if (list->items == NULL) {
320  "xsltPointerListAddSize: memory re-allocation failure.\n");
321  list->size = 0;
322  return(-1);
323  }
324  }
325  list->items[list->number++] = item;
326  return(0);
327 }
328 
337 xsltPointerListPtr
338 xsltPointerListCreate(int initialSize)
339 {
340  xsltPointerListPtr ret;
341 
342  ret = xmlMalloc(sizeof(xsltPointerList));
343  if (ret == NULL) {
345  "xsltPointerListCreate: memory allocation failure.\n");
346  return (NULL);
347  }
348  memset(ret, 0, sizeof(xsltPointerList));
349  if (initialSize > 0) {
350  xsltPointerListAddSize(ret, NULL, initialSize);
351  ret->number = 0;
352  }
353  return (ret);
354 }
355 
363 void
364 xsltPointerListFree(xsltPointerListPtr list)
365 {
366  if (list == NULL)
367  return;
368  if (list->items != NULL)
369  xmlFree(list->items);
370  xmlFree(list);
371 }
372 
380 void
381 xsltPointerListClear(xsltPointerListPtr list)
382 {
383  if (list->items != NULL) {
384  xmlFree(list->items);
385  list->items = NULL;
386  }
387  list->number = 0;
388  list->size = 0;
389 }
390 
391 #endif /* XSLT_REFACTORED */
392 
393 /************************************************************************
394  * *
395  * Handling of XSLT stylesheets messages *
396  * *
397  ************************************************************************/
398 
407 void
410  void *errctx = xsltGenericErrorContext;
411  xmlChar *prop, *message;
412  int terminate = 0;
413 
414  if ((ctxt == NULL) || (inst == NULL))
415  return;
416 
417  if (ctxt->error != NULL) {
418  error = ctxt->error;
419  errctx = ctxt->errctx;
420  }
421 
422  prop = xmlGetNsProp(inst, (const xmlChar *)"terminate", NULL);
423  if (prop != NULL) {
424  if (xmlStrEqual(prop, (const xmlChar *)"yes")) {
425  terminate = 1;
426  } else if (xmlStrEqual(prop, (const xmlChar *)"no")) {
427  terminate = 0;
428  } else {
429  xsltTransformError(ctxt, NULL, inst,
430  "xsl:message : terminate expecting 'yes' or 'no'\n");
431  }
432  xmlFree(prop);
433  }
434  message = xsltEvalTemplateString(ctxt, node, inst);
435  if (message != NULL) {
436  int len = xmlStrlen(message);
437 
438  error(errctx, "%s", (const char *)message);
439  if ((len > 0) && (message[len - 1] != '\n'))
440  error(errctx, "\n");
441  xmlFree(message);
442  }
443  if (terminate)
444  ctxt->state = XSLT_STATE_STOPPED;
445 }
446 
447 /************************************************************************
448  * *
449  * Handling of out of context errors *
450  * *
451  ************************************************************************/
452 
453 #define XSLT_GET_VAR_STR(msg, str) { \
454  int size; \
455  int chars; \
456  char *larger; \
457  va_list ap; \
458  \
459  str = (char *) xmlMalloc(150); \
460  if (str == NULL) \
461  return; \
462  \
463  size = 150; \
464  \
465  while (size < 64000) { \
466  va_start(ap, msg); \
467  chars = vsnprintf(str, size, msg, ap); \
468  va_end(ap); \
469  if ((chars > -1) && (chars < size)) \
470  break; \
471  if (chars > -1) \
472  size += chars + 1; \
473  else \
474  size += 100; \
475  if ((larger = (char *) xmlRealloc(str, size)) == NULL) {\
476  xmlFree(str); \
477  return; \
478  } \
479  str = larger; \
480  } \
481 }
482 
490 static void LIBXSLT_ATTR_FORMAT(2,3)
491 xsltGenericErrorDefaultFunc(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) {
492  va_list args;
493 
495  xsltGenericErrorContext = (void *) stderr;
496 
497  va_start(args, msg);
499  va_end(args);
500 }
501 
502 xmlGenericErrorFunc xsltGenericError = xsltGenericErrorDefaultFunc;
504 
505 
519 void
522  if (handler != NULL)
524  else
525  xsltGenericError = xsltGenericErrorDefaultFunc;
526 }
527 
536 static void LIBXSLT_ATTR_FORMAT(2,3)
537 xsltGenericDebugDefaultFunc(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) {
538  va_list args;
539 
541  return;
542 
543  va_start(args, msg);
545  va_end(args);
546 }
547 
548 xmlGenericErrorFunc xsltGenericDebug = xsltGenericDebugDefaultFunc;
550 
551 
565 void
568  if (handler != NULL)
570  else
571  xsltGenericDebug = xsltGenericDebugDefaultFunc;
572 }
573 
582 void
585  int line = 0;
586  const xmlChar *file = NULL;
587  const xmlChar *name = NULL;
588  const char *type = "error";
590  void *errctx = xsltGenericErrorContext;
591 
592  if (ctxt != NULL) {
593  if (ctxt->state == XSLT_STATE_OK)
594  ctxt->state = XSLT_STATE_ERROR;
595  if (ctxt->error != NULL) {
596  error = ctxt->error;
597  errctx = ctxt->errctx;
598  }
599  }
600  if ((node == NULL) && (ctxt != NULL))
601  node = ctxt->inst;
602 
603  if (node != NULL) {
604  if ((node->type == XML_DOCUMENT_NODE) ||
605  (node->type == XML_HTML_DOCUMENT_NODE)) {
606  xmlDocPtr doc = (xmlDocPtr) node;
607 
608  file = doc->URL;
609  } else {
611  if ((node->doc != NULL) && (node->doc->URL != NULL))
612  file = node->doc->URL;
613  if (node->name != NULL)
614  name = node->name;
615  }
616  }
617 
618  if (ctxt != NULL)
619  type = "runtime error";
620  else if (style != NULL) {
621 #ifdef XSLT_REFACTORED
622  if (XSLT_CCTXT(style)->errSeverity == XSLT_ERROR_SEVERITY_WARNING)
623  type = "compilation warning";
624  else
625  type = "compilation error";
626 #else
627  type = "compilation error";
628 #endif
629  }
630 
631  if ((file != NULL) && (line != 0) && (name != NULL))
632  error(errctx, "%s: file %s line %d element %s\n",
633  type, file, line, name);
634  else if ((file != NULL) && (name != NULL))
635  error(errctx, "%s: file %s element %s\n", type, file, name);
636  else if ((file != NULL) && (line != 0))
637  error(errctx, "%s: file %s line %d\n", type, file, line);
638  else if (file != NULL)
639  error(errctx, "%s: file %s\n", type, file);
640  else if (name != NULL)
641  error(errctx, "%s: element %s\n", type, name);
642  else
643  error(errctx, "%s\n", type);
644 }
645 
658 void
660  void *ctx, xmlGenericErrorFunc handler)
661 {
662  ctxt->error = handler;
663  ctxt->errctx = ctx;
664 }
665 
677 void
681  const char *msg, ...) {
683  void *errctx = xsltGenericErrorContext;
684  char * str;
685 
686  if (ctxt != NULL) {
687  if (ctxt->state == XSLT_STATE_OK)
688  ctxt->state = XSLT_STATE_ERROR;
689  if (ctxt->error != NULL) {
690  error = ctxt->error;
691  errctx = ctxt->errctx;
692  }
693  }
694  if ((node == NULL) && (ctxt != NULL))
695  node = ctxt->inst;
698  error(errctx, "%s", str);
699  if (str != NULL)
700  xmlFree(str);
701 }
702 
703 /************************************************************************
704  * *
705  * QNames *
706  * *
707  ************************************************************************/
708 
719 const xmlChar *
720 xsltSplitQName(xmlDictPtr dict, const xmlChar *name, const xmlChar **prefix) {
721  int len = 0;
722  const xmlChar *ret = NULL;
723 
724  *prefix = NULL;
725  if ((name == NULL) || (dict == NULL)) return(NULL);
726  if (name[0] == ':')
727  return(xmlDictLookup(dict, name, -1));
728  while ((name[len] != 0) && (name[len] != ':')) len++;
729  if (name[len] == 0) return(xmlDictLookup(dict, name, -1));
730  *prefix = xmlDictLookup(dict, name, len);
731  ret = xmlDictLookup(dict, &name[len + 1], -1);
732  return(ret);
733 }
734 
752 const xmlChar *
754 {
755  int len = 0;
756  xmlChar *qname;
757  xmlNsPtr ns;
758 
759  if (name == NULL)
760  return(NULL);
761  qname = *name;
762  if ((qname == NULL) || (*qname == 0))
763  return(NULL);
764  if (node == NULL) {
766  "QName: no element for namespace lookup %s\n",
767  qname);
768  xmlFree(qname);
769  *name = NULL;
770  return(NULL);
771  }
772 
773  /* nasty but valid */
774  if (qname[0] == ':')
775  return(NULL);
776 
777  /*
778  * we are not trying to validate but just to cut, and yes it will
779  * work even if this is a set of UTF-8 encoded chars
780  */
781  while ((qname[len] != 0) && (qname[len] != ':'))
782  len++;
783 
784  if (qname[len] == 0)
785  return(NULL);
786 
787  /*
788  * handle xml: separately, this one is magical
789  */
790  if ((qname[0] == 'x') && (qname[1] == 'm') &&
791  (qname[2] == 'l') && (qname[3] == ':')) {
792  if (qname[4] == 0)
793  return(NULL);
794  *name = xmlStrdup(&qname[4]);
795  xmlFree(qname);
796  return(XML_XML_NAMESPACE);
797  }
798 
799  qname[len] = 0;
800  ns = xmlSearchNs(node->doc, node, qname);
801  if (ns == NULL) {
803  "%s:%s : no namespace bound to prefix %s\n",
804  qname, &qname[len + 1], qname);
805  *name = NULL;
806  xmlFree(qname);
807  return(NULL);
808  }
809  *name = xmlStrdup(&qname[len + 1]);
810  xmlFree(qname);
811  return(ns->href);
812 }
813 
826 const xmlChar *
828  const xmlChar **name) {
829  int len = 0;
830  xmlChar *qname;
831  xmlNsPtr ns;
832 
833  if (name == NULL)
834  return(NULL);
835  qname = (xmlChar *)*name;
836  if ((qname == NULL) || (*qname == 0))
837  return(NULL);
838  if (node == NULL) {
840  "QName: no element for namespace lookup %s\n",
841  qname);
842  *name = NULL;
843  return(NULL);
844  }
845 
846  /*
847  * we are not trying to validate but just to cut, and yes it will
848  * work even if this is a set of UTF-8 encoded chars
849  */
850  while ((qname[len] != 0) && (qname[len] != ':'))
851  len++;
852 
853  if (qname[len] == 0)
854  return(NULL);
855 
856  /*
857  * handle xml: separately, this one is magical
858  */
859  if ((qname[0] == 'x') && (qname[1] == 'm') &&
860  (qname[2] == 'l') && (qname[3] == ':')) {
861  if (qname[4] == 0)
862  return(NULL);
863  *name = xmlDictLookup(style->dict, &qname[4], -1);
864  return(XML_XML_NAMESPACE);
865  }
866 
867  qname = xmlStrndup(*name, len);
868  ns = xmlSearchNs(node->doc, node, qname);
869  if (ns == NULL) {
870  if (style) {
872  "No namespace bound to prefix '%s'.\n",
873  qname);
874  style->errors++;
875  } else {
877  "%s : no namespace bound to prefix %s\n",
878  *name, qname);
879  }
880  *name = NULL;
881  xmlFree(qname);
882  return(NULL);
883  }
884  *name = xmlDictLookup(style->dict, (*name)+len+1, -1);
885  xmlFree(qname);
886  return(ns->href);
887 }
888 
889 /************************************************************************
890  * *
891  * Sorting *
892  * *
893  ************************************************************************/
894 
902 void
904  int i, j;
905  int len, tst;
907 
908  if (list == NULL)
909  return;
910  len = list->nodeNr;
911  if (len <= 1)
912  return;
913  /* TODO: sort is really not optimized, does it needs to ? */
914  for (i = 0;i < len -1;i++) {
915  for (j = i + 1; j < len; j++) {
916  tst = xmlXPathCmpNodes(list->nodeTab[i], list->nodeTab[j]);
917  if (tst == -1) {
918  node = list->nodeTab[i];
919  list->nodeTab[i] = list->nodeTab[j];
920  list->nodeTab[j] = node;
921  }
922  }
923  }
924 }
925 
936 xmlXPathObjectPtr *
938 #ifdef XSLT_REFACTORED
939  xsltStyleItemSortPtr comp;
940 #else
941  xsltStylePreCompPtr comp;
942 #endif
943  xmlXPathObjectPtr *results = NULL;
944  xmlNodeSetPtr list = NULL;
945  xmlXPathObjectPtr res;
946  int len = 0;
947  int i;
948  xmlNodePtr oldNode;
949  xmlNodePtr oldInst;
950  int oldPos, oldSize ;
951  int oldNsNr;
952  xmlNsPtr *oldNamespaces;
953 
954  comp = sort->psvi;
955  if (comp == NULL) {
957  "xsl:sort : compilation failed\n");
958  return(NULL);
959  }
960 
961  if ((comp->select == NULL) || (comp->comp == NULL))
962  return(NULL);
963 
964  list = ctxt->nodeList;
965  if ((list == NULL) || (list->nodeNr <= 1))
966  return(NULL);
967 
968  len = list->nodeNr;
969 
970  /* TODO: xsl:sort lang attribute */
971  /* TODO: xsl:sort case-order attribute */
972 
973 
974  results = xmlMalloc(len * sizeof(xmlXPathObjectPtr));
975  if (results == NULL) {
977  "xsltComputeSortResult: memory allocation failure\n");
978  return(NULL);
979  }
980 
981  oldNode = ctxt->node;
982  oldInst = ctxt->inst;
983  oldPos = ctxt->xpathCtxt->proximityPosition;
984  oldSize = ctxt->xpathCtxt->contextSize;
985  oldNsNr = ctxt->xpathCtxt->nsNr;
986  oldNamespaces = ctxt->xpathCtxt->namespaces;
987  for (i = 0;i < len;i++) {
988  ctxt->inst = sort;
989  ctxt->xpathCtxt->contextSize = len;
990  ctxt->xpathCtxt->proximityPosition = i + 1;
991  ctxt->node = list->nodeTab[i];
992  ctxt->xpathCtxt->node = ctxt->node;
993 #ifdef XSLT_REFACTORED
994  if (comp->inScopeNs != NULL) {
995  ctxt->xpathCtxt->namespaces = comp->inScopeNs->list;
996  ctxt->xpathCtxt->nsNr = comp->inScopeNs->xpathNumber;
997  } else {
998  ctxt->xpathCtxt->namespaces = NULL;
999  ctxt->xpathCtxt->nsNr = 0;
1000  }
1001 #else
1002  ctxt->xpathCtxt->namespaces = comp->nsList;
1003  ctxt->xpathCtxt->nsNr = comp->nsNr;
1004 #endif
1005  res = xmlXPathCompiledEval(comp->comp, ctxt->xpathCtxt);
1006  if (res != NULL) {
1007  if (res->type != XPATH_STRING)
1008  res = xmlXPathConvertString(res);
1009  if (comp->number)
1010  res = xmlXPathConvertNumber(res);
1011  res->index = i; /* Save original pos for dupl resolv */
1012  if (comp->number) {
1013  if (res->type == XPATH_NUMBER) {
1014  results[i] = res;
1015  } else {
1016 #ifdef WITH_XSLT_DEBUG_PROCESS
1018  "xsltComputeSortResult: select didn't evaluate to a number\n");
1019 #endif
1020  results[i] = NULL;
1021  }
1022  } else {
1023  if (res->type == XPATH_STRING) {
1024  if (comp->locale != (xsltLocale)0) {
1025  xmlChar *str = res->stringval;
1026  res->stringval = (xmlChar *) xsltStrxfrm(comp->locale, str);
1027  xmlFree(str);
1028  }
1029 
1030  results[i] = res;
1031  } else {
1032 #ifdef WITH_XSLT_DEBUG_PROCESS
1034  "xsltComputeSortResult: select didn't evaluate to a string\n");
1035 #endif
1036  results[i] = NULL;
1037  }
1038  }
1039  } else {
1040  ctxt->state = XSLT_STATE_STOPPED;
1041  results[i] = NULL;
1042  }
1043  }
1044  ctxt->node = oldNode;
1045  ctxt->inst = oldInst;
1046  ctxt->xpathCtxt->contextSize = oldSize;
1047  ctxt->xpathCtxt->proximityPosition = oldPos;
1048  ctxt->xpathCtxt->nsNr = oldNsNr;
1049  ctxt->xpathCtxt->namespaces = oldNamespaces;
1050 
1051  return(results);
1052 }
1053 
1063 void
1065  int nbsorts) {
1066 #ifdef XSLT_REFACTORED
1067  xsltStyleItemSortPtr comp;
1068 #else
1069  xsltStylePreCompPtr comp;
1070 #endif
1071  xmlXPathObjectPtr *resultsTab[XSLT_MAX_SORT];
1072  xmlXPathObjectPtr *results = NULL, *res;
1073  xmlNodeSetPtr list = NULL;
1074  int descending, number, desc, numb;
1075  int len = 0;
1076  int i, j, incr;
1077  int tst;
1078  int depth;
1079  xmlNodePtr node;
1080  xmlXPathObjectPtr tmp;
1081  int tempstype[XSLT_MAX_SORT], temporder[XSLT_MAX_SORT];
1082 
1083  if ((ctxt == NULL) || (sorts == NULL) || (nbsorts <= 0) ||
1084  (nbsorts >= XSLT_MAX_SORT))
1085  return;
1086  if (sorts[0] == NULL)
1087  return;
1088  comp = sorts[0]->psvi;
1089  if (comp == NULL)
1090  return;
1091 
1092  list = ctxt->nodeList;
1093  if ((list == NULL) || (list->nodeNr <= 1))
1094  return; /* nothing to do */
1095 
1096  for (j = 0; j < nbsorts; j++) {
1097  comp = sorts[j]->psvi;
1098  tempstype[j] = 0;
1099  if ((comp->stype == NULL) && (comp->has_stype != 0)) {
1100  comp->stype =
1101  xsltEvalAttrValueTemplate(ctxt, sorts[j],
1102  (const xmlChar *) "data-type",
1103  XSLT_NAMESPACE);
1104  if (comp->stype != NULL) {
1105  tempstype[j] = 1;
1106  if (xmlStrEqual(comp->stype, (const xmlChar *) "text"))
1107  comp->number = 0;
1108  else if (xmlStrEqual(comp->stype, (const xmlChar *) "number"))
1109  comp->number = 1;
1110  else {
1111  xsltTransformError(ctxt, NULL, sorts[j],
1112  "xsltDoSortFunction: no support for data-type = %s\n",
1113  comp->stype);
1114  comp->number = 0; /* use default */
1115  }
1116  }
1117  }
1118  temporder[j] = 0;
1119  if ((comp->order == NULL) && (comp->has_order != 0)) {
1120  comp->order = xsltEvalAttrValueTemplate(ctxt, sorts[j],
1121  (const xmlChar *) "order",
1122  XSLT_NAMESPACE);
1123  if (comp->order != NULL) {
1124  temporder[j] = 1;
1125  if (xmlStrEqual(comp->order, (const xmlChar *) "ascending"))
1126  comp->descending = 0;
1127  else if (xmlStrEqual(comp->order,
1128  (const xmlChar *) "descending"))
1129  comp->descending = 1;
1130  else {
1131  xsltTransformError(ctxt, NULL, sorts[j],
1132  "xsltDoSortFunction: invalid value %s for order\n",
1133  comp->order);
1134  comp->descending = 0; /* use default */
1135  }
1136  }
1137  }
1138  }
1139 
1140  len = list->nodeNr;
1141 
1142  resultsTab[0] = xsltComputeSortResult(ctxt, sorts[0]);
1143  for (i = 1;i < XSLT_MAX_SORT;i++)
1144  resultsTab[i] = NULL;
1145 
1146  results = resultsTab[0];
1147 
1148  comp = sorts[0]->psvi;
1149  descending = comp->descending;
1150  number = comp->number;
1151  if (results == NULL)
1152  return;
1153 
1154  /* Shell's sort of node-set */
1155  for (incr = len / 2; incr > 0; incr /= 2) {
1156  for (i = incr; i < len; i++) {
1157  j = i - incr;
1158  if (results[i] == NULL)
1159  continue;
1160 
1161  while (j >= 0) {
1162  if (results[j] == NULL)
1163  tst = 1;
1164  else {
1165  if (number) {
1166  /* We make NaN smaller than number in accordance
1167  with XSLT spec */
1168  if (xmlXPathIsNaN(results[j]->floatval)) {
1169  if (xmlXPathIsNaN(results[j + incr]->floatval))
1170  tst = 0;
1171  else
1172  tst = -1;
1173  } else if (xmlXPathIsNaN(results[j + incr]->floatval))
1174  tst = 1;
1175  else if (results[j]->floatval ==
1176  results[j + incr]->floatval)
1177  tst = 0;
1178  else if (results[j]->floatval >
1179  results[j + incr]->floatval)
1180  tst = 1;
1181  else tst = -1;
1182  } else if(comp->locale != (xsltLocale)0) {
1183  tst = xsltLocaleStrcmp(
1184  comp->locale,
1185  (xsltLocaleChar *) results[j]->stringval,
1186  (xsltLocaleChar *) results[j + incr]->stringval);
1187  } else {
1188  tst = xmlStrcmp(results[j]->stringval,
1189  results[j + incr]->stringval);
1190  }
1191  if (descending)
1192  tst = -tst;
1193  }
1194  if (tst == 0) {
1195  /*
1196  * Okay we need to use multi level sorts
1197  */
1198  depth = 1;
1199  while (depth < nbsorts) {
1200  if (sorts[depth] == NULL)
1201  break;
1202  comp = sorts[depth]->psvi;
1203  if (comp == NULL)
1204  break;
1205  desc = comp->descending;
1206  numb = comp->number;
1207 
1208  /*
1209  * Compute the result of the next level for the
1210  * full set, this might be optimized ... or not
1211  */
1212  if (resultsTab[depth] == NULL)
1213  resultsTab[depth] = xsltComputeSortResult(ctxt,
1214  sorts[depth]);
1215  res = resultsTab[depth];
1216  if (res == NULL)
1217  break;
1218  if (res[j] == NULL) {
1219  if (res[j+incr] != NULL)
1220  tst = 1;
1221  } else if (res[j+incr] == NULL) {
1222  tst = -1;
1223  } else {
1224  if (numb) {
1225  /* We make NaN smaller than number in
1226  accordance with XSLT spec */
1227  if (xmlXPathIsNaN(res[j]->floatval)) {
1228  if (xmlXPathIsNaN(res[j +
1229  incr]->floatval))
1230  tst = 0;
1231  else
1232  tst = -1;
1233  } else if (xmlXPathIsNaN(res[j + incr]->
1234  floatval))
1235  tst = 1;
1236  else if (res[j]->floatval == res[j + incr]->
1237  floatval)
1238  tst = 0;
1239  else if (res[j]->floatval >
1240  res[j + incr]->floatval)
1241  tst = 1;
1242  else tst = -1;
1243  } else if(comp->locale != (xsltLocale)0) {
1244  tst = xsltLocaleStrcmp(
1245  comp->locale,
1246  (xsltLocaleChar *) res[j]->stringval,
1247  (xsltLocaleChar *) res[j + incr]->stringval);
1248  } else {
1249  tst = xmlStrcmp(res[j]->stringval,
1250  res[j + incr]->stringval);
1251  }
1252  if (desc)
1253  tst = -tst;
1254  }
1255 
1256  /*
1257  * if we still can't differenciate at this level
1258  * try one level deeper.
1259  */
1260  if (tst != 0)
1261  break;
1262  depth++;
1263  }
1264  }
1265  if (tst == 0) {
1266  tst = results[j]->index > results[j + incr]->index;
1267  }
1268  if (tst > 0) {
1269  tmp = results[j];
1270  results[j] = results[j + incr];
1271  results[j + incr] = tmp;
1272  node = list->nodeTab[j];
1273  list->nodeTab[j] = list->nodeTab[j + incr];
1274  list->nodeTab[j + incr] = node;
1275  depth = 1;
1276  while (depth < nbsorts) {
1277  if (sorts[depth] == NULL)
1278  break;
1279  if (resultsTab[depth] == NULL)
1280  break;
1281  res = resultsTab[depth];
1282  tmp = res[j];
1283  res[j] = res[j + incr];
1284  res[j + incr] = tmp;
1285  depth++;
1286  }
1287  j -= incr;
1288  } else
1289  break;
1290  }
1291  }
1292  }
1293 
1294  for (j = 0; j < nbsorts; j++) {
1295  comp = sorts[j]->psvi;
1296  if (tempstype[j] == 1) {
1297  /* The data-type needs to be recomputed each time */
1298  xmlFree((void *)(comp->stype));
1299  comp->stype = NULL;
1300  }
1301  if (temporder[j] == 1) {
1302  /* The order needs to be recomputed each time */
1303  xmlFree((void *)(comp->order));
1304  comp->order = NULL;
1305  }
1306  if (resultsTab[j] != NULL) {
1307  for (i = 0;i < len;i++)
1308  xmlXPathFreeObject(resultsTab[j][i]);
1309  xmlFree(resultsTab[j]);
1310  }
1311  }
1312 }
1313 
1314 
1316 
1331 void
1333  int nbsorts)
1334 {
1335  if (ctxt->sortfunc != NULL)
1336  (ctxt->sortfunc)(ctxt, sorts, nbsorts);
1337  else if (xsltSortFunction != NULL)
1338  xsltSortFunction(ctxt, sorts, nbsorts);
1339 }
1340 
1348 void
1350  if (handler != NULL)
1352  else
1354 }
1355 
1366 void
1368  ctxt->sortfunc = handler;
1369 }
1370 
1371 /************************************************************************
1372  * *
1373  * Parsing options *
1374  * *
1375  ************************************************************************/
1376 
1387 int
1389 {
1390  int oldopts;
1391 
1392  if (ctxt == NULL)
1393  return(-1);
1394  oldopts = ctxt->parserOptions;
1395  if (ctxt->xinclude)
1396  oldopts |= XML_PARSE_XINCLUDE;
1397  ctxt->parserOptions = options;
1399  ctxt->xinclude = 1;
1400  else
1401  ctxt->xinclude = 0;
1402  return(oldopts);
1403 }
1404 
1405 /************************************************************************
1406  * *
1407  * Output *
1408  * *
1409  ************************************************************************/
1410 
1422 int
1425  const xmlChar *encoding;
1426  int base;
1427  const xmlChar *method;
1428  int indent;
1429 
1430  if ((buf == NULL) || (result == NULL) || (style == NULL))
1431  return(-1);
1432  if ((result->children == NULL) ||
1433  ((result->children->type == XML_DTD_NODE) &&
1434  (result->children->next == NULL)))
1435  return(0);
1436 
1437  if ((style->methodURI != NULL) &&
1438  ((style->method == NULL) ||
1439  (!xmlStrEqual(style->method, (const xmlChar *) "xhtml")))) {
1441  "xsltSaveResultTo : unknown output method\n");
1442  return(-1);
1443  }
1444 
1445  base = buf->written;
1446 
1450 
1451  if ((method == NULL) && (result->type == XML_HTML_DOCUMENT_NODE))
1452  method = (const xmlChar *) "html";
1453 
1454  if ((method != NULL) &&
1455  (xmlStrEqual(method, (const xmlChar *) "html"))) {
1456  if (encoding != NULL) {
1457  htmlSetMetaEncoding(result, (const xmlChar *) encoding);
1458  } else {
1459  htmlSetMetaEncoding(result, (const xmlChar *) "UTF-8");
1460  }
1461  if (indent == -1)
1462  indent = 1;
1463  htmlDocContentDumpFormatOutput(buf, result, (const char *) encoding,
1464  indent);
1465  xmlOutputBufferFlush(buf);
1466  } else if ((method != NULL) &&
1467  (xmlStrEqual(method, (const xmlChar *) "xhtml"))) {
1468  if (encoding != NULL) {
1469  htmlSetMetaEncoding(result, (const xmlChar *) encoding);
1470  } else {
1471  htmlSetMetaEncoding(result, (const xmlChar *) "UTF-8");
1472  }
1473  htmlDocContentDumpOutput(buf, result, (const char *) encoding);
1474  xmlOutputBufferFlush(buf);
1475  } else if ((method != NULL) &&
1476  (xmlStrEqual(method, (const xmlChar *) "text"))) {
1477  xmlNodePtr cur;
1478 
1479  cur = result->children;
1480  while (cur != NULL) {
1481  if (cur->type == XML_TEXT_NODE)
1482  xmlOutputBufferWriteString(buf, (const char *) cur->content);
1483 
1484  /*
1485  * Skip to next node
1486  */
1487  if (cur->children != NULL) {
1488  if ((cur->children->type != XML_ENTITY_DECL) &&
1489  (cur->children->type != XML_ENTITY_REF_NODE) &&
1490  (cur->children->type != XML_ENTITY_NODE)) {
1491  cur = cur->children;
1492  continue;
1493  }
1494  }
1495  if (cur->next != NULL) {
1496  cur = cur->next;
1497  continue;
1498  }
1499 
1500  do {
1501  cur = cur->parent;
1502  if (cur == NULL)
1503  break;
1504  if (cur == (xmlNodePtr) style->doc) {
1505  cur = NULL;
1506  break;
1507  }
1508  if (cur->next != NULL) {
1509  cur = cur->next;
1510  break;
1511  }
1512  } while (cur != NULL);
1513  }
1514  xmlOutputBufferFlush(buf);
1515  } else {
1516  int omitXmlDecl;
1517  int standalone;
1518 
1519  XSLT_GET_IMPORT_INT(omitXmlDecl, style, omitXmlDeclaration);
1520  XSLT_GET_IMPORT_INT(standalone, style, standalone);
1521 
1522  if (omitXmlDecl != 1) {
1523  xmlOutputBufferWriteString(buf, "<?xml version=");
1524  if (result->version != NULL) {
1525  xmlOutputBufferWriteString(buf, "\"");
1526  xmlOutputBufferWriteString(buf, (const char *)result->version);
1527  xmlOutputBufferWriteString(buf, "\"");
1528  } else
1529  xmlOutputBufferWriteString(buf, "\"1.0\"");
1530  if (encoding == NULL) {
1531  if (result->encoding != NULL)
1532  encoding = result->encoding;
1533  else if (result->charset != XML_CHAR_ENCODING_UTF8)
1534  encoding = (const xmlChar *)
1536  result->charset);
1537  }
1538  if (encoding != NULL) {
1539  xmlOutputBufferWriteString(buf, " encoding=");
1540  xmlOutputBufferWriteString(buf, "\"");
1541  xmlOutputBufferWriteString(buf, (const char *) encoding);
1542  xmlOutputBufferWriteString(buf, "\"");
1543  }
1544  switch (standalone) {
1545  case 0:
1546  xmlOutputBufferWriteString(buf, " standalone=\"no\"");
1547  break;
1548  case 1:
1549  xmlOutputBufferWriteString(buf, " standalone=\"yes\"");
1550  break;
1551  default:
1552  break;
1553  }
1554  xmlOutputBufferWriteString(buf, "?>\n");
1555  }
1556  if (result->children != NULL) {
1557  xmlNodePtr children = result->children;
1558  xmlNodePtr child = children;
1559 
1560  /*
1561  * Hack to avoid quadratic behavior when scanning
1562  * result->children in xmlGetIntSubset called by
1563  * xmlNodeDumpOutput.
1564  */
1565  result->children = NULL;
1566 
1567  while (child != NULL) {
1568  xmlNodeDumpOutput(buf, result, child, 0, (indent == 1),
1569  (const char *) encoding);
1570  if (indent && ((child->type == XML_DTD_NODE) ||
1571  ((child->type == XML_COMMENT_NODE) &&
1572  (child->next != NULL))))
1573  xmlOutputBufferWriteString(buf, "\n");
1574  child = child->next;
1575  }
1576  if (indent)
1577  xmlOutputBufferWriteString(buf, "\n");
1578 
1579  result->children = children;
1580  }
1581  xmlOutputBufferFlush(buf);
1582  }
1583  return(buf->written - base);
1584 }
1585 
1598 int
1602  const xmlChar *encoding;
1603  int ret;
1604 
1605  if ((URL == NULL) || (result == NULL) || (style == NULL))
1606  return(-1);
1607  if (result->children == NULL)
1608  return(0);
1609 
1611  if (encoding != NULL) {
1612  xmlCharEncodingHandlerPtr encoder;
1613 
1614  encoder = xmlFindCharEncodingHandler((char *)encoding);
1615  if ((encoder != NULL) &&
1616  (xmlStrEqual((const xmlChar *)encoder->name,
1617  (const xmlChar *) "UTF-8")))
1618  encoder = NULL;
1619  buf = xmlOutputBufferCreateFilename(URL, encoder, compression);
1620  } else {
1621  buf = xmlOutputBufferCreateFilename(URL, NULL, compression);
1622  }
1623  if (buf == NULL)
1624  return(-1);
1626  ret = xmlOutputBufferClose(buf);
1627  return(ret);
1628 }
1629 
1642 int
1645  const xmlChar *encoding;
1646  int ret;
1647 
1648  if ((file == NULL) || (result == NULL) || (style == NULL))
1649  return(-1);
1650  if (result->children == NULL)
1651  return(0);
1652 
1654  if (encoding != NULL) {
1655  xmlCharEncodingHandlerPtr encoder;
1656 
1657  encoder = xmlFindCharEncodingHandler((char *)encoding);
1658  if ((encoder != NULL) &&
1659  (xmlStrEqual((const xmlChar *)encoder->name,
1660  (const xmlChar *) "UTF-8")))
1661  encoder = NULL;
1662  buf = xmlOutputBufferCreateFile(file, encoder);
1663  } else {
1664  buf = xmlOutputBufferCreateFile(file, NULL);
1665  }
1666 
1667  if (buf == NULL)
1668  return(-1);
1670  ret = xmlOutputBufferClose(buf);
1671  return(ret);
1672 }
1673 
1686 int
1689  const xmlChar *encoding;
1690  int ret;
1691 
1692  if ((fd < 0) || (result == NULL) || (style == NULL))
1693  return(-1);
1694  if (result->children == NULL)
1695  return(0);
1696 
1698  if (encoding != NULL) {
1699  xmlCharEncodingHandlerPtr encoder;
1700 
1701  encoder = xmlFindCharEncodingHandler((char *)encoding);
1702  if ((encoder != NULL) &&
1703  (xmlStrEqual((const xmlChar *)encoder->name,
1704  (const xmlChar *) "UTF-8")))
1705  encoder = NULL;
1706  buf = xmlOutputBufferCreateFd(fd, encoder);
1707  } else {
1708  buf = xmlOutputBufferCreateFd(fd, NULL);
1709  }
1710  if (buf == NULL)
1711  return(-1);
1713  ret = xmlOutputBufferClose(buf);
1714  return(ret);
1715 }
1716 
1729 int
1730 xsltSaveResultToString(xmlChar **doc_txt_ptr, int * doc_txt_len,
1733  const xmlChar *encoding;
1734 
1735  *doc_txt_ptr = NULL;
1736  *doc_txt_len = 0;
1737  if (result->children == NULL)
1738  return(0);
1739 
1741  if (encoding != NULL) {
1742  xmlCharEncodingHandlerPtr encoder;
1743 
1744  encoder = xmlFindCharEncodingHandler((char *)encoding);
1745  if ((encoder != NULL) &&
1746  (xmlStrEqual((const xmlChar *)encoder->name,
1747  (const xmlChar *) "UTF-8")))
1748  encoder = NULL;
1749  buf = xmlAllocOutputBuffer(encoder);
1750  } else {
1751  buf = xmlAllocOutputBuffer(NULL);
1752  }
1753  if (buf == NULL)
1754  return(-1);
1756 #ifdef LIBXML2_NEW_BUFFER
1757  if (buf->conv != NULL) {
1758  *doc_txt_len = xmlBufUse(buf->conv);
1759  *doc_txt_ptr = xmlStrndup(xmlBufContent(buf->conv), *doc_txt_len);
1760  } else {
1761  *doc_txt_len = xmlBufUse(buf->buffer);
1762  *doc_txt_ptr = xmlStrndup(xmlBufContent(buf->buffer), *doc_txt_len);
1763  }
1764 #else
1765  if (buf->conv != NULL) {
1766  *doc_txt_len = buf->conv->use;
1767  *doc_txt_ptr = xmlStrndup(buf->conv->content, *doc_txt_len);
1768  } else {
1769  *doc_txt_len = buf->buffer->use;
1770  *doc_txt_ptr = xmlStrndup(buf->buffer->content, *doc_txt_len);
1771  }
1772 #endif
1773  (void)xmlOutputBufferClose(buf);
1774  return 0;
1775 }
1776 
1777 #ifdef WITH_PROFILER
1778 
1779 /************************************************************************
1780  * *
1781  * Generating profiling information *
1782  * *
1783  ************************************************************************/
1784 
1785 static long calibration = -1;
1786 
1795 #if !defined(XSLT_WIN32_PERFORMANCE_COUNTER) && \
1796  (defined(HAVE_CLOCK_GETTIME) || defined(HAVE_GETTIMEOFDAY))
1797 static long
1798 xsltCalibrateTimestamps(void) {
1799  register int i;
1800 
1801  for (i = 0;i < 999;i++)
1802  xsltTimestamp();
1803  return(xsltTimestamp() / 1000);
1804 }
1805 #endif
1806 
1813 void
1814 xsltCalibrateAdjust(long delta) {
1815  calibration += delta;
1816 }
1817 
1826 long
1827 xsltTimestamp(void)
1828 {
1829 #ifdef XSLT_WIN32_PERFORMANCE_COUNTER
1830  BOOL ok;
1831  LARGE_INTEGER performanceCount;
1832  LARGE_INTEGER performanceFrequency;
1833  LONGLONG quadCount;
1834  double seconds;
1835  static LONGLONG startupQuadCount = 0;
1836  static LONGLONG startupQuadFreq = 0;
1837 
1838  ok = QueryPerformanceCounter(&performanceCount);
1839  if (!ok)
1840  return 0;
1841  quadCount = performanceCount.QuadPart;
1842  if (calibration < 0) {
1843  calibration = 0;
1844  ok = QueryPerformanceFrequency(&performanceFrequency);
1845  if (!ok)
1846  return 0;
1847  startupQuadFreq = performanceFrequency.QuadPart;
1848  startupQuadCount = quadCount;
1849  return (0);
1850  }
1851  if (startupQuadFreq == 0)
1852  return 0;
1853  seconds = (quadCount - startupQuadCount) / (double) startupQuadFreq;
1854  return (long) (seconds * XSLT_TIMESTAMP_TICS_PER_SEC);
1855 
1856 #else /* XSLT_WIN32_PERFORMANCE_COUNTER */
1857 #ifdef HAVE_CLOCK_GETTIME
1858 # if defined(CLOCK_MONOTONIC)
1859 # define XSLT_CLOCK CLOCK_MONOTONIC
1860 # elif defined(CLOCK_HIGHRES)
1861 # define XSLT_CLOCK CLOCK_HIGHRES
1862 # else
1863 # define XSLT_CLOCK CLOCK_REALTIME
1864 # endif
1865  static struct timespec startup;
1866  struct timespec cur;
1867  long tics;
1868 
1869  if (calibration < 0) {
1870  clock_gettime(XSLT_CLOCK, &startup);
1871  calibration = 0;
1872  calibration = xsltCalibrateTimestamps();
1873  clock_gettime(XSLT_CLOCK, &startup);
1874  return (0);
1875  }
1876 
1877  clock_gettime(XSLT_CLOCK, &cur);
1878  tics = (cur.tv_sec - startup.tv_sec) * XSLT_TIMESTAMP_TICS_PER_SEC;
1879  tics += (cur.tv_nsec - startup.tv_nsec) /
1880  (1000000000l / XSLT_TIMESTAMP_TICS_PER_SEC);
1881 
1882  tics -= calibration;
1883  return(tics);
1884 
1885 #elif HAVE_GETTIMEOFDAY
1886  static struct timeval startup;
1887  struct timeval cur;
1888  long tics;
1889 
1890  if (calibration < 0) {
1892  calibration = 0;
1893  calibration = xsltCalibrateTimestamps();
1895  return (0);
1896  }
1897 
1898  gettimeofday(&cur, NULL);
1899  tics = (cur.tv_sec - startup.tv_sec) * XSLT_TIMESTAMP_TICS_PER_SEC;
1900  tics += (cur.tv_usec - startup.tv_usec) /
1901  (1000000l / XSLT_TIMESTAMP_TICS_PER_SEC);
1902 
1903  tics -= calibration;
1904  return(tics);
1905 #else
1906 
1907  /* Neither gettimeofday() nor Win32 performance counter available */
1908 
1909  return (0);
1910 
1911 #endif /* HAVE_GETTIMEOFDAY */
1912 #endif /* XSLT_WIN32_PERFORMANCE_COUNTER */
1913 }
1914 
1915 static char *
1916 pretty_templ_match(xsltTemplatePtr templ) {
1917  static char dst[1001];
1918  char *src = (char *)templ->match;
1919  int i=0,j;
1920 
1921  /* strip white spaces */
1922  for (j=0; i<1000 && src[j]; i++,j++) {
1923  for(;src[j]==' ';j++);
1924  dst[i]=src[j];
1925  }
1926  if(i<998 && templ->mode) {
1927  /* append [mode] */
1928  dst[i++]='[';
1929  src=(char *)templ->mode;
1930  for (j=0; i<999 && src[j]; i++,j++) {
1931  dst[i]=src[j];
1932  }
1933  dst[i++]=']';
1934  }
1935  dst[i]='\0';
1936  return dst;
1937 }
1938 
1939 #define MAX_TEMPLATES 10000
1940 
1948 void
1950  int nb, i,j,k,l;
1951  int max;
1952  int total;
1953  unsigned long totalt;
1956  xsltTemplatePtr templ1,templ2;
1957  int *childt;
1958 
1959  if ((output == NULL) || (ctxt == NULL))
1960  return;
1961  if (ctxt->profile == 0)
1962  return;
1963 
1964  nb = 0;
1965  max = MAX_TEMPLATES;
1966  templates = xmlMalloc(max * sizeof(xsltTemplatePtr));
1967  if (templates == NULL)
1968  return;
1969 
1970  style = ctxt->style;
1971  while (style != NULL) {
1972  templ1 = style->templates;
1973  while (templ1 != NULL) {
1974  if (nb >= max)
1975  break;
1976 
1977  if (templ1->nbCalls > 0)
1978  templates[nb++] = templ1;
1979  templ1 = templ1->next;
1980  }
1981 
1983  }
1984 
1985  for (i = 0;i < nb -1;i++) {
1986  for (j = i + 1; j < nb; j++) {
1987  if ((templates[i]->time <= templates[j]->time) ||
1988  ((templates[i]->time == templates[j]->time) &&
1989  (templates[i]->nbCalls <= templates[j]->nbCalls))) {
1990  templ1 = templates[j];
1991  templates[j] = templates[i];
1992  templates[i] = templ1;
1993  }
1994  }
1995  }
1996 
1997 
1998  /* print flat profile */
1999 
2000  fprintf(output, "%6s%20s%20s%10s Calls Tot 100us Avg\n\n",
2001  "number", "match", "name", "mode");
2002  total = 0;
2003  totalt = 0;
2004  for (i = 0;i < nb;i++) {
2005  templ1 = templates[i];
2006  fprintf(output, "%5d ", i);
2007  if (templ1->match != NULL) {
2008  if (xmlStrlen(templ1->match) > 20)
2009  fprintf(output, "%s\n%26s", templ1->match, "");
2010  else
2011  fprintf(output, "%20s", templ1->match);
2012  } else {
2013  fprintf(output, "%20s", "");
2014  }
2015  if (templ1->name != NULL) {
2016  if (xmlStrlen(templ1->name) > 20)
2017  fprintf(output, "%s\n%46s", templ1->name, "");
2018  else
2019  fprintf(output, "%20s", templ1->name);
2020  } else {
2021  fprintf(output, "%20s", "");
2022  }
2023  if (templ1->mode != NULL) {
2024  if (xmlStrlen(templ1->mode) > 10)
2025  fprintf(output, "%s\n%56s", templ1->mode, "");
2026  else
2027  fprintf(output, "%10s", templ1->mode);
2028  } else {
2029  fprintf(output, "%10s", "");
2030  }
2031  fprintf(output, " %6d", templ1->nbCalls);
2032  fprintf(output, " %6ld %6ld\n", templ1->time,
2033  templ1->time / templ1->nbCalls);
2034  total += templ1->nbCalls;
2035  totalt += templ1->time;
2036  }
2037  fprintf(output, "\n%30s%26s %6d %6ld\n", "Total", "", total, totalt);
2038 
2039 
2040  /* print call graph */
2041 
2042  childt = xmlMalloc((nb + 1) * sizeof(int));
2043  if (childt == NULL)
2044  return;
2045 
2046  /* precalculate children times */
2047  for (i = 0; i < nb; i++) {
2048  templ1 = templates[i];
2049 
2050  childt[i] = 0;
2051  for (k = 0; k < nb; k++) {
2052  templ2 = templates[k];
2053  for (l = 0; l < templ2->templNr; l++) {
2054  if (templ2->templCalledTab[l] == templ1) {
2055  childt[i] +=templ2->time;
2056  }
2057  }
2058  }
2059  }
2060  childt[i] = 0;
2061 
2062  fprintf(output, "\nindex %% time self children called name\n");
2063 
2064  for (i = 0; i < nb; i++) {
2065  char ix_str[20], timep_str[20], times_str[20], timec_str[20], called_str[20];
2066  unsigned long t;
2067 
2068  templ1 = templates[i];
2069  /* callers */
2070  for (j = 0; j < templ1->templNr; j++) {
2071  templ2 = templ1->templCalledTab[j];
2072  for (k = 0; k < nb; k++) {
2073  if (templates[k] == templ2)
2074  break;
2075  }
2076  t=templ2?templ2->time:totalt;
2077  snprintf(times_str,sizeof(times_str),"%8.3f",(float)t/XSLT_TIMESTAMP_TICS_PER_SEC);
2078  snprintf(timec_str,sizeof(timec_str),"%8.3f",(float)childt[k]/XSLT_TIMESTAMP_TICS_PER_SEC);
2079  snprintf(called_str,sizeof(called_str),"%6d/%d",
2080  templ1->templCountTab[j], /* number of times caller calls 'this' */
2081  templ1->nbCalls); /* total number of calls to 'this' */
2082 
2083  fprintf(output, " %-8s %-8s %-12s %s [%d]\n",
2084  times_str,timec_str,called_str,
2085  (templ2?(templ2->name?(char *)templ2->name:pretty_templ_match(templ2)):"-"),k);
2086  }
2087  /* this */
2088  snprintf(ix_str,sizeof(ix_str),"[%d]",i);
2089  snprintf(timep_str,sizeof(timep_str),"%6.2f",(float)templ1->time*100.0/totalt);
2090  snprintf(times_str,sizeof(times_str),"%8.3f",(float)templ1->time/XSLT_TIMESTAMP_TICS_PER_SEC);
2091  snprintf(timec_str,sizeof(timec_str),"%8.3f",(float)childt[i]/XSLT_TIMESTAMP_TICS_PER_SEC);
2092  fprintf(output, "%-5s %-6s %-8s %-8s %6d %s [%d]\n",
2093  ix_str, timep_str,times_str,timec_str,
2094  templ1->nbCalls,
2095  templ1->name?(char *)templ1->name:pretty_templ_match(templ1),i);
2096  /* callees
2097  * - go over templates[0..nb] and their templCalledTab[]
2098  * - print those where we in the the call-stack
2099  */
2100  total = 0;
2101  for (k = 0; k < nb; k++) {
2102  templ2 = templates[k];
2103  for (l = 0; l < templ2->templNr; l++) {
2104  if (templ2->templCalledTab[l] == templ1) {
2105  total+=templ2->templCountTab[l];
2106  }
2107  }
2108  }
2109  for (k = 0; k < nb; k++) {
2110  templ2 = templates[k];
2111  for (l = 0; l < templ2->templNr; l++) {
2112  if (templ2->templCalledTab[l] == templ1) {
2113  snprintf(times_str,sizeof(times_str),"%8.3f",(float)templ2->time/XSLT_TIMESTAMP_TICS_PER_SEC);
2114  snprintf(timec_str,sizeof(timec_str),"%8.3f",(float)childt[k]/XSLT_TIMESTAMP_TICS_PER_SEC);
2115  snprintf(called_str,sizeof(called_str),"%6d/%d",
2116  templ2->templCountTab[l], /* number of times 'this' calls callee */
2117  total); /* total number of calls from 'this' */
2118  fprintf(output, " %-8s %-8s %-12s %s [%d]\n",
2119  times_str,timec_str,called_str,
2120  templ2->name?(char *)templ2->name:pretty_templ_match(templ2),k);
2121  }
2122  }
2123  }
2124  fprintf(output, "-----------------------------------------------\n");
2125  }
2126 
2127  fprintf(output, "\f\nIndex by function name\n");
2128  for (i = 0; i < nb; i++) {
2129  templ1 = templates[i];
2130  fprintf(output, "[%d] %s (%s:%d)\n",
2131  i, templ1->name?(char *)templ1->name:pretty_templ_match(templ1),
2132  templ1->style->doc->URL,templ1->elem->line);
2133  }
2134 
2135  fprintf(output, "\f\n");
2136  xmlFree(childt);
2137 
2138  xmlFree(templates);
2139 }
2140 
2141 /************************************************************************
2142  * *
2143  * Fetching profiling information *
2144  * *
2145  ************************************************************************/
2146 
2168 xmlDocPtr
2170 {
2171  xmlDocPtr ret = NULL;
2173  char buf[100];
2174 
2177  xsltTemplatePtr templ;
2178  int nb = 0, max = 0, i, j;
2179 
2180  if (!ctxt)
2181  return NULL;
2182 
2183  if (!ctxt->profile)
2184  return NULL;
2185 
2186  nb = 0;
2187  max = 10000;
2188  templates =
2190  if (templates == NULL)
2191  return NULL;
2192 
2193  /*
2194  * collect all the templates in an array
2195  */
2196  style = ctxt->style;
2197  while (style != NULL) {
2198  templ = style->templates;
2199  while (templ != NULL) {
2200  if (nb >= max)
2201  break;
2202 
2203  if (templ->nbCalls > 0)
2204  templates[nb++] = templ;
2205  templ = templ->next;
2206  }
2207 
2209  }
2210 
2211  /*
2212  * Sort the array by time spent
2213  */
2214  for (i = 0; i < nb - 1; i++) {
2215  for (j = i + 1; j < nb; j++) {
2216  if ((templates[i]->time <= templates[j]->time) ||
2217  ((templates[i]->time == templates[j]->time) &&
2218  (templates[i]->nbCalls <= templates[j]->nbCalls))) {
2219  templ = templates[j];
2220  templates[j] = templates[i];
2221  templates[i] = templ;
2222  }
2223  }
2224  }
2225 
2226  /*
2227  * Generate a document corresponding to the results.
2228  */
2229  ret = xmlNewDoc(BAD_CAST "1.0");
2230  root = xmlNewDocNode(ret, NULL, BAD_CAST "profile", NULL);
2231  xmlDocSetRootElement(ret, root);
2232 
2233  for (i = 0; i < nb; i++) {
2234  child = xmlNewChild(root, NULL, BAD_CAST "template", NULL);
2235  snprintf(buf, sizeof(buf), "%d", i + 1);
2236  xmlSetProp(child, BAD_CAST "rank", BAD_CAST buf);
2237  xmlSetProp(child, BAD_CAST "match", BAD_CAST templates[i]->match);
2238  xmlSetProp(child, BAD_CAST "name", BAD_CAST templates[i]->name);
2239  xmlSetProp(child, BAD_CAST "mode", BAD_CAST templates[i]->mode);
2240 
2241  snprintf(buf, sizeof(buf), "%d", templates[i]->nbCalls);
2242  xmlSetProp(child, BAD_CAST "calls", BAD_CAST buf);
2243 
2244  snprintf(buf, sizeof(buf), "%ld", templates[i]->time);
2245  xmlSetProp(child, BAD_CAST "time", BAD_CAST buf);
2246 
2247  snprintf(buf, sizeof(buf), "%ld", templates[i]->time / templates[i]->nbCalls);
2248  xmlSetProp(child, BAD_CAST "average", BAD_CAST buf);
2249  };
2250 
2251  xmlFree(templates);
2252 
2253  return ret;
2254 }
2255 
2256 #endif /* WITH_PROFILER */
2257 
2258 /************************************************************************
2259  * *
2260  * Hooks for libxml2 XPath *
2261  * *
2262  ************************************************************************/
2263 
2275 xmlXPathCompExprPtr
2277  xmlXPathContextPtr xpathCtxt;
2278  xmlXPathCompExprPtr ret;
2279 
2280  if (style != NULL) {
2281  xpathCtxt = style->principal->xpathCtxt;
2282  if (xpathCtxt == NULL)
2283  return NULL;
2284  xpathCtxt->dict = style->dict;
2285  } else {
2286  xpathCtxt = xmlXPathNewContext(NULL);
2287  if (xpathCtxt == NULL)
2288  return NULL;
2289  }
2290  xpathCtxt->flags = flags;
2291 
2292  /*
2293  * Compile the expression.
2294  */
2295  ret = xmlXPathCtxtCompile(xpathCtxt, str);
2296 
2297  if (style == NULL) {
2298  xmlXPathFreeContext(xpathCtxt);
2299  }
2300  /*
2301  * TODO: there is a lot of optimizations which should be possible
2302  * like variable slot precomputations, function precomputations, etc.
2303  */
2304 
2305  return(ret);
2306 }
2307 
2318 xmlXPathCompExprPtr
2320  return(xsltXPathCompileFlags(style, str, 0));
2321 }
2322 
2323 /************************************************************************
2324  * *
2325  * Hooks for the debugger *
2326  * *
2327  ************************************************************************/
2328 
2330 
2338 int
2340 {
2341  return(xslDebugStatus);
2342 }
2343 
2344 #ifdef WITH_DEBUGGER
2345 
2346 /*
2347  * There is currently only 3 debugging callback defined
2348  * Debugger callbacks are disabled by default
2349  */
2350 #define XSLT_CALLBACK_NUMBER 3
2351 
2352 typedef struct _xsltDebuggerCallbacks xsltDebuggerCallbacks;
2353 typedef xsltDebuggerCallbacks *xsltDebuggerCallbacksPtr;
2354 struct _xsltDebuggerCallbacks {
2357  xsltDropCallCallback drop;
2358 };
2359 
2360 static xsltDebuggerCallbacks xsltDebuggerCurrentCallbacks = {
2361  NULL, /* handler */
2362  NULL, /* add */
2363  NULL /* drop */
2364 };
2365 
2372 void
2374 {
2376 }
2377 
2389 int
2390 xsltSetDebuggerCallbacks(int no, void *block)
2391 {
2392  xsltDebuggerCallbacksPtr callbacks;
2393 
2394  if ((block == NULL) || (no != XSLT_CALLBACK_NUMBER))
2395  return(-1);
2396 
2397  callbacks = (xsltDebuggerCallbacksPtr) block;
2398  xsltDebuggerCurrentCallbacks.handler = callbacks->handler;
2399  xsltDebuggerCurrentCallbacks.add = callbacks->add;
2400  xsltDebuggerCurrentCallbacks.drop = callbacks->drop;
2401  return(0);
2402 }
2403 
2415 void
2418 {
2419  if (xsltDebuggerCurrentCallbacks.handler != NULL)
2420  xsltDebuggerCurrentCallbacks.handler(cur, node, templ, ctxt);
2421 }
2422 
2432 int
2434 {
2435  if (xsltDebuggerCurrentCallbacks.add != NULL)
2436  return(xsltDebuggerCurrentCallbacks.add(templ, source));
2437  return(0);
2438 }
2439 
2445 void
2446 xslDropCall(void)
2447 {
2448  if (xsltDebuggerCurrentCallbacks.drop != NULL)
2449  xsltDebuggerCurrentCallbacks.drop();
2450 }
2451 
2452 #endif /* WITH_DEBUGGER */
2453 
static unsigned int block
Definition: xmlmemory.c:118
xmlNodeSetPtr nodeList
int add
Definition: i386-dis.c:3122
void * psvi
Definition: tree.h:505
XSLTPUBFUN xmlDocPtr XSLTCALL xsltGetProfileInformation(xsltTransformContextPtr ctxt)
void xsltMessage(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst)
Definition: xsltutils.c:408
static xsltSortFunc xsltSortFunction
Definition: xsltutils.c:1315
const xmlChar * prefix
Definition: tree.h:269
#define max(a, b)
Definition: svc.c:63
const xmlChar * mode
Definition: tftpd.h:59
xmlNs * ns
Definition: tree.h:444
void(* xsltDropCallCallback)(void)
Definition: xsltutils.h:293
static UCHAR ULONG UCHAR ULONG UCHAR * output
Definition: bcrypt.c:29
const xmlChar * name
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
static const WCHAR indent[]
Definition: object.c:1156
const xmlChar * URL
Definition: tree.h:577
XMLPUBFUN xmlChar *XMLCALL xmlBufContent(const xmlBuf *buf)
Definition: buf.c:582
#define error(str)
Definition: mkdosfs.c:1605
struct _xmlDtd * intSubset
Definition: tree.h:570
xsltLocaleChar * xsltStrxfrm(xsltLocale locale, const xmlChar *string)
Definition: xsltlocale.c:359
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
int xslDebugStatus
Definition: xsltutils.c:2329
Definition: match.c:28
XSLTPUBFUN void XSLTCALL xsltCalibrateAdjust(long delta)
Definition: tree.h:389
XMLPUBFUN xmlChar *XMLCALL xmlStrndup(const xmlChar *cur, int len)
Definition: xmlstring.c:41
int xsltLocaleStrcmp(xsltLocale locale, const xsltLocaleChar *str1, const xsltLocaleChar *str2)
Definition: xsltlocale.c:422
xsltStylesheetPtr xsltNextImport(xsltStylesheetPtr cur)
Definition: imports.c:251
void xsltPrintErrorContext(xsltTransformContextPtr ctxt, xsltStylesheetPtr style, xmlNodePtr node)
Definition: xsltutils.c:583
_STLP_MOVE_TO_STD_NAMESPACE void sort(_RandomAccessIter __first, _RandomAccessIter __last)
Definition: _algo.c:993
XMLPUBFUN int XMLCALL xmlStrlen(const xmlChar *str)
Definition: xmlstring.c:422
struct _root root
XMLPUBFUN xmlChar *XMLCALL xmlGetProp(const xmlNode *node, const xmlChar *name)
int xsltGetDebuggerStatus(void)
Definition: xsltutils.c:2339
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: glext.h:5579
xmlXPathCompExprPtr xsltXPathCompile(xsltStylesheetPtr style, const xmlChar *str)
Definition: xsltutils.c:2319
xsltTemplatePtr * templCalledTab
GLdouble GLdouble t
Definition: gl.h:2047
xmlNodePtr elem
struct _xmlAttr * next
Definition: tree.h:441
#define snprintf
Definition: wintirpc.h:48
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define XSLT_TIMESTAMP_TICS_PER_SEC
Definition: xsltutils.h:269
int startup(int argc, const char *argv[])
Definition: startup.c:430
struct _xmlNode * children
Definition: tree.h:438
static int fd
Definition: io.c:51
xmlCharEncoding
Definition: encoding.h:58
void xsltSetGenericDebugFunc(void *ctx, xmlGenericErrorFunc handler)
Definition: xsltutils.c:566
XMLPUBFUN const char *XMLCALL xmlGetCharEncodingName(xmlCharEncoding enc)
Definition: encoding.c:1234
__u16 time
Definition: mkdosfs.c:366
XMLPUBFUN xmlAttributePtr XMLCALL xmlGetDtdAttrDesc(xmlDtdPtr dtd, const xmlChar *elem, const xmlChar *name)
Definition: valid.c:3341
XSLTPUBFUN long XSLTCALL xsltTimestamp(void)
#define XSLT_NAMESPACE
Definition: xslt.h:46
Definition: match.c:390
const xmlChar * order
static HWND child
Definition: cursoricon.c:298
xmlChar * xsltEvalAttrValueTemplate(xsltTransformContextPtr ctxt, xmlNodePtr inst, const xmlChar *name, const xmlChar *ns)
Definition: templates.c:384
XSLTPUBFUN int XSLTCALL xsltSetDebuggerCallbacks(int no, void *block)
struct _xsltTemplate * next
void xsltDoSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, int nbsorts)
Definition: xsltutils.c:1332
XSLTPUBFUN void XSLTCALL xslHandleDebugger(xmlNodePtr cur, xmlNodePtr node, xsltTemplatePtr templ, xsltTransformContextPtr ctxt)
void xsltSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc handler)
Definition: xsltutils.c:520
struct node node
#define XSLT_GET_IMPORT_INT(res, style, name)
Definition: imports.h:40
#define gettimeofday(tv, tz)
Definition: adns_win32.h:159
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define XSLT_MAX_SORT
size_type size() const
Definition: _list.h:379
#define va_end(ap)
Definition: acmsvcex.h:90
unsigned int BOOL
Definition: ntddk_ex.h:94
int xsltGetUTF8Char(const unsigned char *utf, int *len)
Definition: xsltutils.c:227
GLuint base
Definition: 3dtext.c:35
xmlGenericErrorFunc xsltGenericError
Definition: xsltutils.c:502
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
static size_t double number
Definition: printf.c:69
static const WCHAR desc[]
Definition: protectdata.c:36
xmlOutputBuffer * xmlOutputBufferPtr
Definition: tree.h:32
int xsltSaveResultTo(xmlOutputBufferPtr buf, xmlDocPtr result, xsltStylesheetPtr style)
Definition: xsltutils.c:1423
XSLTPUBFUN void XSLTCALL xslDropCall(void)
xsltTransformState state
const xmlChar * stype
XMLPUBFUN xmlNsPtr XMLCALL xmlSearchNs(xmlDocPtr doc, xmlNodePtr node, const xmlChar *nameSpace)
const WCHAR * str
BOOL WINAPI QueryPerformanceFrequency(OUT PLARGE_INTEGER lpFrequency)
Definition: perfcnt.c:45
static void LIBXSLT_ATTR_FORMAT(2, 3)
Definition: xsltutils.c:490
smooth NULL
Definition: ftsmooth.c:416
void xsltDocumentSortFunction(xmlNodeSetPtr list)
Definition: xsltutils.c:903
#define XML_XML_NAMESPACE
Definition: tree.h:140
void xsltSetTransformErrorFunc(xsltTransformContextPtr ctxt, void *ctx, xmlGenericErrorFunc handler)
Definition: xsltutils.c:659
Definition: parser.c:48
char * va_list
Definition: acmsvcex.h:78
void xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, int nbsorts)
Definition: xsltutils.c:1064
#define BAD_CAST
Definition: xmlstring.h:35
xmlXPathContextPtr xpathCtxt
Definition: dict.c:116
int options
Definition: main.c:106
XMLPUBFUN long XMLCALL xmlGetLineNo(const xmlNode *node)
XMLPUBVAR xmlReallocFunc xmlRealloc
Definition: globals.h:249
struct _xmlNode * parent
Definition: tree.h:495
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
r l[0]
Definition: byte_order.h:167
int64_t LONGLONG
Definition: typedefs.h:67
const xmlChar * defaultValue
Definition: tree.h:267
void MSVCRT() terminate()
static WCHAR no[MAX_STRING_RESOURCE_LEN]
Definition: object.c:2340
void * xsltGenericDebugContext
Definition: xsltutils.c:549
int xsltSetCtxtParseOptions(xsltTransformContextPtr ctxt, int options)
Definition: xsltutils.c:1388
const xmlChar * xsltSplitQName(xmlDictPtr dict, const xmlChar *name, const xmlChar **prefix)
Definition: xsltutils.c:720
XSLTPUBFUN void XSLTCALL xsltSaveProfiling(xsltTransformContextPtr ctxt, FILE *output)
const GLubyte * c
Definition: glext.h:8905
int xsltSaveResultToFile(FILE *file, xmlDocPtr result, xsltStylesheetPtr style)
Definition: xsltutils.c:1643
void(* xsltHandleDebuggerCallback)(xmlNodePtr cur, xmlNodePtr node, xsltTemplatePtr templ, xsltTransformContextPtr ctxt)
Definition: xsltutils.h:290
#define MAX_TEMPLATES
Definition: appearance.h:29
int xsltSaveResultToFd(int fd, xmlDocPtr result, xsltStylesheetPtr style)
Definition: xsltutils.c:1687
#define for
Definition: utility.h:88
XMLPUBVAR xmlFreeFunc xmlFree
Definition: globals.h:250
XMLPUBFUN xmlChar *XMLCALL xmlGetNsProp(const xmlNode *node, const xmlChar *name, const xmlChar *nameSpace)
xmlChar xsltLocaleChar
Definition: xsltlocale.h:64
XMLPUBFUN const xmlChar *XMLCALL xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len)
Definition: dict.c:865
xmlGenericErrorFunc xsltGenericDebug
Definition: xsltutils.c:548
void(* xsltSortFunc)(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, int nbsorts)
struct _test_info results[8]
Definition: SetCursorPos.c:29
xmlChar * content
Definition: tree.h:502
GLbitfield flags
Definition: glext.h:7161
method
Definition: dragdrop.c:53
void * xsltGenericErrorContext
Definition: xsltutils.c:503
Definition: tree.h:489
BOOL WINAPI QueryPerformanceCounter(OUT PLARGE_INTEGER lpPerformanceCount)
Definition: perfcnt.c:23
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
XMLPUBFUN xmlChar *XMLCALL xmlNodeListGetString(xmlDocPtr doc, const xmlNode *list, int inLine)
int ret
int xsltSaveResultToFilename(const char *URL, xmlDocPtr result, xsltStylesheetPtr style, int compression)
Definition: xsltutils.c:1599
#define ATTRIBUTE_UNUSED
Definition: win32config.h:132
Definition: mxnamespace.c:44
XMLPUBFUN xmlCharEncodingHandlerPtr XMLCALL xmlFindCharEncodingHandler(const char *name)
Definition: encoding.c:1641
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY _In_ uint8_t compression
Definition: btrfs_drv.h:1357
unsigned char xmlChar
Definition: xmlstring.h:28
unsigned long time
GLenum GLsizei len
Definition: glext.h:6722
XSLTPUBFUN void XSLTCALL xsltSetDebuggerStatus(int value)
Definition: _list.h:228
GLenum src
Definition: glext.h:6340
GLenum mode
Definition: glext.h:6217
GLsizei const GLfloat * value
Definition: glext.h:6069
xmlElementType type
Definition: tree.h:491
struct _xsltStylesheet * style
ed encoding
Definition: write.c:2825
void xsltSetSortFunc(xsltSortFunc handler)
Definition: xsltutils.c:1349
xmlDoc * xmlDocPtr
Definition: tree.h:550
xsltStylesheetPtr style
static ATOM item
Definition: dde.c:856
struct _xmlNode * next
Definition: tree.h:496
void xsltSetCtxtSortFunc(xsltTransformContextPtr ctxt, xsltSortFunc handler)
Definition: xsltutils.c:1367
xmlXPathCompExprPtr comp
#define ok(value,...)
Definition: atltest.h:57
GLenum GLenum dst
Definition: glext.h:6340
xmlXPathObjectPtr * xsltComputeSortResult(xsltTransformContextPtr ctxt, xmlNodePtr sort)
Definition: xsltutils.c:937
#define XSLT_GET_IMPORT_PTR(res, style, name)
Definition: imports.h:27
int xsltSaveResultToString(xmlChar **doc_txt_ptr, int *doc_txt_len, xmlDocPtr result, xsltStylesheetPtr style)
Definition: xsltutils.c:1730
xmlGenericErrorFunc error
#define va_start(ap, A)
Definition: acmsvcex.h:91
XMLPUBFUN xmlNodePtr XMLCALL xmlNewDocNode(xmlDocPtr doc, xmlNsPtr ns, const xmlChar *name, const xmlChar *content)
XMLPUBVAR xmlMallocFunc xmlMalloc
Definition: globals.h:247
const xmlChar * xsltGetCNsProp(xsltStylesheetPtr style, xmlNodePtr node, const xmlChar *name, const xmlChar *nameSpace)
Definition: xsltutils.c:52
Definition: tree.h:551
Definition: time.h:88
xmlXPathCompExprPtr xsltXPathCompileFlags(xsltStylesheetPtr style, const xmlChar *str, int flags)
Definition: xsltutils.c:2276
const xmlChar * select
const xmlChar * xsltGetQNameURI2(xsltStylesheetPtr style, xmlNodePtr node, const xmlChar **name)
Definition: xsltutils.c:827
#define msg(x)
Definition: auth_time.c:54
struct _xmlDtd * extSubset
Definition: tree.h:571
struct _xmlNode * children
Definition: tree.h:493
Definition: tree.h:434
xmlChar * xsltEvalTemplateString(xsltTransformContextPtr ctxt, xmlNodePtr contextNode, xmlNodePtr inst)
Definition: templates.c:189
Definition: name.c:38
void(XMLCDECL * xmlGenericErrorFunc)(void *ctx, const char *msg,...) LIBXML_ATTR_FORMAT(2
Definition: xmlerror.h:845
GLuint res
Definition: glext.h:9613
#define c
Definition: ke_i.h:80
XSLTPUBFUN int XSLTCALL xslAddCall(xsltTemplatePtr templ, xmlNodePtr source)
FILE * stderr
#define const
Definition: zconf.h:230
xmlChar * xsltGetNsProp(xmlNodePtr node, const xmlChar *name, const xmlChar *nameSpace)
Definition: xsltutils.c:142
const xmlChar * name
Definition: tree.h:437
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7786
xmlChar * match
XMLPUBFUN int XMLCALL xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:157
char templates[]
Definition: meshbuilder.c:39
void xsltTransformError(xsltTransformContextPtr ctxt, xsltStylesheetPtr style, xmlNodePtr node, const char *msg,...)
Definition: xsltutils.c:678
_Check_return_opt_ _CRTIMP int __cdecl vfprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format, va_list _ArgList)
static int callbacks
Definition: xmllint.c:873
Arabic default style
Definition: afstyles.h:93
const xmlChar * href
Definition: tree.h:392
GLuint64EXT * result
Definition: glext.h:11304
#define memset(x, y, z)
Definition: compat.h:39
#define args
Definition: format.c:66
XMLPUBFUN xmlDocPtr XMLCALL xmlNewDoc(const xmlChar *version)
int k
Definition: mpi.c:3369
XMLPUBFUN size_t XMLCALL xmlBufUse(const xmlBufPtr buf)
Definition: buf.c:687
XMLPUBFUN xmlChar *XMLCALL xmlStrdup(const xmlChar *cur)
Definition: xmlstring.c:66
#define XSLT_GET_VAR_STR(msg, str)
Definition: xsltutils.c:453
unsigned short line
Definition: tree.h:506
LONGLONG QuadPart
Definition: typedefs.h:113
int(* xsltAddCallCallback)(xsltTemplatePtr templ, xmlNodePtr source)
Definition: xsltutils.h:292
Definition: dlist.c:348
Definition: fci.c:126
XMLPUBFUN int XMLCALL xmlStrcmp(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:132
xsltStylesheet * xsltStylesheetPtr
GLuint const GLchar * name
Definition: glext.h:6031
const xmlChar * xsltGetQNameURI(xmlNodePtr node, xmlChar **name)
Definition: xsltutils.c:753