ReactOS 0.4.15-dev-7958-gcd0bb1a
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)
22#define XSLT_WIN32_PERFORMANCE_COUNTER
23#endif
24
25/************************************************************************
26 * *
27 * Convenience function *
28 * *
29 ************************************************************************/
30
51const xmlChar *
53 const xmlChar *name, const xmlChar *nameSpace) {
54 xmlAttrPtr prop;
55 xmlDocPtr doc;
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}
141xmlChar *
142xsltGetNsProp(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
226int
227xsltGetUTF8Char(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
278error:
279 if (len != NULL)
280 *len = 0;
281 return(-1);
282}
283
284#ifdef XSLT_REFACTORED
285
297int
298xsltPointerListAddSize(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
337xsltPointerListPtr
338xsltPointerListCreate(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
363void
364xsltPointerListFree(xsltPointerListPtr list)
365{
366 if (list == NULL)
367 return;
368 if (list->items != NULL)
369 xmlFree(list->items);
370 xmlFree(list);
371}
372
380void
381xsltPointerListClear(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
407void
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");
442 }
443 if (terminate)
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}
490static void LIBXSLT_ATTR_FORMAT(2,3)
491xsltGenericErrorDefaultFunc(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) {
493
496
497 va_start(args, msg);
499 va_end(args);
500}
501
502xmlGenericErrorFunc xsltGenericError = xsltGenericErrorDefaultFunc;
504
505
519void
522 if (handler != NULL)
524 else
525 xsltGenericError = xsltGenericErrorDefaultFunc;
526}
527
536static void LIBXSLT_ATTR_FORMAT(2,3)
537xsltGenericDebugDefaultFunc(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) {
539
541 return;
542
543 va_start(args, msg);
545 va_end(args);
546}
547
548xmlGenericErrorFunc xsltGenericDebug = xsltGenericDebugDefaultFunc;
550
551
565void
568 if (handler != NULL)
570 else
571 xsltGenericDebug = xsltGenericDebugDefaultFunc;
572}
573
582void
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
658void
661{
662 ctxt->error = handler;
663 ctxt->errctx = ctx;
664}
665
677void
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
719const xmlChar *
720xsltSplitQName(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
752const 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
826const 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
902void
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
937static xmlXPathObjectPtr *
939 int xfrm) {
940#ifdef XSLT_REFACTORED
941 xsltStyleItemSortPtr comp;
942#else
944#endif
945 xmlXPathObjectPtr *results = NULL;
946 xmlNodeSetPtr list = NULL;
947 xmlXPathObjectPtr res;
948 int len = 0;
949 int i;
950 xmlNodePtr oldNode;
951 xmlNodePtr oldInst;
952 int oldPos, oldSize ;
953 int oldNsNr;
954 xmlNsPtr *oldNamespaces;
955
956 comp = sort->psvi;
957 if (comp == NULL) {
959 "xsl:sort : compilation failed\n");
960 return(NULL);
961 }
962
963 if ((comp->select == NULL) || (comp->comp == NULL))
964 return(NULL);
965
966 list = ctxt->nodeList;
967 if ((list == NULL) || (list->nodeNr <= 1))
968 return(NULL);
969
970 len = list->nodeNr;
971
972 /* TODO: xsl:sort lang attribute */
973 /* TODO: xsl:sort case-order attribute */
974
975
976 results = xmlMalloc(len * sizeof(xmlXPathObjectPtr));
977 if (results == NULL) {
979 "xsltComputeSortResult: memory allocation failure\n");
980 return(NULL);
981 }
982
983 oldNode = ctxt->node;
984 oldInst = ctxt->inst;
985 oldPos = ctxt->xpathCtxt->proximityPosition;
986 oldSize = ctxt->xpathCtxt->contextSize;
987 oldNsNr = ctxt->xpathCtxt->nsNr;
988 oldNamespaces = ctxt->xpathCtxt->namespaces;
989 for (i = 0;i < len;i++) {
990 ctxt->inst = sort;
991 ctxt->xpathCtxt->contextSize = len;
992 ctxt->xpathCtxt->proximityPosition = i + 1;
993 ctxt->node = list->nodeTab[i];
994 ctxt->xpathCtxt->node = ctxt->node;
995#ifdef XSLT_REFACTORED
996 if (comp->inScopeNs != NULL) {
997 ctxt->xpathCtxt->namespaces = comp->inScopeNs->list;
998 ctxt->xpathCtxt->nsNr = comp->inScopeNs->xpathNumber;
999 } else {
1000 ctxt->xpathCtxt->namespaces = NULL;
1001 ctxt->xpathCtxt->nsNr = 0;
1002 }
1003#else
1004 ctxt->xpathCtxt->namespaces = comp->nsList;
1005 ctxt->xpathCtxt->nsNr = comp->nsNr;
1006#endif
1007 res = xmlXPathCompiledEval(comp->comp, ctxt->xpathCtxt);
1008 if (res != NULL) {
1009 if (res->type != XPATH_STRING)
1010 res = xmlXPathConvertString(res);
1011 if (comp->number)
1012 res = xmlXPathConvertNumber(res);
1013 res->index = i; /* Save original pos for dupl resolv */
1014 if (comp->number) {
1015 if (res->type == XPATH_NUMBER) {
1016 results[i] = res;
1017 } else {
1018#ifdef WITH_XSLT_DEBUG_PROCESS
1020 "xsltComputeSortResult: select didn't evaluate to a number\n");
1021#endif
1022 results[i] = NULL;
1023 }
1024 } else {
1025 if (res->type == XPATH_STRING) {
1026 if ((xfrm) && (comp->locale != (xsltLocale)0)) {
1027 xmlChar *str = res->stringval;
1028 res->stringval = (xmlChar *) xsltStrxfrm(comp->locale, str);
1029 xmlFree(str);
1030 }
1031
1032 results[i] = res;
1033 } else {
1034#ifdef WITH_XSLT_DEBUG_PROCESS
1036 "xsltComputeSortResult: select didn't evaluate to a string\n");
1037#endif
1038 results[i] = NULL;
1039 }
1040 }
1041 } else {
1042 ctxt->state = XSLT_STATE_STOPPED;
1043 results[i] = NULL;
1044 }
1045 }
1046 ctxt->node = oldNode;
1047 ctxt->inst = oldInst;
1048 ctxt->xpathCtxt->contextSize = oldSize;
1049 ctxt->xpathCtxt->proximityPosition = oldPos;
1050 ctxt->xpathCtxt->nsNr = oldNsNr;
1051 ctxt->xpathCtxt->namespaces = oldNamespaces;
1052
1053 return(results);
1054}
1055
1066xmlXPathObjectPtr *
1068 return xsltComputeSortResultInternal(ctxt, sort, /* xfrm */ 0);
1069}
1070
1080void
1082 int nbsorts) {
1083#ifdef XSLT_REFACTORED
1084 xsltStyleItemSortPtr comp;
1085#else
1087#endif
1088 xmlXPathObjectPtr *resultsTab[XSLT_MAX_SORT];
1089 xmlXPathObjectPtr *results = NULL, *res;
1090 xmlNodeSetPtr list = NULL;
1091 int descending, number, desc, numb;
1092 int len = 0;
1093 int i, j, incr;
1094 int tst;
1095 int depth;
1097 xmlXPathObjectPtr tmp;
1098 int tempstype[XSLT_MAX_SORT], temporder[XSLT_MAX_SORT],
1099 templang[XSLT_MAX_SORT];
1100
1101 if ((ctxt == NULL) || (sorts == NULL) || (nbsorts <= 0) ||
1102 (nbsorts >= XSLT_MAX_SORT))
1103 return;
1104 if (sorts[0] == NULL)
1105 return;
1106 comp = sorts[0]->psvi;
1107 if (comp == NULL)
1108 return;
1109
1110 list = ctxt->nodeList;
1111 if ((list == NULL) || (list->nodeNr <= 1))
1112 return; /* nothing to do */
1113
1114 for (j = 0; j < nbsorts; j++) {
1115 comp = sorts[j]->psvi;
1116 tempstype[j] = 0;
1117 if ((comp->stype == NULL) && (comp->has_stype != 0)) {
1118 comp->stype =
1119 xsltEvalAttrValueTemplate(ctxt, sorts[j],
1120 (const xmlChar *) "data-type",
1121 NULL);
1122 if (comp->stype != NULL) {
1123 tempstype[j] = 1;
1124 if (xmlStrEqual(comp->stype, (const xmlChar *) "text"))
1125 comp->number = 0;
1126 else if (xmlStrEqual(comp->stype, (const xmlChar *) "number"))
1127 comp->number = 1;
1128 else {
1129 xsltTransformError(ctxt, NULL, sorts[j],
1130 "xsltDoSortFunction: no support for data-type = %s\n",
1131 comp->stype);
1132 comp->number = 0; /* use default */
1133 }
1134 }
1135 }
1136 temporder[j] = 0;
1137 if ((comp->order == NULL) && (comp->has_order != 0)) {
1138 comp->order = xsltEvalAttrValueTemplate(ctxt, sorts[j],
1139 (const xmlChar *) "order",
1140 NULL);
1141 if (comp->order != NULL) {
1142 temporder[j] = 1;
1143 if (xmlStrEqual(comp->order, (const xmlChar *) "ascending"))
1144 comp->descending = 0;
1145 else if (xmlStrEqual(comp->order,
1146 (const xmlChar *) "descending"))
1147 comp->descending = 1;
1148 else {
1149 xsltTransformError(ctxt, NULL, sorts[j],
1150 "xsltDoSortFunction: invalid value %s for order\n",
1151 comp->order);
1152 comp->descending = 0; /* use default */
1153 }
1154 }
1155 }
1156 templang[j] = 0;
1157 if ((comp->lang == NULL) && (comp->has_lang != 0)) {
1158 xmlChar *lang = xsltEvalAttrValueTemplate(ctxt, sorts[j],
1159 (xmlChar *) "lang",
1160 NULL);
1161 if (lang != NULL) {
1162 templang[j] = 1;
1163 comp->locale = xsltNewLocale(lang);
1164 xmlFree(lang);
1165 }
1166 }
1167 }
1168
1169 len = list->nodeNr;
1170
1171 resultsTab[0] = xsltComputeSortResultInternal(ctxt, sorts[0],
1172 /* xfrm */ 1);
1173 for (i = 1;i < XSLT_MAX_SORT;i++)
1174 resultsTab[i] = NULL;
1175
1176 results = resultsTab[0];
1177
1178 comp = sorts[0]->psvi;
1179 descending = comp->descending;
1180 number = comp->number;
1181 if (results == NULL)
1182 goto cleanup;
1183
1184 /* Shell's sort of node-set */
1185 for (incr = len / 2; incr > 0; incr /= 2) {
1186 for (i = incr; i < len; i++) {
1187 j = i - incr;
1188 if (results[i] == NULL)
1189 continue;
1190
1191 while (j >= 0) {
1192 if (results[j] == NULL)
1193 tst = 1;
1194 else {
1195 if (number) {
1196 /* We make NaN smaller than number in accordance
1197 with XSLT spec */
1198 if (xmlXPathIsNaN(results[j]->floatval)) {
1199 if (xmlXPathIsNaN(results[j + incr]->floatval))
1200 tst = 0;
1201 else
1202 tst = -1;
1203 } else if (xmlXPathIsNaN(results[j + incr]->floatval))
1204 tst = 1;
1205 else if (results[j]->floatval ==
1206 results[j + incr]->floatval)
1207 tst = 0;
1208 else if (results[j]->floatval >
1209 results[j + incr]->floatval)
1210 tst = 1;
1211 else tst = -1;
1212 } else if(comp->locale != (xsltLocale)0) {
1213 tst = xsltLocaleStrcmp(
1214 comp->locale,
1215 (xsltLocaleChar *) results[j]->stringval,
1216 (xsltLocaleChar *) results[j + incr]->stringval);
1217 } else {
1218 tst = xmlStrcmp(results[j]->stringval,
1219 results[j + incr]->stringval);
1220 }
1221 if (descending)
1222 tst = -tst;
1223 }
1224 if (tst == 0) {
1225 /*
1226 * Okay we need to use multi level sorts
1227 */
1228 depth = 1;
1229 while (depth < nbsorts) {
1230 if (sorts[depth] == NULL)
1231 break;
1232 comp = sorts[depth]->psvi;
1233 if (comp == NULL)
1234 break;
1235 desc = comp->descending;
1236 numb = comp->number;
1237
1238 /*
1239 * Compute the result of the next level for the
1240 * full set, this might be optimized ... or not
1241 */
1242 if (resultsTab[depth] == NULL)
1243 resultsTab[depth] =
1245 sorts[depth],
1246 /* xfrm */ 1);
1247 res = resultsTab[depth];
1248 if (res == NULL)
1249 break;
1250 if (res[j] == NULL) {
1251 if (res[j+incr] != NULL)
1252 tst = 1;
1253 } else if (res[j+incr] == NULL) {
1254 tst = -1;
1255 } else {
1256 if (numb) {
1257 /* We make NaN smaller than number in
1258 accordance with XSLT spec */
1259 if (xmlXPathIsNaN(res[j]->floatval)) {
1260 if (xmlXPathIsNaN(res[j +
1261 incr]->floatval))
1262 tst = 0;
1263 else
1264 tst = -1;
1265 } else if (xmlXPathIsNaN(res[j + incr]->
1266 floatval))
1267 tst = 1;
1268 else if (res[j]->floatval == res[j + incr]->
1269 floatval)
1270 tst = 0;
1271 else if (res[j]->floatval >
1272 res[j + incr]->floatval)
1273 tst = 1;
1274 else tst = -1;
1275 } else if(comp->locale != (xsltLocale)0) {
1276 tst = xsltLocaleStrcmp(
1277 comp->locale,
1278 (xsltLocaleChar *) res[j]->stringval,
1279 (xsltLocaleChar *) res[j + incr]->stringval);
1280 } else {
1281 tst = xmlStrcmp(res[j]->stringval,
1282 res[j + incr]->stringval);
1283 }
1284 if (desc)
1285 tst = -tst;
1286 }
1287
1288 /*
1289 * if we still can't differenciate at this level
1290 * try one level deeper.
1291 */
1292 if (tst != 0)
1293 break;
1294 depth++;
1295 }
1296 }
1297 if (tst == 0) {
1298 tst = results[j]->index > results[j + incr]->index;
1299 }
1300 if (tst > 0) {
1301 tmp = results[j];
1302 results[j] = results[j + incr];
1303 results[j + incr] = tmp;
1304 node = list->nodeTab[j];
1305 list->nodeTab[j] = list->nodeTab[j + incr];
1306 list->nodeTab[j + incr] = node;
1307 depth = 1;
1308 while (depth < nbsorts) {
1309 if (sorts[depth] == NULL)
1310 break;
1311 if (resultsTab[depth] == NULL)
1312 break;
1313 res = resultsTab[depth];
1314 tmp = res[j];
1315 res[j] = res[j + incr];
1316 res[j + incr] = tmp;
1317 depth++;
1318 }
1319 j -= incr;
1320 } else
1321 break;
1322 }
1323 }
1324 }
1325
1326cleanup:
1327 for (j = 0; j < nbsorts; j++) {
1328 comp = sorts[j]->psvi;
1329 if (tempstype[j] == 1) {
1330 /* The data-type needs to be recomputed each time */
1331 xmlFree((void *)(comp->stype));
1332 comp->stype = NULL;
1333 }
1334 if (temporder[j] == 1) {
1335 /* The order needs to be recomputed each time */
1336 xmlFree((void *)(comp->order));
1337 comp->order = NULL;
1338 }
1339 if (templang[j] == 1) {
1340 xsltFreeLocale(comp->locale);
1341 comp->locale = (xsltLocale)0;
1342 }
1343 if (resultsTab[j] != NULL) {
1344 for (i = 0;i < len;i++)
1345 xmlXPathFreeObject(resultsTab[j][i]);
1346 xmlFree(resultsTab[j]);
1347 }
1348 }
1349}
1350
1351
1353
1368void
1370 int nbsorts)
1371{
1372 if (ctxt->sortfunc != NULL)
1373 (ctxt->sortfunc)(ctxt, sorts, nbsorts);
1374 else if (xsltSortFunction != NULL)
1375 xsltSortFunction(ctxt, sorts, nbsorts);
1376}
1377
1385void
1387 if (handler != NULL)
1389 else
1391}
1392
1403void
1405 ctxt->sortfunc = handler;
1406}
1407
1408/************************************************************************
1409 * *
1410 * Parsing options *
1411 * *
1412 ************************************************************************/
1413
1424int
1426{
1427 int oldopts;
1428
1429 if (ctxt == NULL)
1430 return(-1);
1431 oldopts = ctxt->parserOptions;
1432 if (ctxt->xinclude)
1433 oldopts |= XML_PARSE_XINCLUDE;
1434 ctxt->parserOptions = options;
1436 ctxt->xinclude = 1;
1437 else
1438 ctxt->xinclude = 0;
1439 return(oldopts);
1440}
1441
1442/************************************************************************
1443 * *
1444 * Output *
1445 * *
1446 ************************************************************************/
1447
1459int
1462 const xmlChar *encoding;
1463 int base;
1464 const xmlChar *method;
1465 int indent;
1466
1467 if ((buf == NULL) || (result == NULL) || (style == NULL))
1468 return(-1);
1469 if ((result->children == NULL) ||
1470 ((result->children->type == XML_DTD_NODE) &&
1471 (result->children->next == NULL)))
1472 return(0);
1473
1474 if ((style->methodURI != NULL) &&
1475 ((style->method == NULL) ||
1476 (!xmlStrEqual(style->method, (const xmlChar *) "xhtml")))) {
1478 "xsltSaveResultTo : unknown output method\n");
1479 return(-1);
1480 }
1481
1482 base = buf->written;
1483
1487
1488 if ((method == NULL) && (result->type == XML_HTML_DOCUMENT_NODE))
1489 method = (const xmlChar *) "html";
1490
1491 if ((method != NULL) &&
1492 (xmlStrEqual(method, (const xmlChar *) "html"))) {
1493 if (encoding != NULL) {
1494 htmlSetMetaEncoding(result, (const xmlChar *) encoding);
1495 } else {
1496 htmlSetMetaEncoding(result, (const xmlChar *) "UTF-8");
1497 }
1498 if (indent == -1)
1499 indent = 1;
1500 htmlDocContentDumpFormatOutput(buf, result, (const char *) encoding,
1501 indent);
1502 xmlOutputBufferFlush(buf);
1503 } else if ((method != NULL) &&
1504 (xmlStrEqual(method, (const xmlChar *) "xhtml"))) {
1505 if (encoding != NULL) {
1506 htmlSetMetaEncoding(result, (const xmlChar *) encoding);
1507 } else {
1508 htmlSetMetaEncoding(result, (const xmlChar *) "UTF-8");
1509 }
1510 htmlDocContentDumpOutput(buf, result, (const char *) encoding);
1511 xmlOutputBufferFlush(buf);
1512 } else if ((method != NULL) &&
1513 (xmlStrEqual(method, (const xmlChar *) "text"))) {
1515
1516 cur = result->children;
1517 while (cur != NULL) {
1518 if (cur->type == XML_TEXT_NODE)
1519 xmlOutputBufferWriteString(buf, (const char *) cur->content);
1520
1521 /*
1522 * Skip to next node
1523 */
1524 if (cur->children != NULL) {
1525 if ((cur->children->type != XML_ENTITY_DECL) &&
1526 (cur->children->type != XML_ENTITY_REF_NODE) &&
1527 (cur->children->type != XML_ENTITY_NODE)) {
1528 cur = cur->children;
1529 continue;
1530 }
1531 }
1532 if (cur->next != NULL) {
1533 cur = cur->next;
1534 continue;
1535 }
1536
1537 do {
1538 cur = cur->parent;
1539 if (cur == NULL)
1540 break;
1541 if (cur == (xmlNodePtr) style->doc) {
1542 cur = NULL;
1543 break;
1544 }
1545 if (cur->next != NULL) {
1546 cur = cur->next;
1547 break;
1548 }
1549 } while (cur != NULL);
1550 }
1551 xmlOutputBufferFlush(buf);
1552 } else {
1553 int omitXmlDecl;
1554 int standalone;
1555
1556 XSLT_GET_IMPORT_INT(omitXmlDecl, style, omitXmlDeclaration);
1557 XSLT_GET_IMPORT_INT(standalone, style, standalone);
1558
1559 if (omitXmlDecl != 1) {
1560 xmlOutputBufferWriteString(buf, "<?xml version=");
1561 if (result->version != NULL) {
1562 xmlOutputBufferWriteString(buf, "\"");
1563 xmlOutputBufferWriteString(buf, (const char *)result->version);
1564 xmlOutputBufferWriteString(buf, "\"");
1565 } else
1566 xmlOutputBufferWriteString(buf, "\"1.0\"");
1567 if (encoding == NULL) {
1568 if (result->encoding != NULL)
1569 encoding = result->encoding;
1570 else if (result->charset != XML_CHAR_ENCODING_UTF8)
1571 encoding = (const xmlChar *)
1573 result->charset);
1574 }
1575 if (encoding != NULL) {
1576 xmlOutputBufferWriteString(buf, " encoding=");
1577 xmlOutputBufferWriteString(buf, "\"");
1578 xmlOutputBufferWriteString(buf, (const char *) encoding);
1579 xmlOutputBufferWriteString(buf, "\"");
1580 }
1581 switch (standalone) {
1582 case 0:
1583 xmlOutputBufferWriteString(buf, " standalone=\"no\"");
1584 break;
1585 case 1:
1586 xmlOutputBufferWriteString(buf, " standalone=\"yes\"");
1587 break;
1588 default:
1589 break;
1590 }
1591 xmlOutputBufferWriteString(buf, "?>\n");
1592 }
1593 if (result->children != NULL) {
1594 xmlNodePtr children = result->children;
1595 xmlNodePtr child = children;
1596
1597 /*
1598 * Hack to avoid quadratic behavior when scanning
1599 * result->children in xmlGetIntSubset called by
1600 * xmlNodeDumpOutput.
1601 */
1602 result->children = NULL;
1603
1604 while (child != NULL) {
1605 xmlNodeDumpOutput(buf, result, child, 0, (indent == 1),
1606 (const char *) encoding);
1607 if (indent && ((child->type == XML_DTD_NODE) ||
1608 ((child->type == XML_COMMENT_NODE) &&
1609 (child->next != NULL))))
1610 xmlOutputBufferWriteString(buf, "\n");
1611 child = child->next;
1612 }
1613 if (indent)
1614 xmlOutputBufferWriteString(buf, "\n");
1615
1616 result->children = children;
1617 }
1618 xmlOutputBufferFlush(buf);
1619 }
1620 return(buf->written - base);
1621}
1622
1635int
1639 const xmlChar *encoding;
1640 int ret;
1641
1642 if ((URL == NULL) || (result == NULL) || (style == NULL))
1643 return(-1);
1644 if (result->children == NULL)
1645 return(0);
1646
1648 if (encoding != NULL) {
1650
1651 encoder = xmlFindCharEncodingHandler((char *)encoding);
1652 if ((encoder != NULL) &&
1653 (xmlStrEqual((const xmlChar *)encoder->name,
1654 (const xmlChar *) "UTF-8")))
1655 encoder = NULL;
1656 buf = xmlOutputBufferCreateFilename(URL, encoder, compression);
1657 } else {
1658 buf = xmlOutputBufferCreateFilename(URL, NULL, compression);
1659 }
1660 if (buf == NULL)
1661 return(-1);
1663 ret = xmlOutputBufferClose(buf);
1664 return(ret);
1665}
1666
1679int
1682 const xmlChar *encoding;
1683 int ret;
1684
1685 if ((file == NULL) || (result == NULL) || (style == NULL))
1686 return(-1);
1687 if (result->children == NULL)
1688 return(0);
1689
1691 if (encoding != NULL) {
1693
1694 encoder = xmlFindCharEncodingHandler((char *)encoding);
1695 if ((encoder != NULL) &&
1696 (xmlStrEqual((const xmlChar *)encoder->name,
1697 (const xmlChar *) "UTF-8")))
1698 encoder = NULL;
1699 buf = xmlOutputBufferCreateFile(file, encoder);
1700 } else {
1701 buf = xmlOutputBufferCreateFile(file, NULL);
1702 }
1703
1704 if (buf == NULL)
1705 return(-1);
1707 ret = xmlOutputBufferClose(buf);
1708 return(ret);
1709}
1710
1723int
1726 const xmlChar *encoding;
1727 int ret;
1728
1729 if ((fd < 0) || (result == NULL) || (style == NULL))
1730 return(-1);
1731 if (result->children == NULL)
1732 return(0);
1733
1735 if (encoding != NULL) {
1737
1738 encoder = xmlFindCharEncodingHandler((char *)encoding);
1739 if ((encoder != NULL) &&
1740 (xmlStrEqual((const xmlChar *)encoder->name,
1741 (const xmlChar *) "UTF-8")))
1742 encoder = NULL;
1743 buf = xmlOutputBufferCreateFd(fd, encoder);
1744 } else {
1745 buf = xmlOutputBufferCreateFd(fd, NULL);
1746 }
1747 if (buf == NULL)
1748 return(-1);
1750 ret = xmlOutputBufferClose(buf);
1751 return(ret);
1752}
1753
1766int
1767xsltSaveResultToString(xmlChar **doc_txt_ptr, int * doc_txt_len,
1770 const xmlChar *encoding;
1771
1772 *doc_txt_ptr = NULL;
1773 *doc_txt_len = 0;
1774 if (result->children == NULL)
1775 return(0);
1776
1778 if (encoding != NULL) {
1780
1781 encoder = xmlFindCharEncodingHandler((char *)encoding);
1782 if ((encoder != NULL) &&
1783 (xmlStrEqual((const xmlChar *)encoder->name,
1784 (const xmlChar *) "UTF-8")))
1785 encoder = NULL;
1786 buf = xmlAllocOutputBuffer(encoder);
1787 } else {
1788 buf = xmlAllocOutputBuffer(NULL);
1789 }
1790 if (buf == NULL)
1791 return(-1);
1793#ifdef LIBXML2_NEW_BUFFER
1794 if (buf->conv != NULL) {
1795 *doc_txt_len = xmlBufUse(buf->conv);
1796 *doc_txt_ptr = xmlStrndup(xmlBufContent(buf->conv), *doc_txt_len);
1797 } else {
1798 *doc_txt_len = xmlBufUse(buf->buffer);
1799 *doc_txt_ptr = xmlStrndup(xmlBufContent(buf->buffer), *doc_txt_len);
1800 }
1801#else
1802 if (buf->conv != NULL) {
1803 *doc_txt_len = buf->conv->use;
1804 *doc_txt_ptr = xmlStrndup(buf->conv->content, *doc_txt_len);
1805 } else {
1806 *doc_txt_len = buf->buffer->use;
1807 *doc_txt_ptr = xmlStrndup(buf->buffer->content, *doc_txt_len);
1808 }
1809#endif
1810 (void)xmlOutputBufferClose(buf);
1811 return 0;
1812}
1813
1814#ifdef WITH_PROFILER
1815
1816/************************************************************************
1817 * *
1818 * Generating profiling information *
1819 * *
1820 ************************************************************************/
1821
1822static long calibration = -1;
1823
1832#if !defined(XSLT_WIN32_PERFORMANCE_COUNTER) && \
1833 (defined(HAVE_CLOCK_GETTIME) || defined(HAVE_GETTIMEOFDAY))
1834static long
1835xsltCalibrateTimestamps(void) {
1836 register int i;
1837
1838 for (i = 0;i < 999;i++)
1839 xsltTimestamp();
1840 return(xsltTimestamp() / 1000);
1841}
1842#endif
1843
1850void
1851xsltCalibrateAdjust(long delta) {
1852 calibration += delta;
1853}
1854
1863long
1864xsltTimestamp(void)
1865{
1866#ifdef XSLT_WIN32_PERFORMANCE_COUNTER
1867 BOOL ok;
1868 LARGE_INTEGER performanceCount;
1869 LARGE_INTEGER performanceFrequency;
1870 LONGLONG quadCount;
1871 double seconds;
1872 static LONGLONG startupQuadCount = 0;
1873 static LONGLONG startupQuadFreq = 0;
1874
1875 ok = QueryPerformanceCounter(&performanceCount);
1876 if (!ok)
1877 return 0;
1878 quadCount = performanceCount.QuadPart;
1879 if (calibration < 0) {
1880 calibration = 0;
1881 ok = QueryPerformanceFrequency(&performanceFrequency);
1882 if (!ok)
1883 return 0;
1884 startupQuadFreq = performanceFrequency.QuadPart;
1885 startupQuadCount = quadCount;
1886 return (0);
1887 }
1888 if (startupQuadFreq == 0)
1889 return 0;
1890 seconds = (quadCount - startupQuadCount) / (double) startupQuadFreq;
1891 return (long) (seconds * XSLT_TIMESTAMP_TICS_PER_SEC);
1892
1893#else /* XSLT_WIN32_PERFORMANCE_COUNTER */
1894#ifdef HAVE_CLOCK_GETTIME
1895# if defined(CLOCK_MONOTONIC)
1896# define XSLT_CLOCK CLOCK_MONOTONIC
1897# elif defined(CLOCK_HIGHRES)
1898# define XSLT_CLOCK CLOCK_HIGHRES
1899# else
1900# define XSLT_CLOCK CLOCK_REALTIME
1901# endif
1902 static struct timespec startup;
1903 struct timespec cur;
1904 long tics;
1905
1906 if (calibration < 0) {
1907 clock_gettime(XSLT_CLOCK, &startup);
1908 calibration = 0;
1909 calibration = xsltCalibrateTimestamps();
1910 clock_gettime(XSLT_CLOCK, &startup);
1911 return (0);
1912 }
1913
1914 clock_gettime(XSLT_CLOCK, &cur);
1915 tics = (cur.tv_sec - startup.tv_sec) * XSLT_TIMESTAMP_TICS_PER_SEC;
1916 tics += (cur.tv_nsec - startup.tv_nsec) /
1917 (1000000000l / XSLT_TIMESTAMP_TICS_PER_SEC);
1918
1919 tics -= calibration;
1920 return(tics);
1921
1922#elif HAVE_GETTIMEOFDAY
1923 static struct timeval startup;
1924 struct timeval cur;
1925 long tics;
1926
1927 if (calibration < 0) {
1929 calibration = 0;
1930 calibration = xsltCalibrateTimestamps();
1932 return (0);
1933 }
1934
1936 tics = (cur.tv_sec - startup.tv_sec) * XSLT_TIMESTAMP_TICS_PER_SEC;
1937 tics += (cur.tv_usec - startup.tv_usec) /
1938 (1000000l / XSLT_TIMESTAMP_TICS_PER_SEC);
1939
1940 tics -= calibration;
1941 return(tics);
1942#else
1943
1944 /* Neither gettimeofday() nor Win32 performance counter available */
1945
1946 return (0);
1947
1948#endif /* HAVE_GETTIMEOFDAY */
1949#endif /* XSLT_WIN32_PERFORMANCE_COUNTER */
1950}
1951
1952static char *
1953pretty_templ_match(xsltTemplatePtr templ) {
1954 static char dst[1001];
1955 char *src = (char *)templ->match;
1956 int i=0,j;
1957
1958 /* strip white spaces */
1959 for (j=0; i<1000 && src[j]; i++,j++) {
1960 for(;src[j]==' ';j++);
1961 dst[i]=src[j];
1962 }
1963 if(i<998 && templ->mode) {
1964 /* append [mode] */
1965 dst[i++]='[';
1966 src=(char *)templ->mode;
1967 for (j=0; i<999 && src[j]; i++,j++) {
1968 dst[i]=src[j];
1969 }
1970 dst[i++]=']';
1971 }
1972 dst[i]='\0';
1973 return dst;
1974}
1975
1976#define MAX_TEMPLATES 10000
1977
1985void
1987 int nb, i,j,k,l;
1988 int max;
1989 int total;
1990 unsigned long totalt;
1993 xsltTemplatePtr templ1,templ2;
1994 int *childt;
1995
1996 if ((output == NULL) || (ctxt == NULL))
1997 return;
1998 if (ctxt->profile == 0)
1999 return;
2000
2001 nb = 0;
2004 if (templates == NULL)
2005 return;
2006
2007 style = ctxt->style;
2008 while (style != NULL) {
2009 templ1 = style->templates;
2010 while (templ1 != NULL) {
2011 if (nb >= max)
2012 break;
2013
2014 if (templ1->nbCalls > 0)
2015 templates[nb++] = templ1;
2016 templ1 = templ1->next;
2017 }
2018
2020 }
2021
2022 for (i = 0;i < nb -1;i++) {
2023 for (j = i + 1; j < nb; j++) {
2024 if ((templates[i]->time <= templates[j]->time) ||
2025 ((templates[i]->time == templates[j]->time) &&
2026 (templates[i]->nbCalls <= templates[j]->nbCalls))) {
2027 templ1 = templates[j];
2028 templates[j] = templates[i];
2029 templates[i] = templ1;
2030 }
2031 }
2032 }
2033
2034
2035 /* print flat profile */
2036
2037 fprintf(output, "%6s%20s%20s%10s Calls Tot 100us Avg\n\n",
2038 "number", "match", "name", "mode");
2039 total = 0;
2040 totalt = 0;
2041 for (i = 0;i < nb;i++) {
2042 templ1 = templates[i];
2043 fprintf(output, "%5d ", i);
2044 if (templ1->match != NULL) {
2045 if (xmlStrlen(templ1->match) > 20)
2046 fprintf(output, "%s\n%26s", templ1->match, "");
2047 else
2048 fprintf(output, "%20s", templ1->match);
2049 } else {
2050 fprintf(output, "%20s", "");
2051 }
2052 if (templ1->name != NULL) {
2053 if (xmlStrlen(templ1->name) > 20)
2054 fprintf(output, "%s\n%46s", templ1->name, "");
2055 else
2056 fprintf(output, "%20s", templ1->name);
2057 } else {
2058 fprintf(output, "%20s", "");
2059 }
2060 if (templ1->mode != NULL) {
2061 if (xmlStrlen(templ1->mode) > 10)
2062 fprintf(output, "%s\n%56s", templ1->mode, "");
2063 else
2064 fprintf(output, "%10s", templ1->mode);
2065 } else {
2066 fprintf(output, "%10s", "");
2067 }
2068 fprintf(output, " %6d", templ1->nbCalls);
2069 fprintf(output, " %6ld %6ld\n", templ1->time,
2070 templ1->time / templ1->nbCalls);
2071 total += templ1->nbCalls;
2072 totalt += templ1->time;
2073 }
2074 fprintf(output, "\n%30s%26s %6d %6ld\n", "Total", "", total, totalt);
2075
2076
2077 /* print call graph */
2078
2079 childt = xmlMalloc((nb + 1) * sizeof(int));
2080 if (childt == NULL)
2081 return;
2082
2083 /* precalculate children times */
2084 for (i = 0; i < nb; i++) {
2085 templ1 = templates[i];
2086
2087 childt[i] = 0;
2088 for (k = 0; k < nb; k++) {
2089 templ2 = templates[k];
2090 for (l = 0; l < templ2->templNr; l++) {
2091 if (templ2->templCalledTab[l] == templ1) {
2092 childt[i] +=templ2->time;
2093 }
2094 }
2095 }
2096 }
2097 childt[i] = 0;
2098
2099 fprintf(output, "\nindex %% time self children called name\n");
2100
2101 for (i = 0; i < nb; i++) {
2102 char ix_str[20], timep_str[20], times_str[20], timec_str[20], called_str[20];
2103 unsigned long t;
2104
2105 templ1 = templates[i];
2106 /* callers */
2107 for (j = 0; j < templ1->templNr; j++) {
2108 templ2 = templ1->templCalledTab[j];
2109 for (k = 0; k < nb; k++) {
2110 if (templates[k] == templ2)
2111 break;
2112 }
2113 t=templ2?templ2->time:totalt;
2114 snprintf(times_str,sizeof(times_str),"%8.3f",(float)t/XSLT_TIMESTAMP_TICS_PER_SEC);
2115 snprintf(timec_str,sizeof(timec_str),"%8.3f",(float)childt[k]/XSLT_TIMESTAMP_TICS_PER_SEC);
2116 snprintf(called_str,sizeof(called_str),"%6d/%d",
2117 templ1->templCountTab[j], /* number of times caller calls 'this' */
2118 templ1->nbCalls); /* total number of calls to 'this' */
2119
2120 fprintf(output, " %-8s %-8s %-12s %s [%d]\n",
2121 times_str,timec_str,called_str,
2122 (templ2?(templ2->name?(char *)templ2->name:pretty_templ_match(templ2)):"-"),k);
2123 }
2124 /* this */
2125 snprintf(ix_str,sizeof(ix_str),"[%d]",i);
2126 snprintf(timep_str,sizeof(timep_str),"%6.2f",(float)templ1->time*100.0/totalt);
2127 snprintf(times_str,sizeof(times_str),"%8.3f",(float)templ1->time/XSLT_TIMESTAMP_TICS_PER_SEC);
2128 snprintf(timec_str,sizeof(timec_str),"%8.3f",(float)childt[i]/XSLT_TIMESTAMP_TICS_PER_SEC);
2129 fprintf(output, "%-5s %-6s %-8s %-8s %6d %s [%d]\n",
2130 ix_str, timep_str,times_str,timec_str,
2131 templ1->nbCalls,
2132 templ1->name?(char *)templ1->name:pretty_templ_match(templ1),i);
2133 /* callees
2134 * - go over templates[0..nb] and their templCalledTab[]
2135 * - print those where we in the the call-stack
2136 */
2137 total = 0;
2138 for (k = 0; k < nb; k++) {
2139 templ2 = templates[k];
2140 for (l = 0; l < templ2->templNr; l++) {
2141 if (templ2->templCalledTab[l] == templ1) {
2142 total+=templ2->templCountTab[l];
2143 }
2144 }
2145 }
2146 for (k = 0; k < nb; k++) {
2147 templ2 = templates[k];
2148 for (l = 0; l < templ2->templNr; l++) {
2149 if (templ2->templCalledTab[l] == templ1) {
2150 snprintf(times_str,sizeof(times_str),"%8.3f",(float)templ2->time/XSLT_TIMESTAMP_TICS_PER_SEC);
2151 snprintf(timec_str,sizeof(timec_str),"%8.3f",(float)childt[k]/XSLT_TIMESTAMP_TICS_PER_SEC);
2152 snprintf(called_str,sizeof(called_str),"%6d/%d",
2153 templ2->templCountTab[l], /* number of times 'this' calls callee */
2154 total); /* total number of calls from 'this' */
2155 fprintf(output, " %-8s %-8s %-12s %s [%d]\n",
2156 times_str,timec_str,called_str,
2157 templ2->name?(char *)templ2->name:pretty_templ_match(templ2),k);
2158 }
2159 }
2160 }
2161 fprintf(output, "-----------------------------------------------\n");
2162 }
2163
2164 fprintf(output, "\f\nIndex by function name\n");
2165 for (i = 0; i < nb; i++) {
2166 templ1 = templates[i];
2167 fprintf(output, "[%d] %s (%s:%d)\n",
2168 i, templ1->name?(char *)templ1->name:pretty_templ_match(templ1),
2169 templ1->style->doc->URL,templ1->elem->line);
2170 }
2171
2172 fprintf(output, "\f\n");
2173 xmlFree(childt);
2174
2176}
2177
2178/************************************************************************
2179 * *
2180 * Fetching profiling information *
2181 * *
2182 ************************************************************************/
2183
2207{
2208 xmlDocPtr ret = NULL;
2210 char buf[100];
2211
2214 xsltTemplatePtr templ;
2215 int nb = 0, max = 0, i, j;
2216
2217 if (!ctxt)
2218 return NULL;
2219
2220 if (!ctxt->profile)
2221 return NULL;
2222
2223 nb = 0;
2224 max = 10000;
2225 templates =
2227 if (templates == NULL)
2228 return NULL;
2229
2230 /*
2231 * collect all the templates in an array
2232 */
2233 style = ctxt->style;
2234 while (style != NULL) {
2235 templ = style->templates;
2236 while (templ != NULL) {
2237 if (nb >= max)
2238 break;
2239
2240 if (templ->nbCalls > 0)
2241 templates[nb++] = templ;
2242 templ = templ->next;
2243 }
2244
2246 }
2247
2248 /*
2249 * Sort the array by time spent
2250 */
2251 for (i = 0; i < nb - 1; i++) {
2252 for (j = i + 1; j < nb; j++) {
2253 if ((templates[i]->time <= templates[j]->time) ||
2254 ((templates[i]->time == templates[j]->time) &&
2255 (templates[i]->nbCalls <= templates[j]->nbCalls))) {
2256 templ = templates[j];
2257 templates[j] = templates[i];
2258 templates[i] = templ;
2259 }
2260 }
2261 }
2262
2263 /*
2264 * Generate a document corresponding to the results.
2265 */
2266 ret = xmlNewDoc(BAD_CAST "1.0");
2267 root = xmlNewDocNode(ret, NULL, BAD_CAST "profile", NULL);
2268 xmlDocSetRootElement(ret, root);
2269
2270 for (i = 0; i < nb; i++) {
2271 child = xmlNewChild(root, NULL, BAD_CAST "template", NULL);
2272 snprintf(buf, sizeof(buf), "%d", i + 1);
2273 xmlSetProp(child, BAD_CAST "rank", BAD_CAST buf);
2274 xmlSetProp(child, BAD_CAST "match", BAD_CAST templates[i]->match);
2275 xmlSetProp(child, BAD_CAST "name", BAD_CAST templates[i]->name);
2276 xmlSetProp(child, BAD_CAST "mode", BAD_CAST templates[i]->mode);
2277
2278 snprintf(buf, sizeof(buf), "%d", templates[i]->nbCalls);
2279 xmlSetProp(child, BAD_CAST "calls", BAD_CAST buf);
2280
2281 snprintf(buf, sizeof(buf), "%ld", templates[i]->time);
2282 xmlSetProp(child, BAD_CAST "time", BAD_CAST buf);
2283
2284 snprintf(buf, sizeof(buf), "%ld", templates[i]->time / templates[i]->nbCalls);
2285 xmlSetProp(child, BAD_CAST "average", BAD_CAST buf);
2286 };
2287
2289
2290 return ret;
2291}
2292
2293#endif /* WITH_PROFILER */
2294
2295/************************************************************************
2296 * *
2297 * Hooks for libxml2 XPath *
2298 * *
2299 ************************************************************************/
2300
2312xmlXPathCompExprPtr
2314 xmlXPathContextPtr xpathCtxt;
2315 xmlXPathCompExprPtr ret;
2316
2317 if (style != NULL) {
2318 xpathCtxt = style->principal->xpathCtxt;
2319 if (xpathCtxt == NULL)
2320 return NULL;
2321 xpathCtxt->dict = style->dict;
2322 } else {
2323 xpathCtxt = xmlXPathNewContext(NULL);
2324 if (xpathCtxt == NULL)
2325 return NULL;
2326 }
2327 xpathCtxt->flags = flags;
2328
2329 /*
2330 * Compile the expression.
2331 */
2332 ret = xmlXPathCtxtCompile(xpathCtxt, str);
2333
2334 if (style == NULL) {
2335 xmlXPathFreeContext(xpathCtxt);
2336 }
2337 /*
2338 * TODO: there is a lot of optimizations which should be possible
2339 * like variable slot precomputations, function precomputations, etc.
2340 */
2341
2342 return(ret);
2343}
2344
2355xmlXPathCompExprPtr
2357 return(xsltXPathCompileFlags(style, str, 0));
2358}
2359
2360/************************************************************************
2361 * *
2362 * Hooks for the debugger *
2363 * *
2364 ************************************************************************/
2365
2367
2375int
2377{
2378 return(xslDebugStatus);
2379}
2380
2381#ifdef WITH_DEBUGGER
2382
2383/*
2384 * There is currently only 3 debugging callback defined
2385 * Debugger callbacks are disabled by default
2386 */
2387#define XSLT_CALLBACK_NUMBER 3
2388
2389typedef struct _xsltDebuggerCallbacks xsltDebuggerCallbacks;
2390typedef xsltDebuggerCallbacks *xsltDebuggerCallbacksPtr;
2391struct _xsltDebuggerCallbacks {
2395};
2396
2397static xsltDebuggerCallbacks xsltDebuggerCurrentCallbacks = {
2398 NULL, /* handler */
2399 NULL, /* add */
2400 NULL /* drop */
2401};
2402
2409void
2411{
2413}
2414
2426int
2428{
2429 xsltDebuggerCallbacksPtr callbacks;
2430
2431 if ((block == NULL) || (no != XSLT_CALLBACK_NUMBER))
2432 return(-1);
2433
2434 callbacks = (xsltDebuggerCallbacksPtr) block;
2435 xsltDebuggerCurrentCallbacks.handler = callbacks->handler;
2436 xsltDebuggerCurrentCallbacks.add = callbacks->add;
2437 xsltDebuggerCurrentCallbacks.drop = callbacks->drop;
2438 return(0);
2439}
2440
2452void
2455{
2456 if (xsltDebuggerCurrentCallbacks.handler != NULL)
2457 xsltDebuggerCurrentCallbacks.handler(cur, node, templ, ctxt);
2458}
2459
2469int
2471{
2472 if (xsltDebuggerCurrentCallbacks.add != NULL)
2473 return(xsltDebuggerCurrentCallbacks.add(templ, source));
2474 return(0);
2475}
2476
2482void
2483xslDropCall(void)
2484{
2485 if (xsltDebuggerCurrentCallbacks.drop != NULL)
2486 xsltDebuggerCurrentCallbacks.drop();
2487}
2488
2489#endif /* WITH_DEBUGGER */
2490
static struct _test_info results[8]
Definition: SetCursorPos.c:31
_STLP_MOVE_TO_STD_NAMESPACE void sort(_RandomAccessIter __first, _RandomAccessIter __last)
Definition: _algo.c:993
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
#define gettimeofday(tv, tz)
Definition: adns_win32.h:159
static void startup(void)
Arabic default style
Definition: afstyles.h:94
#define MAX_TEMPLATES
Definition: appearance.h:29
#define ok(value,...)
Definition: atltest.h:57
#define msg(x)
Definition: auth_time.c:54
struct _root root
_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:1365
r l[0]
Definition: byte_order.h:168
Definition: list.h:37
size_type size() const
Definition: _list.h:379
#define NULL
Definition: types.h:112
static const WCHAR indent[]
Definition: object.c:1156
static WCHAR no[MAX_STRING_RESOURCE_LEN]
Definition: object.c:2340
static void cleanup(void)
Definition: main.c:1335
BOOL WINAPI QueryPerformanceFrequency(OUT PLARGE_INTEGER lpFrequency)
Definition: perfcnt.c:45
BOOL WINAPI QueryPerformanceCounter(OUT PLARGE_INTEGER lpPerformanceCount)
Definition: perfcnt.c:23
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7482
method
Definition: dragdrop.c:54
XMLPUBFUN xmlCharEncodingHandlerPtr XMLCALL xmlFindCharEncodingHandler(const char *name)
Definition: encoding.c:1678
xmlCharEncoding
Definition: encoding.h:56
@ XML_CHAR_ENCODING_UTF8
Definition: encoding.h:59
XMLPUBFUN const char *XMLCALL xmlGetCharEncodingName(xmlCharEncoding enc)
Definition: encoding.c:1254
unsigned int BOOL
Definition: ntddk_ex.h:94
FxCollectionEntry * cur
size_t total
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble GLdouble t
Definition: gl.h:2047
GLuint res
Definition: glext.h:9613
GLenum src
Definition: glext.h:6340
const GLubyte * c
Definition: glext.h:8905
GLenum mode
Definition: glext.h:6217
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLenum dst
Definition: glext.h:6340
GLbitfield flags
Definition: glext.h:7161
GLenum GLsizei len
Definition: glext.h:6722
GLuint64EXT * result
Definition: glext.h:11304
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
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
#define ATTRIBUTE_UNUSED
Definition: i386-dis.c:36
xsltStylesheetPtr xsltNextImport(xsltStylesheetPtr cur)
Definition: imports.c:251
#define stderr
Definition: stdio.h:100
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
_Check_return_opt_ _CRTIMP int __cdecl vfprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format, va_list _ArgList)
#define c
Definition: ke_i.h:80
void MSVCRT() terminate()
char templates[]
Definition: meshbuilder.c:39
__u16 time
Definition: mkdosfs.c:8
#define error(str)
Definition: mkdosfs.c:1605
#define for
Definition: utility.h:88
static const WCHAR desc[]
Definition: protectdata.c:36
static unsigned int number
Definition: dsound.c:1479
static HWND child
Definition: cursoricon.c:298
static ATOM item
Definition: dde.c:856
int k
Definition: mpi.c:3369
const WCHAR * str
XMLPUBFUN const xmlChar *XMLCALL xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len)
Definition: dict.c:867
XMLPUBVAR xmlMallocFunc xmlMalloc
Definition: globals.h:248
XMLPUBVAR xmlFreeFunc xmlFree
Definition: globals.h:251
XMLPUBVAR xmlReallocFunc xmlRealloc
Definition: globals.h:250
@ XML_PARSE_XINCLUDE
Definition: parser.h:1103
XMLPUBFUN xmlChar *XMLCALL xmlGetProp(const xmlNode *node, const xmlChar *name)
XMLPUBFUN xmlNsPtr XMLCALL xmlSearchNs(xmlDocPtr doc, xmlNodePtr node, const xmlChar *nameSpace)
XMLPUBFUN xmlNodePtr XMLCALL xmlNewDocNode(xmlDocPtr doc, xmlNsPtr ns, const xmlChar *name, const xmlChar *content)
xmlOutputBuffer * xmlOutputBufferPtr
Definition: tree.h:32
XMLPUBFUN size_t XMLCALL xmlBufUse(const xmlBufPtr buf)
Definition: buf.c:633
XMLPUBFUN xmlDocPtr XMLCALL xmlNewDoc(const xmlChar *version)
XMLPUBFUN xmlChar *XMLCALL xmlGetNsProp(const xmlNode *node, const xmlChar *name, const xmlChar *nameSpace)
xmlDoc * xmlDocPtr
Definition: tree.h:550
@ XML_ENTITY_DECL
Definition: tree.h:176
@ XML_DOCUMENT_NODE
Definition: tree.h:168
@ XML_TEXT_NODE
Definition: tree.h:162
@ XML_ENTITY_NODE
Definition: tree.h:165
@ XML_COMMENT_NODE
Definition: tree.h:167
@ XML_DTD_NODE
Definition: tree.h:173
@ XML_NAMESPACE_DECL
Definition: tree.h:177
@ XML_HTML_DOCUMENT_NODE
Definition: tree.h:172
@ XML_ELEMENT_NODE
Definition: tree.h:160
@ XML_ENTITY_REF_NODE
Definition: tree.h:164
#define XML_XML_NAMESPACE
Definition: tree.h:140
XMLPUBFUN long XMLCALL xmlGetLineNo(const xmlNode *node)
XMLPUBFUN xmlChar *XMLCALL xmlBufContent(const xmlBuf *buf)
Definition: buf.c:553
XMLPUBFUN xmlChar *XMLCALL xmlNodeListGetString(xmlDocPtr doc, const xmlNode *list, int inLine)
#define XSLT_GET_IMPORT_INT(res, style, name)
Definition: imports.h:40
#define XSLT_GET_IMPORT_PTR(res, style, name)
Definition: imports.h:27
static int fd
Definition: io.c:51
#define memset(x, y, z)
Definition: compat.h:39
#define args
Definition: format.c:66
Definition: tree.h:434
xmlNs * ns
Definition: tree.h:444
struct _xmlNode * children
Definition: tree.h:438
struct _xmlAttr * next
Definition: tree.h:441
const xmlChar * name
Definition: tree.h:437
const xmlChar * defaultValue
Definition: tree.h:267
const xmlChar * prefix
Definition: tree.h:269
Definition: dict.c:111
Definition: tree.h:551
const xmlChar * URL
Definition: tree.h:577
struct _xmlDtd * intSubset
Definition: tree.h:570
struct _xmlDtd * extSubset
Definition: tree.h:571
Definition: tree.h:489
struct _xmlNode * children
Definition: tree.h:493
void * psvi
Definition: tree.h:505
unsigned short line
Definition: tree.h:506
Definition: tree.h:389
const xmlChar * href
Definition: tree.h:392
xmlNodePtr elem
struct _xsltTemplate * next
const xmlChar * name
const xmlChar * mode
unsigned long time
struct _xsltStylesheet * style
xsltTemplatePtr * templCalledTab
xmlChar * match
xsltTransformState state
xmlNodeSetPtr nodeList
xsltStylesheetPtr style
xmlGenericErrorFunc error
xmlXPathContextPtr xpathCtxt
Definition: match.c:390
Definition: fci.c:127
Definition: parser.c:49
Definition: match.c:28
Definition: tftpd.h:60
Definition: name.c:39
Definition: mxnamespace.c:45
Definition: time.h:88
#define max(a, b)
Definition: svc.c:63
xmlChar * xsltEvalAttrValueTemplate(xsltTransformContextPtr ctxt, xmlNodePtr inst, const xmlChar *name, const xmlChar *ns)
Definition: templates.c:392
xmlChar * xsltEvalTemplateString(xsltTransformContextPtr ctxt, xmlNodePtr contextNode, xmlNodePtr inst)
Definition: templates.c:189
XSLTPUBFUN void XSLTCALL xslHandleDebugger(xmlNodePtr cur, xmlNodePtr node, xsltTemplatePtr templ, xsltTransformContextPtr ctxt)
int64_t LONGLONG
Definition: typedefs.h:68
LONGLONG QuadPart
Definition: typedefs.h:114
Definition: dlist.c:348
Definition: pdh_main.c:94
XMLPUBFUN xmlAttributePtr XMLCALL xmlGetDtdAttrDesc(xmlDtdPtr dtd, const xmlChar *elem, const xmlChar *name)
Definition: valid.c:3379
static const WCHAR lang[]
Definition: wbemdisp.c:287
int ret
#define snprintf
Definition: wintirpc.h:48
void(XMLCDECL * xmlGenericErrorFunc)(void *ctx, const char *msg,...) LIBXML_ATTR_FORMAT(2
Definition: xmlerror.h:847
static char * encoding
Definition: xmllint.c:155
static int callbacks
Definition: xmllint.c:838
static unsigned int block
Definition: xmlmemory.c:101
XMLPUBFUN xmlChar *XMLCALL xmlStrndup(const xmlChar *cur, int len)
Definition: xmlstring.c:42
XMLPUBFUN xmlChar *XMLCALL xmlStrdup(const xmlChar *cur)
Definition: xmlstring.c:67
#define BAD_CAST
Definition: xmlstring.h:35
XMLPUBFUN int XMLCALL xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:160
XMLPUBFUN int XMLCALL xmlStrcmp(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:133
XMLPUBFUN int XMLCALL xmlStrlen(const xmlChar *str)
Definition: xmlstring.c:426
unsigned char xmlChar
Definition: xmlstring.h:28
void(* xsltSortFunc)(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, int nbsorts)
xsltStylesheet * xsltStylesheetPtr
@ XSLT_STATE_ERROR
@ XSLT_STATE_STOPPED
@ XSLT_STATE_OK
#define XSLT_MAX_SORT
#define LIBXSLT_ATTR_FORMAT(fmt, args)
Definition: xsltconfig.h:159
xsltLocaleChar * xsltStrxfrm(xsltLocale locale, const xmlChar *string)
Definition: xsltlocale.c:360
void xsltFreeLocale(xsltLocale locale)
Definition: xsltlocale.c:342
xsltLocale xsltNewLocale(const xmlChar *languageTag)
Definition: xsltlocale.c:82
int xsltLocaleStrcmp(xsltLocale locale, const xsltLocaleChar *str1, const xsltLocaleChar *str2)
Definition: xsltlocale.c:423
void * xsltLocale
Definition: xsltlocale.h:63
xmlChar xsltLocaleChar
Definition: xsltlocale.h:64
void xsltDoSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, int nbsorts)
Definition: xsltutils.c:1369
const xmlChar * xsltGetQNameURI(xmlNodePtr node, xmlChar **name)
Definition: xsltutils.c:753
void xsltTransformError(xsltTransformContextPtr ctxt, xsltStylesheetPtr style, xmlNodePtr node, const char *msg,...)
Definition: xsltutils.c:678
xmlXPathCompExprPtr xsltXPathCompileFlags(xsltStylesheetPtr style, const xmlChar *str, int flags)
Definition: xsltutils.c:2313
xmlXPathObjectPtr * xsltComputeSortResult(xsltTransformContextPtr ctxt, xmlNodePtr sort)
Definition: xsltutils.c:1067
int xsltGetDebuggerStatus(void)
Definition: xsltutils.c:2376
static xmlXPathObjectPtr * xsltComputeSortResultInternal(xsltTransformContextPtr ctxt, xmlNodePtr sort, int xfrm)
Definition: xsltutils.c:938
xmlGenericErrorFunc xsltGenericError
Definition: xsltutils.c:502
void xsltDocumentSortFunction(xmlNodeSetPtr list)
Definition: xsltutils.c:903
void xsltSetGenericDebugFunc(void *ctx, xmlGenericErrorFunc handler)
Definition: xsltutils.c:566
const xmlChar * xsltGetCNsProp(xsltStylesheetPtr style, xmlNodePtr node, const xmlChar *name, const xmlChar *nameSpace)
Definition: xsltutils.c:52
static xsltSortFunc xsltSortFunction
Definition: xsltutils.c:1352
int xsltSaveResultToFd(int fd, xmlDocPtr result, xsltStylesheetPtr style)
Definition: xsltutils.c:1724
xmlXPathCompExprPtr xsltXPathCompile(xsltStylesheetPtr style, const xmlChar *str)
Definition: xsltutils.c:2356
int xsltSetCtxtParseOptions(xsltTransformContextPtr ctxt, int options)
Definition: xsltutils.c:1425
xmlGenericErrorFunc xsltGenericDebug
Definition: xsltutils.c:548
#define XSLT_GET_VAR_STR(msg, str)
Definition: xsltutils.c:453
int xsltGetUTF8Char(const unsigned char *utf, int *len)
Definition: xsltutils.c:227
void xsltDefaultSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, int nbsorts)
Definition: xsltutils.c:1081
const xmlChar * xsltGetQNameURI2(xsltStylesheetPtr style, xmlNodePtr node, const xmlChar **name)
Definition: xsltutils.c:827
void xsltSetTransformErrorFunc(xsltTransformContextPtr ctxt, void *ctx, xmlGenericErrorFunc handler)
Definition: xsltutils.c:659
void xsltPrintErrorContext(xsltTransformContextPtr ctxt, xsltStylesheetPtr style, xmlNodePtr node)
Definition: xsltutils.c:583
int xsltSaveResultToString(xmlChar **doc_txt_ptr, int *doc_txt_len, xmlDocPtr result, xsltStylesheetPtr style)
Definition: xsltutils.c:1767
int xsltSaveResultTo(xmlOutputBufferPtr buf, xmlDocPtr result, xsltStylesheetPtr style)
Definition: xsltutils.c:1460
int xsltSaveResultToFilename(const char *URL, xmlDocPtr result, xsltStylesheetPtr style, int compression)
Definition: xsltutils.c:1636
void xsltSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc handler)
Definition: xsltutils.c:520
int xslDebugStatus
Definition: xsltutils.c:2366
void * xsltGenericDebugContext
Definition: xsltutils.c:549
void xsltSetCtxtSortFunc(xsltTransformContextPtr ctxt, xsltSortFunc handler)
Definition: xsltutils.c:1404
void * xsltGenericErrorContext
Definition: xsltutils.c:503
const xmlChar * xsltSplitQName(xmlDictPtr dict, const xmlChar *name, const xmlChar **prefix)
Definition: xsltutils.c:720
void xsltSetSortFunc(xsltSortFunc handler)
Definition: xsltutils.c:1386
int xsltSaveResultToFile(FILE *file, xmlDocPtr result, xsltStylesheetPtr style)
Definition: xsltutils.c:1680
xmlChar * xsltGetNsProp(xmlNodePtr node, const xmlChar *name, const xmlChar *nameSpace)
Definition: xsltutils.c:142
void xsltMessage(xsltTransformContextPtr ctxt, xmlNodePtr node, xmlNodePtr inst)
Definition: xsltutils.c:408
XSLTPUBFUN void XSLTCALL xslDropCall(void)
XSLTPUBFUN void XSLTCALL xsltSaveProfiling(xsltTransformContextPtr ctxt, FILE *output)
XSLTPUBFUN int XSLTCALL xslAddCall(xsltTemplatePtr templ, xmlNodePtr source)
XSLTPUBFUN void XSLTCALL xsltSetDebuggerStatus(int value)
int(* xsltAddCallCallback)(xsltTemplatePtr templ, xmlNodePtr source)
Definition: xsltutils.h:289
void(* xsltHandleDebuggerCallback)(xmlNodePtr cur, xmlNodePtr node, xsltTemplatePtr templ, xsltTransformContextPtr ctxt)
Definition: xsltutils.h:287
XSLTPUBFUN void XSLTCALL xsltCalibrateAdjust(long delta)
void(* xsltDropCallCallback)(void)
Definition: xsltutils.h:290
XSLTPUBFUN xmlDocPtr XSLTCALL xsltGetProfileInformation(xsltTransformContextPtr ctxt)
#define XSLT_TIMESTAMP_TICS_PER_SEC
Definition: xsltutils.h:266
XSLTPUBFUN long XSLTCALL xsltTimestamp(void)
XSLTPUBFUN int XSLTCALL xsltSetDebuggerCallbacks(int no, void *block)
#define const
Definition: zconf.h:233