19 #pragma convert("ISO8859-1") 29 #ifdef HAVE_SYS_TYPES_H 52 #ifdef LIBXML_XPTR_ENABLED 55 #ifdef LIBXML_DEBUG_ENABLED 61 #ifdef LIBXML_PATTERN_ENABLED 67 #ifdef LIBXML_PATTERN_ENABLED 68 #define XPATH_STREAMING 72 xmlGenericError(xmlGenericErrorContext, \ 73 "Unimplemented block at %s:%d\n", \ 94 #define XP_OPTIMIZED_NON_ELEM_COMPARISON 101 #define XP_OPTIMIZED_FILTER_FIRST 117 #define XPATH_MAX_STEPS 1000000 126 #define XPATH_MAX_STACK_DEPTH 1000000 136 #define XPATH_MAX_NODESET_LENGTH 10000000 145 #ifdef XP_OPTIMIZED_NON_ELEM_COMPARISON 160 int misc = 0, precedence1 = 0, precedence2 = 0;
165 if ((node1 ==
NULL) || (node2 ==
NULL))
174 switch (node1->
type) {
179 (node1->
doc == node2->
doc))
188 goto turtle_comparison;
245 switch (node2->
type) {
291 if (node1 == node2) {
292 if (precedence1 == precedence2) {
297 cur = miscNode2->prev;
299 if (
cur == miscNode1)
312 if (precedence1 < precedence2)
327 if ((precedence2 == 3) && (precedence1 > 1)) {
335 if ((precedence1 == 3) && (precedence2 > 1)) {
352 (node1->
doc == node2->
doc)) {
364 if (node1 == node2->
prev)
366 if (node1 == node2->
next)
372 if (
cur->parent == node1)
378 if (
cur->parent == node2)
391 while (depth1 > depth2) {
395 while (depth2 > depth1) {
403 if ((node1 ==
NULL) || (node2 ==
NULL))
409 if (node1 == node2->
prev)
411 if (node1 == node2->
next)
420 (node1->
doc == node2->
doc)) {
441 #define SORT_NAME libxml_domnode 442 #define SORT_TYPE xmlNodePtr 455 #ifdef XP_OPTIMIZED_NON_ELEM_COMPARISON 464 int res = xmlXPathCmpNodes(
x,
y);
468 #define SORT_CMP(x, y) (wrap_cmp(x, y)) 472 #if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) 481 #define INFINITY (DBL_MAX * DBL_MAX) 485 #define NAN (INFINITY / INFINITY) 511 xmlXPathIsNaN(
double val) {
526 xmlXPathIsInf(
double val) {
540 #ifdef LIBXML_XPATH_ENABLED 546 #ifdef DEBUG_XPATH_EXPRESSION 549 #define DEBUG_EVAL_COUNTS 552 static xmlNs xmlXPathXMLNamespaceStruct = {
560 static xmlNsPtr xmlXPathXMLNamespace = &xmlXPathXMLNamespaceStruct;
561 #ifndef LIBXML_THREAD_ENABLED 566 static int xmlXPathDisableOptimizer = 0;
581 #define XP_ERRORNULL(X) \ 582 { xmlXPathErr(ctxt, X); return(NULL); } 587 static const char *xmlXPathErrorMessages[] = {
590 "Unfinished literal\n",
591 "Start of literal\n",
592 "Expected $ for variable reference\n",
593 "Undefined variable\n",
594 "Invalid predicate\n",
595 "Invalid expression\n",
596 "Missing closing curly brace\n",
597 "Unregistered function\n",
600 "Invalid number of arguments\n",
601 "Invalid context size\n",
602 "Invalid context position\n",
603 "Memory allocation error\n",
606 "Sub resource error\n",
607 "Undefined namespace prefix\n",
609 "Char out of XML range\n",
610 "Invalid or incomplete context\n",
611 "Stack usage error\n",
612 "Forbidden variable\n",
613 "Operation limit exceeded\n",
614 "Recursion limit exceeded\n",
615 "?? Unknown error ??\n" 617 #define MAXERRNO ((int)(sizeof(xmlXPathErrorMessages) / \ 618 sizeof(xmlXPathErrorMessages[0])) - 1) 627 xmlXPathErrMemory(xmlXPathContextPtr ctxt,
const char *
extra)
635 "Memory allocation failed : %s\n",
639 ctxt->lastError.message = (
char *)
644 if (ctxt->error !=
NULL)
645 ctxt->error(ctxt->userData, &ctxt->lastError);
652 "Memory allocation failed : %s\n",
extra);
658 "Memory allocation failed\n");
670 xmlXPathPErrMemory(xmlXPathParserContextPtr ctxt,
const char *
extra)
675 ctxt->error = XPATH_MEMORY_ERROR;
676 xmlXPathErrMemory(ctxt->context,
extra);
688 xmlXPathErr(xmlXPathParserContextPtr ctxt,
int error)
698 "%s", xmlXPathErrorMessages[
error]);
702 if (ctxt->context ==
NULL) {
707 (
const char *) ctxt->base,
NULL,
NULL,
708 ctxt->cur - ctxt->base, 0,
709 "%s", xmlXPathErrorMessages[
error]);
720 ctxt->context->lastError.str1 = (
char *)
xmlStrdup(ctxt->base);
721 ctxt->context->lastError.int1 = ctxt->cur - ctxt->base;
722 ctxt->context->lastError.node = ctxt->context->debugNode;
723 if (ctxt->context->error !=
NULL) {
724 ctxt->context->error(ctxt->context->userData,
725 &ctxt->context->lastError);
731 (
const char *) ctxt->base,
NULL,
NULL,
732 ctxt->cur - ctxt->base, 0,
733 "%s", xmlXPathErrorMessages[
error]);
750 xmlXPathErr(ctxt,
no);
762 xmlXPathCheckOpLimit(xmlXPathParserContextPtr ctxt,
unsigned long opCount) {
763 xmlXPathContextPtr xpctxt = ctxt->context;
765 if ((opCount > xpctxt->opLimit) ||
766 (xpctxt->opCount > xpctxt->opLimit - opCount)) {
767 xpctxt->opCount = xpctxt->opLimit;
768 xmlXPathErr(ctxt, XPATH_OP_LIMIT_EXCEEDED);
772 xpctxt->opCount += opCount;
776 #define OP_LIMIT_EXCEEDED(ctxt, n) \ 777 ((ctxt->context->opLimit != 0) && (xmlXPathCheckOpLimit(ctxt, n) < 0)) 790 typedef struct _xmlPointerList xmlPointerList;
791 typedef xmlPointerList *xmlPointerListPtr;
792 struct _xmlPointerList {
802 xmlPointerListAddSize(xmlPointerListPtr
list,
807 if (initialSize <= 0)
809 list->items = (
void **)
xmlMalloc(initialSize *
sizeof(
void *));
811 xmlXPathErrMemory(
NULL,
812 "xmlPointerListCreate: allocating item\n");
819 xmlXPathErrMemory(
NULL,
820 "xmlPointerListAddSize: re-allocating item\n");
827 xmlXPathErrMemory(
NULL,
828 "xmlPointerListAddSize: re-allocating item\n");
844 static xmlPointerListPtr
845 xmlPointerListCreate(
int initialSize)
847 xmlPointerListPtr
ret;
851 xmlXPathErrMemory(
NULL,
852 "xmlPointerListCreate: allocating item\n");
856 if (initialSize > 0) {
857 xmlPointerListAddSize(
ret,
NULL, initialSize);
870 xmlPointerListFree(xmlPointerListPtr
list)
908 #ifdef LIBXML_XPTR_ENABLED 915 AXIS_ANCESTOR_OR_SELF,
919 AXIS_DESCENDANT_OR_SELF,
921 AXIS_FOLLOWING_SIBLING,
925 AXIS_PRECEDING_SIBLING,
945 typedef struct _xmlXPathStepOp xmlXPathStepOp;
946 typedef xmlXPathStepOp *xmlXPathStepOpPtr;
947 struct _xmlXPathStepOp {
956 xmlXPathFunction
cache;
960 struct _xmlXPathCompExpr {
963 xmlXPathStepOp *
steps;
967 #ifdef DEBUG_EVAL_COUNTS 971 #ifdef XPATH_STREAMING 982 xmlXPathFreeValueTree(xmlNodeSetPtr
obj);
984 xmlXPathReleaseObject(xmlXPathContextPtr ctxt, xmlXPathObjectPtr
obj);
986 xmlXPathCompOpEvalFirst(xmlXPathParserContextPtr ctxt,
989 xmlXPathCompOpEvalToBoolean(xmlXPathParserContextPtr ctxt,
990 xmlXPathStepOpPtr
op,
1008 static xmlXPathCompExprPtr
1009 xmlXPathNewCompExpr(
void) {
1010 xmlXPathCompExprPtr
cur;
1012 cur = (xmlXPathCompExprPtr)
xmlMalloc(
sizeof(xmlXPathCompExpr));
1014 xmlXPathErrMemory(
NULL,
"allocating component\n");
1017 memset(
cur, 0,
sizeof(xmlXPathCompExpr));
1021 sizeof(xmlXPathStepOp));
1023 xmlXPathErrMemory(
NULL,
"allocating steps\n");
1027 memset(
cur->steps, 0,
cur->maxStep *
sizeof(xmlXPathStepOp));
1029 #ifdef DEBUG_EVAL_COUNTS 1042 xmlXPathFreeCompExpr(xmlXPathCompExprPtr comp)
1044 xmlXPathStepOpPtr
op;
1049 if (comp->dict ==
NULL) {
1050 for (
i = 0;
i < comp->nbStep;
i++) {
1051 op = &comp->steps[
i];
1052 if (
op->value4 !=
NULL) {
1053 if (
op->op == XPATH_OP_VALUE)
1054 xmlXPathFreeObject(
op->value4);
1062 for (
i = 0;
i < comp->nbStep;
i++) {
1063 op = &comp->steps[
i];
1064 if (
op->value4 !=
NULL) {
1065 if (
op->op == XPATH_OP_VALUE)
1066 xmlXPathFreeObject(
op->value4);
1071 if (comp->steps !=
NULL) {
1074 #ifdef DEBUG_EVAL_COUNTS 1075 if (comp->string !=
NULL) {
1079 #ifdef XPATH_STREAMING 1080 if (comp->stream !=
NULL) {
1081 xmlFreePatternList(comp->stream);
1084 if (comp->expr !=
NULL) {
1108 xmlXPathCompExprAdd(xmlXPathParserContextPtr ctxt,
int ch1,
int ch2,
1110 int value2,
int value3,
void *value4,
void *value5) {
1111 xmlXPathCompExprPtr comp = ctxt->comp;
1112 if (comp->nbStep >= comp->maxStep) {
1113 xmlXPathStepOp *
real;
1116 xmlXPathPErrMemory(ctxt,
"adding step\n");
1121 comp->maxStep *
sizeof(xmlXPathStepOp));
1124 xmlXPathPErrMemory(ctxt,
"adding step\n");
1129 comp->last = comp->nbStep;
1130 comp->steps[comp->nbStep].ch1 = ch1;
1131 comp->steps[comp->nbStep].ch2 = ch2;
1132 comp->steps[comp->nbStep].op =
op;
1133 comp->steps[comp->nbStep].value =
value;
1134 comp->steps[comp->nbStep].value2 = value2;
1135 comp->steps[comp->nbStep].value3 = value3;
1136 if ((comp->dict !=
NULL) &&
1137 ((
op == XPATH_OP_FUNCTION) || (
op == XPATH_OP_VARIABLE) ||
1138 (
op == XPATH_OP_COLLECT))) {
1139 if (value4 !=
NULL) {
1140 comp->steps[comp->nbStep].value4 = (
xmlChar *)
1144 comp->steps[comp->nbStep].value4 =
NULL;
1145 if (value5 !=
NULL) {
1146 comp->steps[comp->nbStep].value5 = (
xmlChar *)
1150 comp->steps[comp->nbStep].value5 =
NULL;
1152 comp->steps[comp->nbStep].value4 = value4;
1153 comp->steps[comp->nbStep].value5 = value5;
1155 comp->steps[comp->nbStep].cache =
NULL;
1156 return(comp->nbStep++);
1167 xmlXPathCompSwap(xmlXPathStepOpPtr
op) {
1170 #ifndef LIBXML_THREAD_ENABLED 1176 if (xmlXPathDisableOptimizer)
1185 #define PUSH_FULL_EXPR(op, op1, op2, val, val2, val3, val4, val5) \ 1186 xmlXPathCompExprAdd(ctxt, (op1), (op2), \ 1187 (op), (val), (val2), (val3), (val4), (val5)) 1188 #define PUSH_LONG_EXPR(op, val, val2, val3, val4, val5) \ 1189 xmlXPathCompExprAdd(ctxt, ctxt->comp->last, -1, \ 1190 (op), (val), (val2), (val3), (val4), (val5)) 1192 #define PUSH_LEAVE_EXPR(op, val, val2) \ 1193 xmlXPathCompExprAdd(ctxt, -1, -1, (op), (val), (val2), 0 ,NULL ,NULL) 1195 #define PUSH_UNARY_EXPR(op, ch, val, val2) \ 1196 xmlXPathCompExprAdd(ctxt, (ch), -1, (op), (val), (val2), 0 ,NULL ,NULL) 1198 #define PUSH_BINARY_EXPR(op, ch1, ch2, val, val2) \ 1199 xmlXPathCompExprAdd(ctxt, (ch1), (ch2), (op), \ 1200 (val), (val2), 0 ,NULL ,NULL) 1210 #define XP_HAS_CACHE(c) ((c != NULL) && ((c)->cache != NULL)) 1212 typedef struct _xmlXPathContextCache xmlXPathContextCache;
1213 typedef xmlXPathContextCache *xmlXPathContextCachePtr;
1214 struct _xmlXPathContextCache {
1215 xmlPointerListPtr nodesetObjs;
1216 xmlPointerListPtr stringObjs;
1217 xmlPointerListPtr booleanObjs;
1218 xmlPointerListPtr numberObjs;
1219 xmlPointerListPtr miscObjs;
1225 #ifdef XP_DEBUG_OBJ_USAGE 1227 int dbgCachedNodeset;
1228 int dbgCachedString;
1230 int dbgCachedNumber;
1233 int dbgCachedLocset;
1235 int dbgCachedXSLTTree;
1236 int dbgCachedUndefined;
1240 int dbgReusedNodeset;
1241 int dbgReusedString;
1243 int dbgReusedNumber;
1246 int dbgReusedLocset;
1248 int dbgReusedXSLTTree;
1249 int dbgReusedUndefined;
1261 xmlGenericError(xmlGenericErrorContext, \ 1262 "Internal error at %s:%d\n", \ 1263 __FILE__, __LINE__); 1265 #ifdef LIBXML_DEBUG_ENABLED 1271 for (
i = 0;((
i <
depth) && (
i < 25));
i++)
1296 for (
i = 0;((
i <
depth) && (
i < 25));
i++)
1318 for (
i = 0;((
i <
depth) && (
i < 25));
i++)
1331 for (
i = 0;
i <
cur->nodeNr;
i++) {
1344 for (
i = 0;((
i <
depth) && (
i < 25));
i++)
1357 xmlXPathDebugDumpNodeList(
output,
cur->nodeTab[0]->children,
depth + 1);
1359 #if defined(LIBXML_XPTR_ENABLED) 1365 for (
i = 0;((
i <
depth) && (
i < 25));
i++)
1376 for (
i = 0;
i <
cur->locNr;
i++) {
1399 for (
i = 0;((
i <
depth) && (
i < 25));
i++)
1411 case XPATH_UNDEFINED:
1418 case XPATH_XSLT_TREE:
1428 switch (xmlXPathIsInf(
cur->floatval)) {
1436 if (xmlXPathIsNaN(
cur->floatval)) {
1438 }
else if (
cur->floatval == 0) {
1448 xmlDebugDumpString(
output,
cur->stringval);
1458 ((
cur->user2 ==
cur->user) && (
cur->index ==
cur->index2))) {
1461 if (
cur->index >= 0)
1470 if (
cur->index >= 0)
1477 if (
cur->index2 >= 0)
1485 case XPATH_LOCATIONSET:
1486 #if defined(LIBXML_XPTR_ENABLED) 1488 xmlXPathDebugDumpLocationSet(
output,
1489 (xmlLocationSetPtr)
cur->user,
depth);
1499 xmlXPathDebugDumpStepOp(
FILE *
output, xmlXPathCompExprPtr comp,
1500 xmlXPathStepOpPtr
op,
int depth) {
1504 for (
i = 0;((
i <
depth) && (
i < 25));
i++)
1520 case XPATH_OP_EQUAL:
1537 else if (
op->value == 1)
1539 else if (
op->value == 2)
1541 else if (
op->value == 3)
1547 else if (
op->value == 1)
1552 case XPATH_OP_UNION:
1560 case XPATH_OP_COLLECT: {
1561 xmlXPathAxisVal axis = (xmlXPathAxisVal)
op->value;
1562 xmlXPathTestVal
test = (xmlXPathTestVal)
op->value2;
1563 xmlXPathTypeVal
type = (xmlXPathTypeVal)
op->value3;
1571 case AXIS_ANCESTOR_OR_SELF:
1577 case AXIS_DESCENDANT:
1579 case AXIS_DESCENDANT_OR_SELF:
1581 case AXIS_FOLLOWING:
1583 case AXIS_FOLLOWING_SIBLING:
1585 case AXIS_NAMESPACE:
1589 case AXIS_PRECEDING:
1591 case AXIS_PRECEDING_SIBLING:
1597 case NODE_TEST_NONE:
1599 case NODE_TEST_TYPE:
1607 case NODE_TEST_NAME:
1611 case NODE_TYPE_NODE:
1613 case NODE_TYPE_COMMENT:
1615 case NODE_TYPE_TEXT:
1627 case XPATH_OP_VALUE: {
1628 xmlXPathObjectPtr
object = (xmlXPathObjectPtr)
op->value4;
1631 xmlXPathDebugDumpObject(
output,
object, 0);
1634 case XPATH_OP_VARIABLE: {
1644 case XPATH_OP_FUNCTION: {
1645 int nbargs =
op->value;
1651 prefix,
name, nbargs);
1657 case XPATH_OP_PREDICATE:
fprintf(
output,
"PREDICATE");
break;
1659 #ifdef LIBXML_XPTR_ENABLED 1668 xmlXPathDebugDumpStepOp(
output, comp, &comp->steps[
op->ch1],
depth + 1);
1670 xmlXPathDebugDumpStepOp(
output, comp, &comp->steps[
op->ch2],
depth + 1);
1682 xmlXPathDebugDumpCompExpr(
FILE *
output, xmlXPathCompExprPtr comp,
1689 for (
i = 0;((
i <
depth) && (
i < 25));
i++)
1695 #ifdef XPATH_STREAMING 1704 xmlXPathDebugDumpStepOp(
output, comp, &comp->steps[
i],
depth + 1);
1708 #ifdef XP_DEBUG_OBJ_USAGE 1713 static int xmlXPathDebugObjCounterUndefined = 0;
1714 static int xmlXPathDebugObjCounterNodeset = 0;
1715 static int xmlXPathDebugObjCounterBool = 0;
1716 static int xmlXPathDebugObjCounterNumber = 0;
1717 static int xmlXPathDebugObjCounterString = 0;
1718 static int xmlXPathDebugObjCounterPoint = 0;
1719 static int xmlXPathDebugObjCounterRange = 0;
1720 static int xmlXPathDebugObjCounterLocset = 0;
1721 static int xmlXPathDebugObjCounterUsers = 0;
1722 static int xmlXPathDebugObjCounterXSLTTree = 0;
1723 static int xmlXPathDebugObjCounterAll = 0;
1725 static int xmlXPathDebugObjTotalUndefined = 0;
1726 static int xmlXPathDebugObjTotalNodeset = 0;
1727 static int xmlXPathDebugObjTotalBool = 0;
1728 static int xmlXPathDebugObjTotalNumber = 0;
1729 static int xmlXPathDebugObjTotalString = 0;
1730 static int xmlXPathDebugObjTotalPoint = 0;
1731 static int xmlXPathDebugObjTotalRange = 0;
1732 static int xmlXPathDebugObjTotalLocset = 0;
1733 static int xmlXPathDebugObjTotalUsers = 0;
1734 static int xmlXPathDebugObjTotalXSLTTree = 0;
1735 static int xmlXPathDebugObjTotalAll = 0;
1737 static int xmlXPathDebugObjMaxUndefined = 0;
1738 static int xmlXPathDebugObjMaxNodeset = 0;
1739 static int xmlXPathDebugObjMaxBool = 0;
1740 static int xmlXPathDebugObjMaxNumber = 0;
1741 static int xmlXPathDebugObjMaxString = 0;
1742 static int xmlXPathDebugObjMaxPoint = 0;
1743 static int xmlXPathDebugObjMaxRange = 0;
1744 static int xmlXPathDebugObjMaxLocset = 0;
1745 static int xmlXPathDebugObjMaxUsers = 0;
1746 static int xmlXPathDebugObjMaxXSLTTree = 0;
1747 static int xmlXPathDebugObjMaxAll = 0;
1751 xmlXPathDebugObjUsageReset(xmlXPathContextPtr ctxt)
1754 if (ctxt->cache !=
NULL) {
1755 xmlXPathContextCachePtr
cache =
1756 (xmlXPathContextCachePtr) ctxt->cache;
1758 cache->dbgCachedAll = 0;
1759 cache->dbgCachedNodeset = 0;
1760 cache->dbgCachedString = 0;
1761 cache->dbgCachedBool = 0;
1762 cache->dbgCachedNumber = 0;
1763 cache->dbgCachedPoint = 0;
1764 cache->dbgCachedRange = 0;
1765 cache->dbgCachedLocset = 0;
1766 cache->dbgCachedUsers = 0;
1767 cache->dbgCachedXSLTTree = 0;
1768 cache->dbgCachedUndefined = 0;
1770 cache->dbgReusedAll = 0;
1771 cache->dbgReusedNodeset = 0;
1772 cache->dbgReusedString = 0;
1773 cache->dbgReusedBool = 0;
1774 cache->dbgReusedNumber = 0;
1775 cache->dbgReusedPoint = 0;
1776 cache->dbgReusedRange = 0;
1777 cache->dbgReusedLocset = 0;
1778 cache->dbgReusedUsers = 0;
1779 cache->dbgReusedXSLTTree = 0;
1780 cache->dbgReusedUndefined = 0;
1784 xmlXPathDebugObjCounterUndefined = 0;
1785 xmlXPathDebugObjCounterNodeset = 0;
1786 xmlXPathDebugObjCounterBool = 0;
1787 xmlXPathDebugObjCounterNumber = 0;
1788 xmlXPathDebugObjCounterString = 0;
1789 xmlXPathDebugObjCounterPoint = 0;
1790 xmlXPathDebugObjCounterRange = 0;
1791 xmlXPathDebugObjCounterLocset = 0;
1792 xmlXPathDebugObjCounterUsers = 0;
1793 xmlXPathDebugObjCounterXSLTTree = 0;
1794 xmlXPathDebugObjCounterAll = 0;
1796 xmlXPathDebugObjTotalUndefined = 0;
1797 xmlXPathDebugObjTotalNodeset = 0;
1798 xmlXPathDebugObjTotalBool = 0;
1799 xmlXPathDebugObjTotalNumber = 0;
1800 xmlXPathDebugObjTotalString = 0;
1801 xmlXPathDebugObjTotalPoint = 0;
1802 xmlXPathDebugObjTotalRange = 0;
1803 xmlXPathDebugObjTotalLocset = 0;
1804 xmlXPathDebugObjTotalUsers = 0;
1805 xmlXPathDebugObjTotalXSLTTree = 0;
1806 xmlXPathDebugObjTotalAll = 0;
1808 xmlXPathDebugObjMaxUndefined = 0;
1809 xmlXPathDebugObjMaxNodeset = 0;
1810 xmlXPathDebugObjMaxBool = 0;
1811 xmlXPathDebugObjMaxNumber = 0;
1812 xmlXPathDebugObjMaxString = 0;
1813 xmlXPathDebugObjMaxPoint = 0;
1814 xmlXPathDebugObjMaxRange = 0;
1815 xmlXPathDebugObjMaxLocset = 0;
1816 xmlXPathDebugObjMaxUsers = 0;
1817 xmlXPathDebugObjMaxXSLTTree = 0;
1818 xmlXPathDebugObjMaxAll = 0;
1823 xmlXPathDebugObjUsageRequested(xmlXPathContextPtr ctxt,
1824 xmlXPathObjectType objType)
1829 if (ctxt->cache !=
NULL) {
1830 xmlXPathContextCachePtr
cache =
1831 (xmlXPathContextCachePtr) ctxt->cache;
1835 cache->dbgReusedAll++;
1837 case XPATH_UNDEFINED:
1838 cache->dbgReusedUndefined++;
1841 cache->dbgReusedNodeset++;
1844 cache->dbgReusedBool++;
1847 cache->dbgReusedNumber++;
1850 cache->dbgReusedString++;
1853 cache->dbgReusedPoint++;
1856 cache->dbgReusedRange++;
1858 case XPATH_LOCATIONSET:
1859 cache->dbgReusedLocset++;
1862 cache->dbgReusedUsers++;
1864 case XPATH_XSLT_TREE:
1865 cache->dbgReusedXSLTTree++;
1874 case XPATH_UNDEFINED:
1876 xmlXPathDebugObjTotalUndefined++;
1877 xmlXPathDebugObjCounterUndefined++;
1878 if (xmlXPathDebugObjCounterUndefined >
1879 xmlXPathDebugObjMaxUndefined)
1880 xmlXPathDebugObjMaxUndefined =
1881 xmlXPathDebugObjCounterUndefined;
1885 xmlXPathDebugObjTotalNodeset++;
1886 xmlXPathDebugObjCounterNodeset++;
1887 if (xmlXPathDebugObjCounterNodeset >
1888 xmlXPathDebugObjMaxNodeset)
1889 xmlXPathDebugObjMaxNodeset =
1890 xmlXPathDebugObjCounterNodeset;
1894 xmlXPathDebugObjTotalBool++;
1895 xmlXPathDebugObjCounterBool++;
1896 if (xmlXPathDebugObjCounterBool >
1897 xmlXPathDebugObjMaxBool)
1898 xmlXPathDebugObjMaxBool =
1899 xmlXPathDebugObjCounterBool;
1903 xmlXPathDebugObjTotalNumber++;
1904 xmlXPathDebugObjCounterNumber++;
1905 if (xmlXPathDebugObjCounterNumber >
1906 xmlXPathDebugObjMaxNumber)
1907 xmlXPathDebugObjMaxNumber =
1908 xmlXPathDebugObjCounterNumber;
1912 xmlXPathDebugObjTotalString++;
1913 xmlXPathDebugObjCounterString++;
1914 if (xmlXPathDebugObjCounterString >
1915 xmlXPathDebugObjMaxString)
1916 xmlXPathDebugObjMaxString =
1917 xmlXPathDebugObjCounterString;
1921 xmlXPathDebugObjTotalPoint++;
1922 xmlXPathDebugObjCounterPoint++;
1923 if (xmlXPathDebugObjCounterPoint >
1924 xmlXPathDebugObjMaxPoint)
1925 xmlXPathDebugObjMaxPoint =
1926 xmlXPathDebugObjCounterPoint;
1930 xmlXPathDebugObjTotalRange++;
1931 xmlXPathDebugObjCounterRange++;
1932 if (xmlXPathDebugObjCounterRange >
1933 xmlXPathDebugObjMaxRange)
1934 xmlXPathDebugObjMaxRange =
1935 xmlXPathDebugObjCounterRange;
1937 case XPATH_LOCATIONSET:
1939 xmlXPathDebugObjTotalLocset++;
1940 xmlXPathDebugObjCounterLocset++;
1941 if (xmlXPathDebugObjCounterLocset >
1942 xmlXPathDebugObjMaxLocset)
1943 xmlXPathDebugObjMaxLocset =
1944 xmlXPathDebugObjCounterLocset;
1948 xmlXPathDebugObjTotalUsers++;
1949 xmlXPathDebugObjCounterUsers++;
1950 if (xmlXPathDebugObjCounterUsers >
1951 xmlXPathDebugObjMaxUsers)
1952 xmlXPathDebugObjMaxUsers =
1953 xmlXPathDebugObjCounterUsers;
1955 case XPATH_XSLT_TREE:
1957 xmlXPathDebugObjTotalXSLTTree++;
1958 xmlXPathDebugObjCounterXSLTTree++;
1959 if (xmlXPathDebugObjCounterXSLTTree >
1960 xmlXPathDebugObjMaxXSLTTree)
1961 xmlXPathDebugObjMaxXSLTTree =
1962 xmlXPathDebugObjCounterXSLTTree;
1968 xmlXPathDebugObjTotalAll++;
1969 xmlXPathDebugObjCounterAll++;
1970 if (xmlXPathDebugObjCounterAll >
1971 xmlXPathDebugObjMaxAll)
1972 xmlXPathDebugObjMaxAll =
1973 xmlXPathDebugObjCounterAll;
1977 xmlXPathDebugObjUsageReleased(xmlXPathContextPtr ctxt,
1978 xmlXPathObjectType objType)
1983 if (ctxt->cache !=
NULL) {
1984 xmlXPathContextCachePtr
cache =
1985 (xmlXPathContextCachePtr) ctxt->cache;
1989 cache->dbgCachedAll++;
1991 case XPATH_UNDEFINED:
1992 cache->dbgCachedUndefined++;
1995 cache->dbgCachedNodeset++;
1998 cache->dbgCachedBool++;
2001 cache->dbgCachedNumber++;
2004 cache->dbgCachedString++;
2007 cache->dbgCachedPoint++;
2010 cache->dbgCachedRange++;
2012 case XPATH_LOCATIONSET:
2013 cache->dbgCachedLocset++;
2016 cache->dbgCachedUsers++;
2018 case XPATH_XSLT_TREE:
2019 cache->dbgCachedXSLTTree++;
2028 case XPATH_UNDEFINED:
2029 xmlXPathDebugObjCounterUndefined--;
2032 xmlXPathDebugObjCounterNodeset--;
2035 xmlXPathDebugObjCounterBool--;
2038 xmlXPathDebugObjCounterNumber--;
2041 xmlXPathDebugObjCounterString--;
2044 xmlXPathDebugObjCounterPoint--;
2047 xmlXPathDebugObjCounterRange--;
2049 case XPATH_LOCATIONSET:
2050 xmlXPathDebugObjCounterLocset--;
2053 xmlXPathDebugObjCounterUsers--;
2055 case XPATH_XSLT_TREE:
2056 xmlXPathDebugObjCounterXSLTTree--;
2061 xmlXPathDebugObjCounterAll--;
2066 xmlXPathDebugObjUsageDisplay(xmlXPathContextPtr ctxt)
2068 int reqAll, reqNodeset, reqString, reqBool, reqNumber,
2069 reqXSLTTree, reqUndefined;
2070 int caAll = 0, caNodeset = 0, caString = 0, caBool = 0,
2071 caNumber = 0, caXSLTTree = 0, caUndefined = 0;
2072 int reAll = 0, reNodeset = 0, reString = 0, reBool = 0,
2073 reNumber = 0, reXSLTTree = 0, reUndefined = 0;
2074 int leftObjs = xmlXPathDebugObjCounterAll;
2076 reqAll = xmlXPathDebugObjTotalAll;
2077 reqNodeset = xmlXPathDebugObjTotalNodeset;
2078 reqString = xmlXPathDebugObjTotalString;
2079 reqBool = xmlXPathDebugObjTotalBool;
2080 reqNumber = xmlXPathDebugObjTotalNumber;
2081 reqXSLTTree = xmlXPathDebugObjTotalXSLTTree;
2082 reqUndefined = xmlXPathDebugObjTotalUndefined;
2084 printf(
"# XPath object usage:\n");
2087 if (ctxt->cache !=
NULL) {
2088 xmlXPathContextCachePtr
cache =
2089 (xmlXPathContextCachePtr) ctxt->cache;
2091 reAll =
cache->dbgReusedAll;
2093 reNodeset =
cache->dbgReusedNodeset;
2094 reqNodeset += reNodeset;
2095 reString =
cache->dbgReusedString;
2096 reqString += reString;
2097 reBool =
cache->dbgReusedBool;
2099 reNumber =
cache->dbgReusedNumber;
2100 reqNumber += reNumber;
2101 reXSLTTree =
cache->dbgReusedXSLTTree;
2102 reqXSLTTree += reXSLTTree;
2103 reUndefined =
cache->dbgReusedUndefined;
2104 reqUndefined += reUndefined;
2106 caAll =
cache->dbgCachedAll;
2107 caBool =
cache->dbgCachedBool;
2108 caNodeset =
cache->dbgCachedNodeset;
2109 caString =
cache->dbgCachedString;
2110 caNumber =
cache->dbgCachedNumber;
2111 caXSLTTree =
cache->dbgCachedXSLTTree;
2112 caUndefined =
cache->dbgCachedUndefined;
2115 leftObjs -=
cache->nodesetObjs->number;
2116 if (
cache->stringObjs)
2117 leftObjs -=
cache->stringObjs->number;
2118 if (
cache->booleanObjs)
2119 leftObjs -=
cache->booleanObjs->number;
2120 if (
cache->numberObjs)
2121 leftObjs -=
cache->numberObjs->number;
2122 if (
cache->miscObjs)
2123 leftObjs -=
cache->miscObjs->number;
2128 printf(
"# total : %d\n", reqAll);
2129 printf(
"# left : %d\n", leftObjs);
2130 printf(
"# created: %d\n", xmlXPathDebugObjTotalAll);
2131 printf(
"# reused : %d\n", reAll);
2132 printf(
"# max : %d\n", xmlXPathDebugObjMaxAll);
2135 printf(
"# total : %d\n", reqNodeset);
2136 printf(
"# created: %d\n", xmlXPathDebugObjTotalNodeset);
2137 printf(
"# reused : %d\n", reNodeset);
2138 printf(
"# max : %d\n", xmlXPathDebugObjMaxNodeset);
2141 printf(
"# total : %d\n", reqString);
2142 printf(
"# created: %d\n", xmlXPathDebugObjTotalString);
2143 printf(
"# reused : %d\n", reString);
2144 printf(
"# max : %d\n", xmlXPathDebugObjMaxString);
2147 printf(
"# total : %d\n", reqBool);
2148 printf(
"# created: %d\n", xmlXPathDebugObjTotalBool);
2149 printf(
"# reused : %d\n", reBool);
2150 printf(
"# max : %d\n", xmlXPathDebugObjMaxBool);
2153 printf(
"# total : %d\n", reqNumber);
2154 printf(
"# created: %d\n", xmlXPathDebugObjTotalNumber);
2155 printf(
"# reused : %d\n", reNumber);
2156 printf(
"# max : %d\n", xmlXPathDebugObjMaxNumber);
2158 printf(
"# XSLT result tree fragments\n");
2159 printf(
"# total : %d\n", reqXSLTTree);
2160 printf(
"# created: %d\n", xmlXPathDebugObjTotalXSLTTree);
2161 printf(
"# reused : %d\n", reXSLTTree);
2162 printf(
"# max : %d\n", xmlXPathDebugObjMaxXSLTTree);
2165 printf(
"# total : %d\n", reqUndefined);
2166 printf(
"# created: %d\n", xmlXPathDebugObjTotalUndefined);
2167 printf(
"# reused : %d\n", reUndefined);
2168 printf(
"# max : %d\n", xmlXPathDebugObjMaxUndefined);
2189 static xmlXPathContextCachePtr
2190 xmlXPathNewCache(
void)
2192 xmlXPathContextCachePtr
ret;
2194 ret = (xmlXPathContextCachePtr)
xmlMalloc(
sizeof(xmlXPathContextCache));
2196 xmlXPathErrMemory(
NULL,
"creating object cache\n");
2199 memset(
ret, 0 , (
size_t)
sizeof(xmlXPathContextCache));
2200 ret->maxNodeset = 100;
2201 ret->maxString = 100;
2202 ret->maxBoolean = 100;
2203 ret->maxNumber = 100;
2209 xmlXPathCacheFreeObjectList(xmlPointerListPtr
list)
2212 xmlXPathObjectPtr
obj;
2217 for (
i = 0;
i <
list->number;
i++) {
2223 if (
obj->nodesetval !=
NULL) {
2224 if (
obj->nodesetval->nodeTab !=
NULL)
2229 #ifdef XP_DEBUG_OBJ_USAGE 2230 xmlXPathDebugObjCounterAll--;
2233 xmlPointerListFree(
list);
2237 xmlXPathFreeCache(xmlXPathContextCachePtr
cache)
2241 if (
cache->nodesetObjs)
2242 xmlXPathCacheFreeObjectList(
cache->nodesetObjs);
2243 if (
cache->stringObjs)
2244 xmlXPathCacheFreeObjectList(
cache->stringObjs);
2245 if (
cache->booleanObjs)
2246 xmlXPathCacheFreeObjectList(
cache->booleanObjs);
2247 if (
cache->numberObjs)
2248 xmlXPathCacheFreeObjectList(
cache->numberObjs);
2249 if (
cache->miscObjs)
2250 xmlXPathCacheFreeObjectList(
cache->miscObjs);
2277 xmlXPathContextSetCache(xmlXPathContextPtr ctxt,
2285 xmlXPathContextCachePtr
cache;
2287 if (ctxt->cache ==
NULL) {
2288 ctxt->cache = xmlXPathNewCache();
2289 if (ctxt->cache ==
NULL)
2292 cache = (xmlXPathContextCachePtr) ctxt->cache;
2302 }
else if (ctxt->cache !=
NULL) {
2303 xmlXPathFreeCache((xmlXPathContextCachePtr) ctxt->cache);
2319 static xmlXPathObjectPtr
2320 xmlXPathCacheWrapNodeSet(xmlXPathContextPtr ctxt, xmlNodeSetPtr
val)
2322 if ((ctxt !=
NULL) && (ctxt->cache !=
NULL)) {
2323 xmlXPathContextCachePtr
cache =
2324 (xmlXPathContextCachePtr) ctxt->cache;
2327 (
cache->miscObjs->number != 0))
2329 xmlXPathObjectPtr
ret;
2331 ret = (xmlXPathObjectPtr)
2332 cache->miscObjs->items[--
cache->miscObjs->number];
2333 ret->type = XPATH_NODESET;
2335 #ifdef XP_DEBUG_OBJ_USAGE
2336 xmlXPathDebugObjUsageRequested(ctxt, XPATH_NODESET);
2342 return(xmlXPathWrapNodeSet(
val));
2356 static xmlXPathObjectPtr
2357 xmlXPathCacheWrapString(xmlXPathContextPtr ctxt,
xmlChar *
val)
2359 if ((ctxt !=
NULL) && (ctxt->cache !=
NULL)) {
2360 xmlXPathContextCachePtr
cache = (xmlXPathContextCachePtr) ctxt->cache;
2363 (
cache->stringObjs->number != 0))
2366 xmlXPathObjectPtr
ret;
2368 ret = (xmlXPathObjectPtr)
2369 cache->stringObjs->items[--
cache->stringObjs->number];
2370 ret->type = XPATH_STRING;
2372 #ifdef XP_DEBUG_OBJ_USAGE
2373 xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
2377 (
cache->miscObjs->number != 0))
2379 xmlXPathObjectPtr
ret;
2383 ret = (xmlXPathObjectPtr)
2384 cache->miscObjs->items[--
cache->miscObjs->number];
2386 ret->type = XPATH_STRING;
2388 #ifdef XP_DEBUG_OBJ_USAGE
2389 xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
2394 return(xmlXPathWrapString(
val));
2408 static xmlXPathObjectPtr
2409 xmlXPathCacheNewNodeSet(xmlXPathContextPtr ctxt,
xmlNodePtr val)
2411 if ((ctxt !=
NULL) && (ctxt->cache)) {
2412 xmlXPathContextCachePtr
cache = (xmlXPathContextCachePtr) ctxt->cache;
2415 (
cache->nodesetObjs->number != 0))
2417 xmlXPathObjectPtr
ret;
2421 ret = (xmlXPathObjectPtr)
2422 cache->nodesetObjs->items[--
cache->nodesetObjs->number];
2423 ret->type = XPATH_NODESET;
2426 if ((
ret->nodesetval->nodeMax == 0) ||
2430 xmlXPathNodeSetAddUnique(
ret->nodesetval,
val);
2432 ret->nodesetval->nodeTab[0] =
val;
2433 ret->nodesetval->nodeNr = 1;
2436 #ifdef XP_DEBUG_OBJ_USAGE 2437 xmlXPathDebugObjUsageRequested(ctxt, XPATH_NODESET);
2441 (
cache->miscObjs->number != 0))
2443 xmlXPathObjectPtr
ret;
2448 ret = (xmlXPathObjectPtr)
2449 cache->miscObjs->items[--
cache->miscObjs->number];
2451 ret->type = XPATH_NODESET;
2453 ret->nodesetval = xmlXPathNodeSetCreate(
val);
2454 if (
ret->nodesetval ==
NULL) {
2459 #ifdef XP_DEBUG_OBJ_USAGE 2460 xmlXPathDebugObjUsageRequested(ctxt, XPATH_NODESET);
2465 return(xmlXPathNewNodeSet(
val));
2478 static xmlXPathObjectPtr
2479 xmlXPathCacheNewCString(xmlXPathContextPtr ctxt,
const char *
val)
2481 if ((ctxt !=
NULL) && (ctxt->cache)) {
2482 xmlXPathContextCachePtr
cache = (xmlXPathContextCachePtr) ctxt->cache;
2485 (
cache->stringObjs->number != 0))
2487 xmlXPathObjectPtr
ret;
2489 ret = (xmlXPathObjectPtr)
2490 cache->stringObjs->items[--
cache->stringObjs->number];
2492 ret->type = XPATH_STRING;
2494 #ifdef XP_DEBUG_OBJ_USAGE 2495 xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
2499 (
cache->miscObjs->number != 0))
2501 xmlXPathObjectPtr
ret;
2503 ret = (xmlXPathObjectPtr)
2504 cache->miscObjs->items[--
cache->miscObjs->number];
2506 ret->type = XPATH_STRING;
2508 #ifdef XP_DEBUG_OBJ_USAGE 2509 xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
2514 return(xmlXPathNewCString(
val));
2527 static xmlXPathObjectPtr
2528 xmlXPathCacheNewString(xmlXPathContextPtr ctxt,
const xmlChar *
val)
2530 if ((ctxt !=
NULL) && (ctxt->cache)) {
2531 xmlXPathContextCachePtr
cache = (xmlXPathContextCachePtr) ctxt->cache;
2534 (
cache->stringObjs->number != 0))
2536 xmlXPathObjectPtr
ret;
2538 ret = (xmlXPathObjectPtr)
2539 cache->stringObjs->items[--
cache->stringObjs->number];
2540 ret->type = XPATH_STRING;
2545 #ifdef XP_DEBUG_OBJ_USAGE 2546 xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
2550 (
cache->miscObjs->number != 0))
2552 xmlXPathObjectPtr
ret;
2554 ret = (xmlXPathObjectPtr)
2555 cache->miscObjs->items[--
cache->miscObjs->number];
2557 ret->type = XPATH_STRING;
2562 #ifdef XP_DEBUG_OBJ_USAGE 2563 xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
2568 return(xmlXPathNewString(
val));
2581 static xmlXPathObjectPtr
2582 xmlXPathCacheNewBoolean(xmlXPathContextPtr ctxt,
int val)
2584 if ((ctxt !=
NULL) && (ctxt->cache)) {
2585 xmlXPathContextCachePtr
cache = (xmlXPathContextCachePtr) ctxt->cache;
2588 (
cache->booleanObjs->number != 0))
2590 xmlXPathObjectPtr
ret;
2592 ret = (xmlXPathObjectPtr)
2593 cache->booleanObjs->items[--
cache->booleanObjs->number];
2594 ret->type = XPATH_BOOLEAN;
2595 ret->boolval = (
val != 0);
2596 #ifdef XP_DEBUG_OBJ_USAGE 2597 xmlXPathDebugObjUsageRequested(ctxt, XPATH_BOOLEAN);
2601 (
cache->miscObjs->number != 0))
2603 xmlXPathObjectPtr
ret;
2605 ret = (xmlXPathObjectPtr)
2606 cache->miscObjs->items[--
cache->miscObjs->number];
2608 ret->type = XPATH_BOOLEAN;
2609 ret->boolval = (
val != 0);
2610 #ifdef XP_DEBUG_OBJ_USAGE 2611 xmlXPathDebugObjUsageRequested(ctxt, XPATH_BOOLEAN);
2616 return(xmlXPathNewBoolean(
val));
2629 static xmlXPathObjectPtr
2630 xmlXPathCacheNewFloat(xmlXPathContextPtr ctxt,
double val)
2632 if ((ctxt !=
NULL) && (ctxt->cache)) {
2633 xmlXPathContextCachePtr
cache = (xmlXPathContextCachePtr) ctxt->cache;
2636 (
cache->numberObjs->number != 0))
2638 xmlXPathObjectPtr
ret;
2640 ret = (xmlXPathObjectPtr)
2641 cache->numberObjs->items[--
cache->numberObjs->number];
2642 ret->type = XPATH_NUMBER;
2644 #ifdef XP_DEBUG_OBJ_USAGE
2645 xmlXPathDebugObjUsageRequested(ctxt, XPATH_NUMBER);
2649 (
cache->miscObjs->number != 0))
2651 xmlXPathObjectPtr
ret;
2653 ret = (xmlXPathObjectPtr)
2654 cache->miscObjs->items[--
cache->miscObjs->number];
2656 ret->type = XPATH_NUMBER;
2658 #ifdef XP_DEBUG_OBJ_USAGE
2659 xmlXPathDebugObjUsageRequested(ctxt, XPATH_NUMBER);
2664 return(xmlXPathNewFloat(
val));
2679 static xmlXPathObjectPtr
2680 xmlXPathCacheConvertString(xmlXPathContextPtr ctxt, xmlXPathObjectPtr
val) {
2684 return(xmlXPathCacheNewCString(ctxt,
""));
2686 switch (
val->type) {
2687 case XPATH_UNDEFINED:
2693 case XPATH_XSLT_TREE:
2694 res = xmlXPathCastNodeSetToString(
val->nodesetval);
2699 res = xmlXPathCastBooleanToString(
val->boolval);
2702 res = xmlXPathCastNumberToString(
val->floatval);
2707 case XPATH_LOCATIONSET:
2711 xmlXPathReleaseObject(ctxt,
val);
2713 return(xmlXPathCacheNewCString(ctxt,
""));
2714 return(xmlXPathCacheWrapString(ctxt,
res));
2727 static xmlXPathObjectPtr
2728 xmlXPathCacheObjectCopy(xmlXPathContextPtr ctxt, xmlXPathObjectPtr
val)
2733 if (XP_HAS_CACHE(ctxt)) {
2734 switch (
val->type) {
2736 return(xmlXPathCacheWrapNodeSet(ctxt,
2737 xmlXPathNodeSetMerge(
NULL,
val->nodesetval)));
2739 return(xmlXPathCacheNewString(ctxt,
val->stringval));
2741 return(xmlXPathCacheNewBoolean(ctxt,
val->boolval));
2743 return(xmlXPathCacheNewFloat(ctxt,
val->floatval));
2748 return(xmlXPathObjectCopy(
val));
2762 static xmlXPathObjectPtr
2763 xmlXPathCacheConvertBoolean(xmlXPathContextPtr ctxt, xmlXPathObjectPtr
val) {
2764 xmlXPathObjectPtr
ret;
2767 return(xmlXPathCacheNewBoolean(ctxt, 0));
2768 if (
val->type == XPATH_BOOLEAN)
2770 ret = xmlXPathCacheNewBoolean(ctxt, xmlXPathCastToBoolean(
val));
2771 xmlXPathReleaseObject(ctxt,
val);
2786 static xmlXPathObjectPtr
2787 xmlXPathCacheConvertNumber(xmlXPathContextPtr ctxt, xmlXPathObjectPtr
val) {
2788 xmlXPathObjectPtr
ret;
2791 return(xmlXPathCacheNewFloat(ctxt, 0.0));
2792 if (
val->type == XPATH_NUMBER)
2794 ret = xmlXPathCacheNewFloat(ctxt, xmlXPathCastToNumber(
val));
2795 xmlXPathReleaseObject(ctxt,
val);
2814 xmlXPathSetFrame(xmlXPathParserContextPtr ctxt) {
2819 ret = ctxt->valueFrame;
2820 ctxt->valueFrame = ctxt->valueNr;
2832 xmlXPathPopFrame(xmlXPathParserContextPtr ctxt,
int frame) {
2835 if (ctxt->valueNr < ctxt->valueFrame) {
2836 xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_STACK_ERROR);
2838 ctxt->valueFrame = frame;
2850 valuePop(xmlXPathParserContextPtr ctxt)
2852 xmlXPathObjectPtr
ret;
2854 if ((ctxt ==
NULL) || (ctxt->valueNr <= 0))
2857 if (ctxt->valueNr <= ctxt->valueFrame) {
2858 xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_STACK_ERROR);
2863 if (ctxt->valueNr > 0)
2864 ctxt->value = ctxt->valueTab[ctxt->valueNr - 1];
2867 ret = ctxt->valueTab[ctxt->valueNr];
2868 ctxt->valueTab[ctxt->valueNr] =
NULL;
2882 valuePush(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr
value)
2884 if (ctxt ==
NULL)
return(-1);
2890 ctxt->error = XPATH_MEMORY_ERROR;
2893 if (ctxt->valueNr >= ctxt->valueMax) {
2894 xmlXPathObjectPtr *tmp;
2897 xmlXPathPErrMemory(ctxt,
"XPath stack depth limit reached\n");
2900 tmp = (xmlXPathObjectPtr *)
xmlRealloc(ctxt->valueTab,
2901 2 * ctxt->valueMax *
2902 sizeof(ctxt->valueTab[0]));
2904 xmlXPathPErrMemory(ctxt,
"pushing value\n");
2907 ctxt->valueMax *= 2;
2908 ctxt->valueTab = tmp;
2910 ctxt->valueTab[ctxt->valueNr] =
value;
2911 ctxt->value =
value;
2912 return (ctxt->valueNr++);
2925 xmlXPathPopBoolean (xmlXPathParserContextPtr ctxt) {
2926 xmlXPathObjectPtr
obj;
2929 obj = valuePop(ctxt);
2931 xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
2934 if (
obj->type != XPATH_BOOLEAN)
2935 ret = xmlXPathCastToBoolean(
obj);
2938 xmlXPathReleaseObject(ctxt->context,
obj);
2952 xmlXPathPopNumber (xmlXPathParserContextPtr ctxt) {
2953 xmlXPathObjectPtr
obj;
2956 obj = valuePop(ctxt);
2958 xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
2961 if (
obj->type != XPATH_NUMBER)
2962 ret = xmlXPathCastToNumber(
obj);
2965 xmlXPathReleaseObject(ctxt->context,
obj);
2979 xmlXPathPopString (xmlXPathParserContextPtr ctxt) {
2980 xmlXPathObjectPtr
obj;
2983 obj = valuePop(ctxt);
2985 xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
2988 ret = xmlXPathCastToString(
obj);
2990 if (
obj->stringval ==
ret)
2992 xmlXPathReleaseObject(ctxt->context,
obj);
3006 xmlXPathPopNodeSet (xmlXPathParserContextPtr ctxt) {
3007 xmlXPathObjectPtr
obj;
3011 if (ctxt->value ==
NULL) {
3012 xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
3015 if (!xmlXPathStackIsNodeSet(ctxt)) {
3016 xmlXPathSetTypeError(ctxt);
3019 obj = valuePop(ctxt);
3027 xmlXPathReleaseObject(ctxt->context,
obj);
3041 xmlXPathPopExternal (xmlXPathParserContextPtr ctxt) {
3042 xmlXPathObjectPtr
obj;
3045 if ((ctxt ==
NULL) || (ctxt->value ==
NULL)) {
3046 xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
3049 if (ctxt->value->type != XPATH_USERS) {
3050 xmlXPathSetTypeError(ctxt);
3053 obj = valuePop(ctxt);
3056 xmlXPathReleaseObject(ctxt->context,
obj);
3083 #define CUR (*ctxt->cur) 3084 #define SKIP(val) ctxt->cur += (val) 3085 #define NXT(val) ctxt->cur[(val)] 3086 #define CUR_PTR ctxt->cur 3087 #define CUR_CHAR(l) xmlXPathCurrentChar(ctxt, &l) 3089 #define COPY_BUF(l,b,i,v) \ 3090 if (l == 1) b[i++] = (xmlChar) v; \ 3091 else i += xmlCopyChar(l,&b[i],v) 3093 #define NEXTL(l) ctxt->cur += l 3095 #define SKIP_BLANKS \ 3096 while (IS_BLANK_CH(*(ctxt->cur))) NEXT 3098 #define CURRENT (*ctxt->cur) 3099 #define NEXT ((*ctxt->cur) ? ctxt->cur++: ctxt->cur) 3106 #define DBL_EPSILON 1E-9 3109 #define UPPER_DOUBLE 1E9 3110 #define LOWER_DOUBLE 1E-5 3111 #define LOWER_DOUBLE_EXP 5 3113 #define INTEGER_DIGITS DBL_DIG 3114 #define FRACTION_DIGITS (DBL_DIG + 1 + (LOWER_DOUBLE_EXP)) 3115 #define EXPONENT_DIGITS (3 + 2) 3126 xmlXPathFormatNumber(
double number,
char buffer[],
int buffersize)
3128 switch (xmlXPathIsInf(
number)) {
3130 if (buffersize > (
int)
sizeof(
"Infinity"))
3134 if (buffersize > (
int)
sizeof(
"-Infinity"))
3138 if (xmlXPathIsNaN(
number)) {
3139 if (buffersize > (
int)
sizeof(
"NaN"))
3141 }
else if (
number == 0) {
3162 }
else if (buffersize > 0) {
3176 char work[
DBL_DIG + EXPONENT_DIGITS + 3 + LOWER_DOUBLE_EXP];
3177 int integer_place, fraction_place;
3179 char *after_fraction;
3180 double absolute_value;
3190 if ( ((absolute_value > UPPER_DOUBLE) ||
3191 (absolute_value < LOWER_DOUBLE)) &&
3192 (absolute_value != 0.0) ) {
3194 integer_place =
DBL_DIG + EXPONENT_DIGITS + 1;
3197 integer_place, fraction_place,
number);
3203 if (absolute_value > 0.0) {
3204 integer_place = (
int)
log10(absolute_value);
3205 if (integer_place > 0)
3206 fraction_place =
DBL_DIG - integer_place - 1;
3208 fraction_place =
DBL_DIG - integer_place;
3217 while (work[0] ==
' ') {
3223 after_fraction = work +
size;
3224 ptr = after_fraction;
3225 while (*(--
ptr) ==
'0')
3229 while ((*
ptr++ = *after_fraction++) != 0);
3233 if (
size > buffersize) {
3234 work[buffersize - 1] = 0;
3273 cur->content = (
void *) (-(++
count));
3297 return((
long)
count);
3313 int attr1 = 0, attr2 = 0;
3317 if ((node1 ==
NULL) || (node2 ==
NULL))
3334 if (node1 == node2) {
3335 if (attr1 == attr2) {
3338 cur = attrNode2->prev;
3340 if (
cur == attrNode1)
3355 if (node1 == node2->
prev)
3357 if (node1 == node2->
next)
3367 (node1->
doc == node2->
doc)) {
3382 if (
cur->parent == node1)
3388 if (
cur->parent == node2)
3401 while (depth1 > depth2) {
3405 while (depth2 > depth1) {
3413 if ((node1 ==
NULL) || (node2 ==
NULL))
3419 if (node1 == node2->
prev)
3421 if (node1 == node2->
next)
3430 (node1->
doc == node2->
doc)) {
3454 xmlXPathNodeSetSort(xmlNodeSetPtr
set) {
3455 #ifndef WITH_TIM_SORT 3456 int i,
j, incr,
len;
3463 #ifndef WITH_TIM_SORT 3469 for (incr =
len / 2; incr > 0; incr /= 2) {
3470 for (
i = incr;
i <
len;
i++) {
3473 #ifdef XP_OPTIMIZED_NON_ELEM_COMPARISON 3475 set->nodeTab[
j + incr]) == -1)
3477 if (xmlXPathCmpNodes(
set->nodeTab[
j],
3478 set->nodeTab[
j + incr]) == -1)
3481 tmp =
set->nodeTab[
j];
3482 set->nodeTab[
j] =
set->nodeTab[
j + incr];
3483 set->nodeTab[
j + incr] = tmp;
3491 libxml_domnode_tim_sort(
set->nodeTab,
set->nodeNr);
3495 #define XML_NODESET_DEFAULT 10 3521 xmlXPathErrMemory(
NULL,
"duplicating namespace\n");
3570 xmlXPathErrMemory(
NULL,
"creating nodeset\n");
3573 memset(
ret, 0 , (
size_t)
sizeof(xmlNodeSet));
3578 xmlXPathErrMemory(
NULL,
"creating nodeset\n");
3583 XML_NODESET_DEFAULT * (
size_t)
sizeof(
xmlNodePtr));
3584 ret->nodeMax = XML_NODESET_DEFAULT;
3589 ret->nodeTab[
ret->nodeNr++] =
3612 for (
i = 0;
i <
cur->nodeNr;
i++) {
3626 for (
i = 0;
i <
cur->nodeNr;
i++) {
3658 for (
i = 0;
i <
cur->nodeNr;
i++) {
3669 if (
cur->nodeMax == 0) {
3673 xmlXPathErrMemory(
NULL,
"growing nodeset\n");
3677 XML_NODESET_DEFAULT * (
size_t)
sizeof(
xmlNodePtr));
3678 cur->nodeMax = XML_NODESET_DEFAULT;
3679 }
else if (
cur->nodeNr ==
cur->nodeMax) {
3683 xmlXPathErrMemory(
NULL,
"growing nodeset hit limit\n");
3689 xmlXPathErrMemory(
NULL,
"growing nodeset\n");
3696 cur->nodeTab[
cur->nodeNr++] = xmlXPathNodeSetDupNs(
node,
ns);
3719 for (
i = 0;
i <
cur->nodeNr;
i++)
3720 if (
cur->nodeTab[
i] ==
val)
return(0);
3725 if (
cur->nodeMax == 0) {
3729 xmlXPathErrMemory(
NULL,
"growing nodeset\n");
3733 XML_NODESET_DEFAULT * (
size_t)
sizeof(
xmlNodePtr));
3734 cur->nodeMax = XML_NODESET_DEFAULT;
3735 }
else if (
cur->nodeNr ==
cur->nodeMax) {
3739 xmlXPathErrMemory(
NULL,
"growing nodeset hit limit\n");
3745 xmlXPathErrMemory(
NULL,
"growing nodeset\n");
3755 cur->nodeTab[
cur->nodeNr++] =
3780 if (
cur->nodeMax == 0) {
3784 xmlXPathErrMemory(
NULL,
"growing nodeset\n");
3788 XML_NODESET_DEFAULT * (
size_t)
sizeof(
xmlNodePtr));
3789 cur->nodeMax = XML_NODESET_DEFAULT;
3790 }
else if (
cur->nodeNr ==
cur->nodeMax) {
3794 xmlXPathErrMemory(
NULL,
"growing nodeset hit limit\n");
3800 xmlXPathErrMemory(
NULL,
"growing nodeset\n");
3810 cur->nodeTab[
cur->nodeNr++] =
3828 xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
3832 if (val2 ==
NULL)
return(val1);
3834 val1 = xmlXPathNodeSetCreate(
NULL);
3850 val1 = xmlXPathNodeSetCreateSize(val2->nodeNr);
3853 if (val2->nodeNr != 0) {
3854 if (val2->nodeNr == 1)
3855 *(val1->nodeTab) = *(val2->nodeTab);
3857 memcpy(val1->nodeTab, val2->nodeTab,
3860 val1->nodeNr = val2->nodeNr;
3867 initNr = val1->nodeNr;
3869 for (
i = 0;
i < val2->nodeNr;
i++) {
3870 n2 = val2->nodeTab[
i];
3875 for (
j = 0;
j < initNr;
j++) {
3876 n1 = val1->nodeTab[
j];
3897 if (val1->nodeMax == 0) {
3900 if (val1->nodeTab ==
NULL) {
3901 xmlXPathErrMemory(
NULL,
"merging nodeset\n");
3904 memset(val1->nodeTab, 0 ,
3905 XML_NODESET_DEFAULT * (
size_t)
sizeof(
xmlNodePtr));
3906 val1->nodeMax = XML_NODESET_DEFAULT;
3907 }
else if (val1->nodeNr == val1->nodeMax) {
3911 xmlXPathErrMemory(
NULL,
"merging nodeset hit limit\n");
3917 xmlXPathErrMemory(
NULL,
"merging nodeset\n");
3920 val1->nodeTab =
temp;
3927 val1->nodeTab[val1->nodeNr++] =
3930 val1->nodeTab[val1->nodeNr++] =
n2;
3947 static xmlNodeSetPtr
3948 xmlXPathNodeSetMergeAndClear(xmlNodeSetPtr
set1, xmlNodeSetPtr set2)
3951 int i,
j, initNbSet1;
3954 initNbSet1 =
set1->nodeNr;
3955 for (
i = 0;
i < set2->nodeNr;
i++) {
3956 n2 = set2->nodeTab[
i];
3960 for (
j = 0;
j < initNbSet1;
j++) {
3974 set2->nodeTab[
i] =
NULL;
3983 if (
set1->nodeMax == 0) {
3987 xmlXPathErrMemory(
NULL,
"merging nodeset\n");
3991 XML_NODESET_DEFAULT * (
size_t)
sizeof(
xmlNodePtr));
3992 set1->nodeMax = XML_NODESET_DEFAULT;
3993 }
else if (
set1->nodeNr >=
set1->nodeMax) {
3997 xmlXPathErrMemory(
NULL,
"merging nodeset hit limit\n");
4003 xmlXPathErrMemory(
NULL,
"merging nodeset\n");
4028 static xmlNodeSetPtr
4029 xmlXPathNodeSetMergeAndClearNoDupls(xmlNodeSetPtr
set1, xmlNodeSetPtr set2)
4035 for (
i = 0;
i < set2->nodeNr;
i++) {
4036 n2 = set2->nodeTab[
i];
4037 if (
set1->nodeMax == 0) {
4041 xmlXPathErrMemory(
NULL,
"merging nodeset\n");
4045 XML_NODESET_DEFAULT * (
size_t)
sizeof(
xmlNodePtr));
4046 set1->nodeMax = XML_NODESET_DEFAULT;
4047 }
else if (
set1->nodeNr >=
set1->nodeMax) {
4051 xmlXPathErrMemory(
NULL,
"merging nodeset hit limit\n");
4057 xmlXPathErrMemory(
NULL,
"merging nodeset\n");
4087 for (
i = 0;
i <
cur->nodeNr;
i++)
4088 if (
cur->nodeTab[
i] ==
val)
break;
4090 if (
i >=
cur->nodeNr) {
4093 "xmlXPathNodeSetDel: Node %s wasn't found in NodeList\n",
4102 for (;
i <
cur->nodeNr;
i++)
4103 cur->nodeTab[
i] =
cur->nodeTab[
i + 1];
4115 xmlXPathNodeSetRemove(xmlNodeSetPtr
cur,
int val) {
4117 if (
val >=
cur->nodeNr)
return;
4134 xmlXPathFreeNodeSet(xmlNodeSetPtr
obj) {
4140 for (
i = 0;
i <
obj->nodeNr;
i++)
4159 xmlXPathNodeSetClearFromPos(xmlNodeSetPtr
set,
int pos,
int hasNsNodes)
4163 else if ((hasNsNodes)) {
4186 xmlXPathNodeSetClear(xmlNodeSetPtr
set,
int hasNsNodes)
4188 xmlXPathNodeSetClearFromPos(
set, 0, hasNsNodes);
4200 xmlXPathNodeSetKeepLast(xmlNodeSetPtr
set)
4207 for (
i = 0;
i <
set->nodeNr - 1;
i++) {
4213 set->nodeTab[0] =
set->nodeTab[
set->nodeNr-1];
4225 xmlXPathFreeValueTree(xmlNodeSetPtr
obj) {
4231 for (
i = 0;
i <
obj->nodeNr;
i++) {
4245 #if defined(DEBUG) || defined(DEBUG_STEP) 4254 xmlGenericErrorContextNodeSet(
FILE *
output, xmlNodeSetPtr
obj) {
4262 if (
obj->nodeNr == 0) {
4270 for (
i = 0;
i <
obj->nodeNr;
i++) {
4278 else if (
obj->nodeTab[
i]->name ==
NULL)
4297 xmlXPathObjectPtr
ret;
4299 ret = (xmlXPathObjectPtr)
xmlMalloc(
sizeof(xmlXPathObject));
4301 xmlXPathErrMemory(
NULL,
"creating nodeset\n");
4304 memset(
ret, 0 , (
size_t)
sizeof(xmlXPathObject));
4305 ret->type = XPATH_NODESET;
4308 ret->nodesetval = xmlXPathNodeSetCreate(
val);
4310 #ifdef XP_DEBUG_OBJ_USAGE 4311 xmlXPathDebugObjUsageRequested(
NULL, XPATH_NODESET);
4327 xmlXPathObjectPtr
ret;
4329 ret = (xmlXPathObjectPtr)
xmlMalloc(
sizeof(xmlXPathObject));
4331 xmlXPathErrMemory(
NULL,
"creating result value tree\n");
4334 memset(
ret, 0 , (
size_t)
sizeof(xmlXPathObject));
4335 ret->type = XPATH_XSLT_TREE;
4337 ret->user = (
void *)
val;
4338 ret->nodesetval = xmlXPathNodeSetCreate(
val);
4339 #ifdef XP_DEBUG_OBJ_USAGE 4340 xmlXPathDebugObjUsageRequested(
NULL, XPATH_XSLT_TREE);
4355 xmlXPathNewNodeSetList(xmlNodeSetPtr
val)
4357 xmlXPathObjectPtr
ret;
4362 else if (
val->nodeTab ==
NULL)
4363 ret = xmlXPathNewNodeSet(
NULL);
4365 ret = xmlXPathNewNodeSet(
val->nodeTab[0]);
4367 for (
i = 1;
i <
val->nodeNr; ++
i) {
4369 if (xmlXPathNodeSetAddUnique(
ret->nodesetval,
val->nodeTab[
i])
4387 xmlXPathWrapNodeSet(xmlNodeSetPtr
val) {
4388 xmlXPathObjectPtr
ret;
4390 ret = (xmlXPathObjectPtr)
xmlMalloc(
sizeof(xmlXPathObject));
4392 xmlXPathErrMemory(
NULL,
"creating node set object\n");
4395 memset(
ret, 0 , (
size_t)
sizeof(xmlXPathObject));
4396 ret->type = XPATH_NODESET;
4398 #ifdef XP_DEBUG_OBJ_USAGE 4399 xmlXPathDebugObjUsageRequested(
NULL, XPATH_NODESET);
4412 xmlXPathFreeNodeSetList(xmlXPathObjectPtr
obj) {
4414 #ifdef XP_DEBUG_OBJ_USAGE 4415 xmlXPathDebugObjUsageReleased(
NULL,
obj->type);
4432 xmlXPathDifference (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
4437 if (xmlXPathNodeSetIsEmpty(nodes2))
4441 ret = xmlXPathNodeSetCreate(
NULL);
4442 if (xmlXPathNodeSetIsEmpty(nodes1))
4445 l1 = xmlXPathNodeSetGetLength(nodes1);
4447 for (
i = 0;
i < l1;
i++) {
4448 cur = xmlXPathNodeSetItem(nodes1,
i);
4449 if (!xmlXPathNodeSetContains(nodes2,
cur)) {
4451 if (xmlXPathNodeSetAddUnique(
ret,
cur) < 0)
4470 xmlXPathIntersection (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
4471 xmlNodeSetPtr
ret = xmlXPathNodeSetCreate(
NULL);
4477 if (xmlXPathNodeSetIsEmpty(nodes1))
4479 if (xmlXPathNodeSetIsEmpty(nodes2))
4482 l1 = xmlXPathNodeSetGetLength(nodes1);
4484 for (
i = 0;
i < l1;
i++) {
4485 cur = xmlXPathNodeSetItem(nodes1,
i);
4486 if (xmlXPathNodeSetContains(nodes2,
cur)) {
4488 if (xmlXPathNodeSetAddUnique(
ret,
cur) < 0)
4506 xmlXPathDistinctSorted (xmlNodeSetPtr nodes) {
4513 if (xmlXPathNodeSetIsEmpty(nodes))
4516 ret = xmlXPathNodeSetCreate(
NULL);
4519 l = xmlXPathNodeSetGetLength(nodes);
4521 for (
i = 0;
i <
l;
i++) {
4522 cur = xmlXPathNodeSetItem(nodes,
i);
4527 if (xmlXPathNodeSetAddUnique(
ret,
cur) < 0)
4550 xmlXPathDistinct (xmlNodeSetPtr nodes) {
4551 if (xmlXPathNodeSetIsEmpty(nodes))
4554 xmlXPathNodeSetSort(nodes);
4555 return(xmlXPathDistinctSorted(nodes));
4570 xmlXPathHasSameNodes (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
4574 if (xmlXPathNodeSetIsEmpty(nodes1) ||
4575 xmlXPathNodeSetIsEmpty(nodes2))
4578 l = xmlXPathNodeSetGetLength(nodes1);
4579 for (
i = 0;
i <
l;
i++) {
4580 cur = xmlXPathNodeSetItem(nodes1,
i);
4581 if (xmlXPathNodeSetContains(nodes2,
cur))
4600 xmlXPathNodeLeadingSorted (xmlNodeSetPtr nodes,
xmlNodePtr node) {
4608 ret = xmlXPathNodeSetCreate(
NULL);
4611 if (xmlXPathNodeSetIsEmpty(nodes) ||
4612 (!xmlXPathNodeSetContains(nodes,
node)))
4615 l = xmlXPathNodeSetGetLength(nodes);
4616 for (
i = 0;
i <
l;
i++) {
4617 cur = xmlXPathNodeSetItem(nodes,
i);
4621 if (xmlXPathNodeSetAddUnique(
ret,
cur) < 0)
4643 xmlXPathNodeSetSort(nodes);
4644 return(xmlXPathNodeLeadingSorted(nodes,
node));
4660 xmlXPathLeadingSorted (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
4661 if (xmlXPathNodeSetIsEmpty(nodes2))
4663 return(xmlXPathNodeLeadingSorted(nodes1,
4664 xmlXPathNodeSetItem(nodes2, 1)));
4682 xmlXPathLeading (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
4683 if (xmlXPathNodeSetIsEmpty(nodes2))
4685 if (xmlXPathNodeSetIsEmpty(nodes1))
4686 return(xmlXPathNodeSetCreate(
NULL));
4687 xmlXPathNodeSetSort(nodes1);
4688 xmlXPathNodeSetSort(nodes2);
4689 return(xmlXPathNodeLeadingSorted(nodes1,
4690 xmlXPathNodeSetItem(nodes2, 1)));
4706 xmlXPathNodeTrailingSorted (xmlNodeSetPtr nodes,
xmlNodePtr node) {
4714 ret = xmlXPathNodeSetCreate(
NULL);
4717 if (xmlXPathNodeSetIsEmpty(nodes) ||
4718 (!xmlXPathNodeSetContains(nodes,
node)))
4721 l = xmlXPathNodeSetGetLength(nodes);
4722 for (
i =
l - 1;
i >= 0;
i--) {
4723 cur = xmlXPathNodeSetItem(nodes,
i);
4727 if (xmlXPathNodeSetAddUnique(
ret,
cur) < 0)
4730 xmlXPathNodeSetSort(
ret);
4750 xmlXPathNodeSetSort(nodes);
4751 return(xmlXPathNodeTrailingSorted(nodes,
node));
4767 xmlXPathTrailingSorted (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
4768 if (xmlXPathNodeSetIsEmpty(nodes2))
4770 return(xmlXPathNodeTrailingSorted(nodes1,
4771 xmlXPathNodeSetItem(nodes2, 0)));
4789 xmlXPathTrailing (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
4790 if (xmlXPathNodeSetIsEmpty(nodes2))
4792 if (xmlXPathNodeSetIsEmpty(nodes1))
4793 return(xmlXPathNodeSetCreate(
NULL));
4794 xmlXPathNodeSetSort(nodes1);
4795 xmlXPathNodeSetSort(nodes2);
4796 return(xmlXPathNodeTrailingSorted(nodes1,
4797 xmlXPathNodeSetItem(nodes2, 0)));
4817 xmlXPathRegisterFunc(xmlXPathContextPtr ctxt,
const xmlChar *
name,
4818 xmlXPathFunction
f) {
4819 return(xmlXPathRegisterFuncNS(ctxt,
name,
NULL,
f));
4834 xmlXPathRegisterFuncNS(xmlXPathContextPtr ctxt,
const xmlChar *
name,
4835 const xmlChar *ns_uri, xmlXPathFunction
f) {
4841 if (ctxt->funcHash ==
NULL)
4843 if (ctxt->funcHash ==
NULL)
4861 xmlXPathRegisterFuncLookup (xmlXPathContextPtr ctxt,
4862 xmlXPathFuncLookupFunc
f,
4866 ctxt->funcLookupFunc =
f;
4867 ctxt->funcLookupData = funcCtxt;
4881 xmlXPathFunctionLookup(xmlXPathContextPtr ctxt,
const xmlChar *
name) {
4885 if (ctxt->funcLookupFunc !=
NULL) {
4886 xmlXPathFunction
ret;
4887 xmlXPathFuncLookupFunc
f;
4889 f = ctxt->funcLookupFunc;
4894 return(xmlXPathFunctionLookupNS(ctxt,
name,
NULL));
4909 xmlXPathFunctionLookupNS(xmlXPathContextPtr ctxt,
const xmlChar *
name,
4911 xmlXPathFunction
ret;
4918 if (ctxt->funcLookupFunc !=
NULL) {
4919 xmlXPathFuncLookupFunc
f;
4921 f = ctxt->funcLookupFunc;
4922 ret =
f(ctxt->funcLookupData,
name, ns_uri);
4927 if (ctxt->funcHash ==
NULL)
4943 xmlXPathRegisteredFuncsCleanup(xmlXPathContextPtr ctxt) {
4948 ctxt->funcHash =
NULL;
4969 xmlXPathRegisterVariable(xmlXPathContextPtr ctxt,
const xmlChar *
name,
4970 xmlXPathObjectPtr
value) {
4971 return(xmlXPathRegisterVariableNS(ctxt,
name,
NULL,
value));
4987 xmlXPathRegisterVariableNS(xmlXPathContextPtr ctxt,
const xmlChar *
name,
4989 xmlXPathObjectPtr
value) {
4995 if (ctxt->varHash ==
NULL)
4997 if (ctxt->varHash ==
NULL)
5001 xmlXPathFreeObjectEntry));
5003 (
void *)
value, xmlXPathFreeObjectEntry));
5015 xmlXPathRegisterVariableLookup(xmlXPathContextPtr ctxt,
5016 xmlXPathVariableLookupFunc
f,
void *
data) {
5019 ctxt->varLookupFunc =
f;
5020 ctxt->varLookupData =
data;
5034 xmlXPathVariableLookup(xmlXPathContextPtr ctxt,
const xmlChar *
name) {
5038 if (ctxt->varLookupFunc !=
NULL) {
5039 xmlXPathObjectPtr
ret;
5041 ret = ((xmlXPathVariableLookupFunc)ctxt->varLookupFunc)
5045 return(xmlXPathVariableLookupNS(ctxt,
name,
NULL));
5060 xmlXPathVariableLookupNS(xmlXPathContextPtr ctxt,
const xmlChar *
name,
5065 if (ctxt->varLookupFunc !=
NULL) {
5066 xmlXPathObjectPtr
ret;
5068 ret = ((xmlXPathVariableLookupFunc)ctxt->varLookupFunc)
5069 (ctxt->varLookupData,
name, ns_uri);
5073 if (ctxt->varHash ==
NULL)
5078 return(xmlXPathCacheObjectCopy(ctxt, (xmlXPathObjectPtr)
5089 xmlXPathRegisteredVariablesCleanup(xmlXPathContextPtr ctxt) {
5093 xmlHashFree(ctxt->varHash, xmlXPathFreeObjectEntry);
5094 ctxt->varHash =
NULL;
5109 xmlXPathRegisterNs(xmlXPathContextPtr ctxt,
const xmlChar *prefix,
5118 if (ctxt->nsHash ==
NULL)
5120 if (ctxt->nsHash ==
NULL)
5140 xmlXPathNsLookup(xmlXPathContextPtr ctxt,
const xmlChar *prefix) {
5146 #ifdef XML_XML_NAMESPACE 5151 if (ctxt->namespaces !=
NULL) {
5154 for (
i = 0;
i < ctxt->nsNr;
i++) {
5155 if ((ctxt->namespaces[
i] !=
NULL) &&
5157 return(ctxt->namespaces[
i]->href);
5171 xmlXPathRegisteredNsCleanup(xmlXPathContextPtr ctxt) {
5176 ctxt->nsHash =
NULL;
5196 xmlXPathNewFloat(
double val) {
5197 xmlXPathObjectPtr
ret;
5199 ret = (xmlXPathObjectPtr)
xmlMalloc(
sizeof(xmlXPathObject));
5201 xmlXPathErrMemory(
NULL,
"creating float object\n");
5204 memset(
ret, 0 , (
size_t)
sizeof(xmlXPathObject));
5205 ret->type = XPATH_NUMBER;
5207 #ifdef XP_DEBUG_OBJ_USAGE 5208 xmlXPathDebugObjUsageRequested(
NULL, XPATH_NUMBER);
5222 xmlXPathNewBoolean(
int val) {
5223 xmlXPathObjectPtr
ret;
5225 ret = (xmlXPathObjectPtr)
xmlMalloc(
sizeof(xmlXPathObject));
5227 xmlXPathErrMemory(
NULL,
"creating boolean object\n");
5230 memset(
ret, 0 , (
size_t)
sizeof(xmlXPathObject));
5231 ret->type = XPATH_BOOLEAN;
5232 ret->boolval = (
val != 0);
5233 #ifdef XP_DEBUG_OBJ_USAGE 5234 xmlXPathDebugObjUsageRequested(
NULL, XPATH_BOOLEAN);
5249 xmlXPathObjectPtr
ret;
5251 ret = (xmlXPathObjectPtr)
xmlMalloc(
sizeof(xmlXPathObject));
5253 xmlXPathErrMemory(
NULL,
"creating string object\n");
5256 memset(
ret, 0 , (
size_t)
sizeof(xmlXPathObject));
5257 ret->type = XPATH_STRING;
5262 #ifdef XP_DEBUG_OBJ_USAGE 5263 xmlXPathDebugObjUsageRequested(
NULL, XPATH_STRING);
5278 xmlXPathObjectPtr
ret;
5280 ret = (xmlXPathObjectPtr)
xmlMalloc(
sizeof(xmlXPathObject));
5282 xmlXPathErrMemory(
NULL,
"creating string object\n");
5285 memset(
ret, 0 , (
size_t)
sizeof(xmlXPathObject));
5286 ret->type = XPATH_STRING;
5288 #ifdef XP_DEBUG_OBJ_USAGE 5289 xmlXPathDebugObjUsageRequested(
NULL, XPATH_STRING);
5303 xmlXPathNewCString(
const char *
val) {
5304 xmlXPathObjectPtr
ret;
5306 ret = (xmlXPathObjectPtr)
xmlMalloc(
sizeof(xmlXPathObject));
5308 xmlXPathErrMemory(
NULL,
"creating string object\n");
5311 memset(
ret, 0 , (
size_t)
sizeof(xmlXPathObject));
5312 ret->type = XPATH_STRING;
5314 #ifdef XP_DEBUG_OBJ_USAGE 5315 xmlXPathDebugObjUsageRequested(
NULL, XPATH_STRING);
5329 xmlXPathWrapCString (
char *
val) {
5330 return(xmlXPathWrapString((
xmlChar *)(
val)));
5342 xmlXPathWrapExternal (
void *
val) {
5343 xmlXPathObjectPtr
ret;
5345 ret = (xmlXPathObjectPtr)
xmlMalloc(
sizeof(xmlXPathObject));
5347 xmlXPathErrMemory(
NULL,
"creating user object\n");
5350 memset(
ret, 0 , (
size_t)
sizeof(xmlXPathObject));
5351 ret->type = XPATH_USERS;
5353 #ifdef XP_DEBUG_OBJ_USAGE 5354 xmlXPathDebugObjUsageRequested(
NULL, XPATH_USERS);
5368 xmlXPathObjectCopy(xmlXPathObjectPtr
val) {
5369 xmlXPathObjectPtr
ret;
5374 ret = (xmlXPathObjectPtr)
xmlMalloc(
sizeof(xmlXPathObject));
5376 xmlXPathErrMemory(
NULL,
"copying object\n");
5380 #ifdef XP_DEBUG_OBJ_USAGE 5381 xmlXPathDebugObjUsageRequested(
NULL,
val->type);
5383 switch (
val->type) {
5392 case XPATH_XSLT_TREE:
5399 if ((
val->nodesetval !=
NULL) &&
5400 (
val->nodesetval->nodeTab !=
NULL)) {
5406 top->name = (
char *)
5411 cur =
val->nodesetval->nodeTab[0]->children;
5421 ret->nodesetval = xmlXPathNodeSetCreate(
NULL);
5427 ret->nodesetval = xmlXPathNodeSetMerge(
NULL,
val->nodesetval);
5431 case XPATH_LOCATIONSET:
5432 #ifdef LIBXML_XPTR_ENABLED 5434 xmlLocationSetPtr loc =
val->user;
5435 ret->user = (
void *) xmlXPtrLocationSetMerge(
NULL, loc);
5442 case XPATH_UNDEFINED:
5444 "xmlXPathObjectCopy: unsupported type %d\n",
5458 xmlXPathFreeObject(xmlXPathObjectPtr
obj) {
5460 if ((
obj->type == XPATH_NODESET) || (
obj->type == XPATH_XSLT_TREE)) {
5464 xmlXPathFreeNodeSet(
obj->nodesetval);
5468 obj->type = XPATH_XSLT_TREE;
5470 xmlXPathFreeValueTree(
obj->nodesetval);
5473 xmlXPathFreeNodeSet(
obj->nodesetval);
5475 #ifdef LIBXML_XPTR_ENABLED 5476 }
else if (
obj->type == XPATH_LOCATIONSET) {
5478 xmlXPtrFreeLocationSet(
obj->user);
5480 }
else if (
obj->type == XPATH_STRING) {
5484 #ifdef XP_DEBUG_OBJ_USAGE 5485 xmlXPathDebugObjUsageReleased(
NULL,
obj->type);
5492 xmlXPathFreeObject((xmlXPathObjectPtr)
obj);
5503 xmlXPathReleaseObject(xmlXPathContextPtr ctxt, xmlXPathObjectPtr
obj)
5505 #define XP_CACHE_ADD(sl, o) if (sl == NULL) { \ 5506 sl = xmlPointerListCreate(10); if (sl == NULL) goto free_obj; } \ 5507 if (xmlPointerListAddSize(sl, obj, 0) == -1) goto free_obj; 5509 #define XP_CACHE_WANTS(sl, n) ((sl == NULL) || ((sl)->number < n)) 5513 if ((ctxt ==
NULL) || (ctxt->cache ==
NULL)) {
5514 xmlXPathFreeObject(
obj);
5516 xmlXPathContextCachePtr
cache =
5517 (xmlXPathContextCachePtr) ctxt->cache;
5521 case XPATH_XSLT_TREE:
5522 if (
obj->nodesetval !=
NULL) {
5529 obj->type = XPATH_XSLT_TREE;
5530 xmlXPathFreeValueTree(
obj->nodesetval);
5532 }
else if ((
obj->nodesetval->nodeMax <= 40) &&
5533 (XP_CACHE_WANTS(
cache->nodesetObjs,
5534 cache->maxNodeset)))
5536 XP_CACHE_ADD(
cache->nodesetObjs,
obj);
5539 xmlXPathFreeNodeSet(
obj->nodesetval);
5548 if (XP_CACHE_WANTS(
cache->stringObjs,
cache->maxString)) {
5549 XP_CACHE_ADD(
cache->stringObjs,
obj);
5554 if (XP_CACHE_WANTS(
cache->booleanObjs,
cache->maxBoolean)) {
5555 XP_CACHE_ADD(
cache->booleanObjs,
obj);
5560 if (XP_CACHE_WANTS(
cache->numberObjs,
cache->maxNumber)) {
5561 XP_CACHE_ADD(
cache->numberObjs,
obj);
5565 #ifdef LIBXML_XPTR_ENABLED 5566 case XPATH_LOCATIONSET:
5568 xmlXPtrFreeLocationSet(
obj->user);
5579 if (XP_CACHE_WANTS(
cache->miscObjs,
cache->maxMisc)) {
5580 XP_CACHE_ADD(
cache->miscObjs,
obj);
5586 #ifdef XP_DEBUG_OBJ_USAGE 5587 xmlXPathDebugObjUsageReleased(ctxt,
obj->type);
5590 if (
obj->nodesetval !=
NULL) {
5591 xmlNodeSetPtr tmpset =
obj->nodesetval;
5599 if (tmpset->nodeNr > 1) {
5603 for (
i = 0;
i < tmpset->nodeNr;
i++) {
5604 node = tmpset->nodeTab[
i];
5611 }
else if (tmpset->nodeNr == 1) {
5612 if ((tmpset->nodeTab[0] !=
NULL) &&
5614 xmlXPathNodeSetFreeNs((
xmlNsPtr) tmpset->nodeTab[0]);
5618 obj->nodesetval = tmpset;
5629 xmlXPathFreeNodeSet(
obj->nodesetval);
5630 #ifdef XP_DEBUG_OBJ_USAGE 5631 xmlXPathDebugObjUsageReleased(
NULL,
obj->type);
5654 xmlXPathCastBooleanToString (
int val) {
5672 xmlXPathCastNumberToString (
double val) {
5674 switch (xmlXPathIsInf(
val)) {
5682 if (xmlXPathIsNaN(
val)) {
5684 }
else if (
val == 0) {
5690 xmlXPathFormatNumber(
val,
buf, 99);
5723 xmlXPathCastNodeSetToString (xmlNodeSetPtr
ns) {
5728 xmlXPathNodeSetSort(
ns);
5729 return(xmlXPathCastNodeToString(
ns->nodeTab[0]));
5742 xmlXPathCastToString(xmlXPathObjectPtr
val) {
5747 switch (
val->type) {
5748 case XPATH_UNDEFINED:
5755 case XPATH_XSLT_TREE:
5756 ret = xmlXPathCastNodeSetToString(
val->nodesetval);
5761 ret = xmlXPathCastBooleanToString(
val->boolval);
5763 case XPATH_NUMBER: {
5764 ret = xmlXPathCastNumberToString(
val->floatval);
5770 case XPATH_LOCATIONSET:
5788 xmlXPathConvertString(xmlXPathObjectPtr
val) {
5792 return(xmlXPathNewCString(
""));
5794 switch (
val->type) {
5795 case XPATH_UNDEFINED:
5801 case XPATH_XSLT_TREE:
5802 res = xmlXPathCastNodeSetToString(
val->nodesetval);
5807 res = xmlXPathCastBooleanToString(
val->boolval);
5810 res = xmlXPathCastNumberToString(
val->floatval);
5815 case XPATH_LOCATIONSET:
5819 xmlXPathFreeObject(
val);
5821 return(xmlXPathNewCString(
""));
5822 return(xmlXPathWrapString(
res));
5834 xmlXPathCastBooleanToNumber(
int val) {
5849 xmlXPathCastStringToNumber(
const xmlChar *
val) {
5871 ret = xmlXPathCastStringToNumber(
strval);
5886 xmlXPathCastNodeSetToNumber (xmlNodeSetPtr
ns) {
5892 str = xmlXPathCastNodeSetToString(
ns);
5893 ret = xmlXPathCastStringToNumber(
str);
5907 xmlXPathCastToNumber(xmlXPathObjectPtr
val) {
5912 switch (
val->type) {
5913 case XPATH_UNDEFINED:
5920 case XPATH_XSLT_TREE:
5921 ret = xmlXPathCastNodeSetToNumber(
val->nodesetval);
5924 ret = xmlXPathCastStringToNumber(
val->stringval);
5930 ret = xmlXPathCastBooleanToNumber(
val->boolval);
5935 case XPATH_LOCATIONSET:
5953 xmlXPathConvertNumber(xmlXPathObjectPtr
val) {
5954 xmlXPathObjectPtr
ret;
5957 return(xmlXPathNewFloat(0.0));
5958 if (
val->type == XPATH_NUMBER)
5960 ret = xmlXPathNewFloat(xmlXPathCastToNumber(
val));
5961 xmlXPathFreeObject(
val);
5974 xmlXPathCastNumberToBoolean (
double val) {
5975 if (xmlXPathIsNaN(
val) || (
val == 0.0))
5989 xmlXPathCastStringToBoolean (
const xmlChar *
val) {
6004 xmlXPathCastNodeSetToBoolean (xmlNodeSetPtr
ns) {
6005 if ((
ns ==
NULL) || (
ns->nodeNr == 0))
6019 xmlXPathCastToBoolean (xmlXPathObjectPtr
val) {
6024 switch (
val->type) {
6025 case XPATH_UNDEFINED:
6032 case XPATH_XSLT_TREE:
6033 ret = xmlXPathCastNodeSetToBoolean(
val->nodesetval);
6036 ret = xmlXPathCastStringToBoolean(
val->stringval);
6039 ret = xmlXPathCastNumberToBoolean(
val->floatval);
6047 case XPATH_LOCATIONSET:
6066 xmlXPathConvertBoolean(xmlXPathObjectPtr
val) {
6067 xmlXPathObjectPtr
ret;
6070 return(xmlXPathNewBoolean(0));
6071 if (
val->type == XPATH_BOOLEAN)
6073 ret = xmlXPathNewBoolean(xmlXPathCastToBoolean(
val));
6074 xmlXPathFreeObject(
val);
6094 xmlXPathContextPtr
ret;
6096 ret = (xmlXPathContextPtr)
xmlMalloc(
sizeof(xmlXPathContext));
6098 xmlXPathErrMemory(
NULL,
"creating context\n");
6101 memset(
ret, 0 , (
size_t)
sizeof(xmlXPathContext));
6120 ret->contextSize = -1;
6121 ret->proximityPosition = -1;
6126 #ifdef XP_DEFAULT_CACHE_ON 6127 if (xmlXPathContextSetCache(
ret, 1, -1, 0) == -1) {
6128 xmlXPathFreeContext(
ret);
6133 xmlXPathRegisterAllFunctions(
ret);
6145 xmlXPathFreeContext(xmlXPathContextPtr ctxt) {
6146 if (ctxt ==
NULL)
return;
6148 if (ctxt->cache !=
NULL)
6149 xmlXPathFreeCache((xmlXPathContextCachePtr) ctxt->cache);
6150 xmlXPathRegisteredNsCleanup(ctxt);
6151 xmlXPathRegisteredFuncsCleanup(ctxt);
6152 xmlXPathRegisteredVariablesCleanup(ctxt);
6163 #define CHECK_CTXT(ctxt) \ 6164 if (ctxt == NULL) { \ 6165 __xmlRaiseError(NULL, NULL, NULL, \ 6166 NULL, NULL, XML_FROM_XPATH, \ 6167 XML_ERR_INTERNAL_ERROR, XML_ERR_FATAL, \ 6168 __FILE__, __LINE__, \ 6169 NULL, NULL, NULL, 0, 0, \ 6170 "NULL context pointer\n"); \ 6174 #define CHECK_CTXT_NEG(ctxt) \ 6175 if (ctxt == NULL) { \ 6176 __xmlRaiseError(NULL, NULL, NULL, \ 6177 NULL, NULL, XML_FROM_XPATH, \ 6178 XML_ERR_INTERNAL_ERROR, XML_ERR_FATAL, \ 6179 __FILE__, __LINE__, \ 6180 NULL, NULL, NULL, 0, 0, \ 6181 "NULL context pointer\n"); \ 6186 #define CHECK_CONTEXT(ctxt) \ 6187 if ((ctxt == NULL) || (ctxt->doc == NULL) || \ 6188 (ctxt->doc->children == NULL)) { \ 6189 xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_INVALID_CTXT); \ 6203 xmlXPathParserContextPtr
6204 xmlXPathNewParserContext(
const xmlChar *
str, xmlXPathContextPtr ctxt) {
6205 xmlXPathParserContextPtr
ret;
6207 ret = (xmlXPathParserContextPtr)
xmlMalloc(
sizeof(xmlXPathParserContext));
6209 xmlXPathErrMemory(ctxt,
"creating parser context\n");
6212 memset(
ret, 0 , (
size_t)
sizeof(xmlXPathParserContext));
6214 ret->context = ctxt;
6216 ret->comp = xmlXPathNewCompExpr();
6222 if ((ctxt !=
NULL) && (ctxt->dict !=
NULL)) {
6223 ret->comp->dict = ctxt->dict;
6239 static xmlXPathParserContextPtr
6240 xmlXPathCompParserContext(xmlXPathCompExprPtr comp, xmlXPathContextPtr ctxt) {
6241 xmlXPathParserContextPtr
ret;
6243 ret = (xmlXPathParserContextPtr)
xmlMalloc(
sizeof(xmlXPathParserContext));
6245 xmlXPathErrMemory(ctxt,
"creating evaluation context\n");
6248 memset(
ret, 0 , (
size_t)
sizeof(xmlXPathParserContext));
6251 ret->valueTab = (xmlXPathObjectPtr *)
6252 xmlMalloc(10 *
sizeof(xmlXPathObjectPtr));
6255 xmlXPathErrMemory(ctxt,
"creating evaluation context\n");
6261 ret->valueFrame = 0;
6263 ret->context = ctxt;
6276 xmlXPathFreeParserContext(xmlXPathParserContextPtr ctxt) {
6279 if (ctxt->valueTab !=
NULL) {
6280 for (
i = 0;
i < ctxt->valueNr;
i++) {
6282 xmlXPathReleaseObject(ctxt->context, ctxt->valueTab[
i]);
6284 xmlXPathFreeObject(ctxt->valueTab[
i]);
6288 if (ctxt->comp !=
NULL) {
6289 #ifdef XPATH_STREAMING 6290 if (ctxt->comp->stream !=
NULL) {
6291 xmlFreePatternList(ctxt->comp->stream);
6292 ctxt->comp->stream =
NULL;
6295 xmlXPathFreeCompExpr(ctxt->comp);
6320 unsigned int ret = 0;
6336 switch (
node->type) {
6341 string =
node->content;
6346 return(((
unsigned int)
string[0]) +
6347 (((
unsigned int)
string[1]) << 8));
6354 return(((
unsigned int)
string[0]) +
6355 (((
unsigned int)
string[1]) << 8));
6360 tmp =
node->children;
6365 while (tmp !=
NULL) {
6366 switch (tmp->
type) {
6375 if ((
string !=
NULL) && (
string[0] != 0)) {
6377 return(
ret + (((
unsigned int)
string[0]) << 8));
6379 if (
string[1] == 0) {
<